Initial commit
This commit is contained in:
commit
2fd06a5e83
40 changed files with 1354 additions and 0 deletions
10
src/lib.rs
Normal file
10
src/lib.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
macro_rules! expose_submodules {
|
||||
( $( $x:ident ),* ) => {
|
||||
$(
|
||||
mod $x;
|
||||
pub use self::$x::*;
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
pub mod v1;
|
11
src/v1/mod.rs
Normal file
11
src/v1/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
macro_rules! default_derive {
|
||||
($i:item) => {
|
||||
use serde::{Serialize, Deserialize};
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
$i
|
||||
};
|
||||
}
|
||||
|
||||
mod schemas;
|
||||
|
||||
pub use schemas::*;
|
11
src/v1/schemas/attribute.rs
Normal file
11
src/v1/schemas/attribute.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct Attribute {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
47
src/v1/schemas/attribute_attachment.rs
Normal file
47
src/v1/schemas/attribute_attachment.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use regex_macro::regex;
|
||||
|
||||
default_derive!{
|
||||
pub struct AttributeAttachment {
|
||||
content: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeAttachment {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let re = regex!("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$");
|
||||
if re.is_match(value) {
|
||||
Ok(AttributeAttachment { content: String::from(value) })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse AttributeAttachment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeAttachment {
|
||||
fn into(self) -> String {
|
||||
self.content
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn forbidden_char() {
|
||||
let att: Result<AttributeAttachment, _> = "uqiolgfnluiqoegn&".try_into();
|
||||
println!("{:?}", att);
|
||||
assert!(att.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let att: Result<AttributeAttachment, _> = "".try_into();
|
||||
assert_eq!(att, Ok(AttributeAttachment {content: String::from("")}))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let att: Result<AttributeAttachment, _> = "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu".try_into();
|
||||
assert_eq!(att, Ok(AttributeAttachment{content: String::from("TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu")}))
|
||||
}
|
53
src/v1/schemas/attribute_category.rs
Normal file
53
src/v1/schemas/attribute_category.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
use phf::phf_set;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct AttributeCategory {
|
||||
cat: String,
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeCategory {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let valid_categories: phf::Set<&'static str> = phf_set!("Internal reference", "Targeting data", "Antivirus detection", "Payload delivery", "Artifacts dropped", "Payload installation", "Persistence mechanism", "Network activity", "Payload type", "Attribution", "External analysis", "Financial fraud", "Support Tool", "Social network", "Person", "Other");
|
||||
if value.len() <= 255 && valid_categories.contains(value) {
|
||||
Ok(AttributeCategory { cat: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse AttributeCategory")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeCategory {
|
||||
fn into(self) -> String {
|
||||
self.cat
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let cat: Result<AttributeCategory, _> = "".try_into();
|
||||
assert!(cat.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let cat: Result<AttributeCategory, _> = format!("{:>256}", "Test").as_str().try_into();
|
||||
assert!(cat.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let cat: Result<AttributeCategory, _> = "Internal reference".try_into();
|
||||
assert_eq!(cat, Ok(AttributeCategory { cat: "Internal reference".to_string() }))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let cat: Result<AttributeCategory, _> = "Person".try_into();
|
||||
assert_eq!(cat, Ok(AttributeCategory {cat: String::from("Person")}))
|
||||
}
|
44
src/v1/schemas/attribute_comment.rs
Normal file
44
src/v1/schemas/attribute_comment.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct AttributeComment {
|
||||
text: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeComment {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
if value.len() <= 65535 {
|
||||
Ok(AttributeComment { text: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse AttributeComment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeComment {
|
||||
fn into(self) -> String {
|
||||
self.text
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let comment: Result<AttributeComment, _> = format!("{:>65536}", "Test").as_str().try_into();
|
||||
assert!(comment.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let comment: Result<AttributeComment, _> = "".try_into();
|
||||
assert_eq!(comment, Ok(AttributeComment { text: "".to_string() }))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let comment: Result<AttributeComment, _> = "Comment".try_into();
|
||||
assert_eq!(comment, Ok(AttributeComment{text: String::from("Comment")}))
|
||||
}
|
44
src/v1/schemas/attribute_event_uuid.rs
Normal file
44
src/v1/schemas/attribute_event_uuid.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use super::UUID;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct AttributeEventUUID {
|
||||
uuid: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeEventUUID {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let uuid: Result<UUID, _> = value.try_into();
|
||||
match uuid {
|
||||
Ok(id) => Ok(AttributeEventUUID{uuid: id.into()}),
|
||||
Err(_) => Err("Failed to parse AttributeEventUUID"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeEventUUID {
|
||||
fn into(self) -> String {
|
||||
self.uuid
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let uuid: Result<AttributeEventUUID, _> = "".try_into();
|
||||
assert!(uuid.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let uuid: Result<AttributeEventUUID, _> = format!("{:>37}", "Test").as_str().try_into();
|
||||
assert!(uuid.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let uuid: Result<AttributeEventUUID, _> = "c99506a6-1255-4b71-afa5-7b8ba48c3b1b".try_into();
|
||||
assert_eq!(uuid, Ok(AttributeEventUUID{ uuid: "c99506a6-1255-4b71-afa5-7b8ba48c3b1b".to_string() }))
|
||||
}
|
57
src/v1/schemas/attribute_id.rs
Normal file
57
src/v1/schemas/attribute_id.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use regex_macro::regex;
|
||||
|
||||
default_derive!{
|
||||
pub struct AttributeId {
|
||||
id: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeId {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let re = regex!("^[[:digit:]]+$");
|
||||
if re.is_match(value) && value.len() <= 10 {
|
||||
Ok(AttributeId{ id: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse AttributeId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeId {
|
||||
fn into(self) -> String {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let id: Result<AttributeId, _> = "".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let id: Result<AttributeId, _> = "12345678910".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forbidden_char() {
|
||||
let id: Result<AttributeId, _> = "123r5".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let id: Result<AttributeId, _> = "0".try_into();
|
||||
assert_eq!(id, Ok(AttributeId{id: String::from("0")}))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let id: Result<AttributeId, _> = "123456789".try_into();
|
||||
assert_eq!(id, Ok(AttributeId{id: String::from("123456789")}));
|
||||
}
|
25
src/v1/schemas/attribute_list.rs
Normal file
25
src/v1/schemas/attribute_list.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use super::Attribute;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct AttributeList {
|
||||
attrs: Vec<Attribute>
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Attribute>> for AttributeList {
|
||||
fn from(value: Vec<Attribute>) -> Self {
|
||||
AttributeList { attrs: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<Attribute>> for AttributeList {
|
||||
fn into(self) -> Vec<Attribute> {
|
||||
self.attrs
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/attribute_no_id.rs
Normal file
11
src/v1/schemas/attribute_no_id.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct AttributeWithoutId {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/attribute_rest_search_filter.rs
Normal file
11
src/v1/schemas/attribute_rest_search_filter.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct AttributeRestSearchFilter {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
25
src/v1/schemas/attribute_rest_search_list.rs
Normal file
25
src/v1/schemas/attribute_rest_search_list.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use super::AttributeRestSearchListItem;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct AttributeRestSearchList {
|
||||
items: Vec<AttributeRestSearchListItem>
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<AttributeRestSearchListItem>> for AttributeRestSearchList {
|
||||
fn from(value: Vec<AttributeRestSearchListItem>) -> Self {
|
||||
AttributeRestSearchList { items: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<AttributeRestSearchListItem>> for AttributeRestSearchList {
|
||||
fn into(self) -> Vec<AttributeRestSearchListItem> {
|
||||
self.items
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/attribute_rest_search_list_item.rs
Normal file
11
src/v1/schemas/attribute_rest_search_list_item.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct AttributeRestSearchListItem {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/attribute_statistics_response.rs
Normal file
11
src/v1/schemas/attribute_statistics_response.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct AttributeStatisticsResponse {
|
||||
stats: Vec<(String, i64)>
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
255
src/v1/schemas/attribute_type.rs
Normal file
255
src/v1/schemas/attribute_type.rs
Normal file
|
@ -0,0 +1,255 @@
|
|||
use phf::phf_set;
|
||||
|
||||
default_derive! {
|
||||
pub struct AttributeType {
|
||||
t: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeType {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let valid_types: phf::Set<&'static str> = phf_set!(
|
||||
"md5",
|
||||
"sha1",
|
||||
"sha256",
|
||||
"filename",
|
||||
"pdb",
|
||||
"filename|md5",
|
||||
"filename|sha1",
|
||||
"filename|sha256",
|
||||
"ip-src",
|
||||
"ip-dst",
|
||||
"hostname",
|
||||
"domain",
|
||||
"domain|ip",
|
||||
"email",
|
||||
"email-src",
|
||||
"eppn",
|
||||
"email-dst",
|
||||
"email-subject",
|
||||
"email-attachment",
|
||||
"email-body",
|
||||
"float",
|
||||
"git-commit-id",
|
||||
"url",
|
||||
"http-method",
|
||||
"user-agent",
|
||||
"ja3-fingerprint-md5",
|
||||
"jarm-fingerprint",
|
||||
"favicon-mmh3",
|
||||
"hassh-md5",
|
||||
"hasshserver-md5",
|
||||
"regkey",
|
||||
"regkey|value",
|
||||
"AS",
|
||||
"snort",
|
||||
"bro",
|
||||
"zeek",
|
||||
"community-id",
|
||||
"pattern-in-file",
|
||||
"pattern-in-traffic",
|
||||
"pattern-in-memory",
|
||||
"pattern-filename",
|
||||
"pgp-public-key",
|
||||
"pgp-private-key",
|
||||
"yara",
|
||||
"stix2-pattern",
|
||||
"sigma",
|
||||
"gene",
|
||||
"kusto-query",
|
||||
"mime-type",
|
||||
"identity-card-number",
|
||||
"cookie",
|
||||
"vulnerability",
|
||||
"cpe",
|
||||
"weakness",
|
||||
"attachment",
|
||||
"malware-sample",
|
||||
"link",
|
||||
"comment",
|
||||
"text",
|
||||
"hex",
|
||||
"other",
|
||||
"named pipe",
|
||||
"mutex",
|
||||
"process-state",
|
||||
"target-user",
|
||||
"target-email",
|
||||
"target-machine",
|
||||
"target-org",
|
||||
"target-location",
|
||||
"target-external",
|
||||
"btc",
|
||||
"dash",
|
||||
"xmr",
|
||||
"iban",
|
||||
"bic",
|
||||
"bank-account-nr",
|
||||
"aba-rtn",
|
||||
"bin",
|
||||
"cc-number",
|
||||
"prtn",
|
||||
"phone-number",
|
||||
"threat-actor",
|
||||
"campaign-name",
|
||||
"campaign-id",
|
||||
"malware-type",
|
||||
"uri",
|
||||
"authentihash",
|
||||
"vhash",
|
||||
"ssdeep",
|
||||
"imphash",
|
||||
"telfhash",
|
||||
"pehash",
|
||||
"impfuzzy",
|
||||
"sha224",
|
||||
"sha384",
|
||||
"sha512",
|
||||
"sha512/224",
|
||||
"sha512/256",
|
||||
"sha3-224",
|
||||
"sha3-256",
|
||||
"sha3-384",
|
||||
"sha3-512",
|
||||
"tlsh",
|
||||
"cdhash",
|
||||
"filename|authentihash",
|
||||
"filename|vhash",
|
||||
"filename|ssdeep",
|
||||
"filename|imphash",
|
||||
"filename|impfuzzy",
|
||||
"filename|pehash",
|
||||
"filename|sha224",
|
||||
"filename|sha384",
|
||||
"filename|sha512",
|
||||
"filename|sha512/224",
|
||||
"filename|sha512/256",
|
||||
"filename|sha3-224",
|
||||
"filename|sha3-256",
|
||||
"filename|sha3-384",
|
||||
"filename|sha3-512",
|
||||
"filename|tlsh",
|
||||
"windows-scheduled-task",
|
||||
"windows-service-name",
|
||||
"windows-service-displayname",
|
||||
"whois-registrant-email",
|
||||
"whois-registrant-phone",
|
||||
"whois-registrant-name",
|
||||
"whois-registrant-org",
|
||||
"whois-registrar",
|
||||
"whois-creation-date",
|
||||
"x509-fingerprint-sha1",
|
||||
"x509-fingerprint-md5",
|
||||
"x509-fingerprint-sha256",
|
||||
"dns-soa-email",
|
||||
"size-in-bytes",
|
||||
"counter",
|
||||
"datetime",
|
||||
"port",
|
||||
"ip-dst|port",
|
||||
"ip-src|port",
|
||||
"hostname|port",
|
||||
"mac-address",
|
||||
"mac-eui-64",
|
||||
"email-dst-display-name",
|
||||
"email-src-display-name",
|
||||
"email-header",
|
||||
"email-reply-to",
|
||||
"email-x-mailer",
|
||||
"email-mime-boundary",
|
||||
"email-thread-index",
|
||||
"email-message-id",
|
||||
"github-username",
|
||||
"github-repository",
|
||||
"github-organisation",
|
||||
"jabber-id",
|
||||
"twitter-id",
|
||||
"dkim",
|
||||
"dkim-signature",
|
||||
"first-name",
|
||||
"middle-name",
|
||||
"last-name",
|
||||
"full-name",
|
||||
"date-of-birth",
|
||||
"place-of-birth",
|
||||
"gender",
|
||||
"passport-number",
|
||||
"passport-country",
|
||||
"passport-expiration",
|
||||
"redress-number",
|
||||
"nationality",
|
||||
"visa-number",
|
||||
"issue-date-of-the-visa",
|
||||
"primary-residence",
|
||||
"country-of-residence",
|
||||
"special-service-request",
|
||||
"frequent-flyer-number",
|
||||
"travel-details",
|
||||
"payment-details",
|
||||
"place-port-of-original-embarkation",
|
||||
"place-port-of-clearance",
|
||||
"place-port-of-onward-foreign-destination",
|
||||
"passenger-name-record-locator-number",
|
||||
"mobile-application-id",
|
||||
"chrome-extension-id",
|
||||
"cortex",
|
||||
"boolean",
|
||||
"anonymised"
|
||||
);
|
||||
if value.len() <= 100 && valid_types.contains(value) {
|
||||
Ok(AttributeType {
|
||||
t: value.to_string(),
|
||||
})
|
||||
} else {
|
||||
Err("Failed to parse AttributeType")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeType {
|
||||
fn into(self) -> String {
|
||||
self.t
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let t: Result<AttributeType, _> = "".try_into();
|
||||
assert!(t.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let t: Result<AttributeType, _> = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw".try_into();
|
||||
assert!(t.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unknown() {
|
||||
let t: Result<AttributeType, _> = "abcde".try_into();
|
||||
assert!(t.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let t: Result<AttributeType, _> = "text".try_into();
|
||||
assert_eq!(
|
||||
t,
|
||||
Ok(AttributeType {
|
||||
t: "text".to_string()
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let t: Result<AttributeType, _> = "filename|sha512/224".try_into();
|
||||
assert_eq!(
|
||||
t,
|
||||
Ok(AttributeType {
|
||||
t: "filename|sha512/224".to_string()
|
||||
})
|
||||
)
|
||||
}
|
44
src/v1/schemas/attribute_value.rs
Normal file
44
src/v1/schemas/attribute_value.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct AttributeValue {
|
||||
value: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for AttributeValue {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
if value.len() <= 131071 {
|
||||
Ok(AttributeValue { value: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse AttributeValue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AttributeValue {
|
||||
fn into(self) -> String {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let val: Result<AttributeValue, _> = format!("{:>131072}", "Test").as_str().try_into();
|
||||
assert!(val.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let val: Result<AttributeValue, _> = "".try_into();
|
||||
assert_eq!(val, Ok(AttributeValue { value: "".to_string() }))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let val: Result<AttributeValue, _> = "123456789".try_into();
|
||||
assert_eq!(val, Ok(AttributeValue {value: String::from("123456789")}))
|
||||
}
|
17
src/v1/schemas/decay_score.rs
Normal file
17
src/v1/schemas/decay_score.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use super::{FullDecayingModel, DecayingModel};
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct DecayScore {
|
||||
score: f64,
|
||||
base_score: f64,
|
||||
decayed: bool,
|
||||
decaying_model: DecayingModel,
|
||||
full_decaying_model: FullDecayingModel,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
13
src/v1/schemas/decay_score_list.rs
Normal file
13
src/v1/schemas/decay_score_list.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use super::DecayScore;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct DecayScoreList {
|
||||
scores: Vec<DecayScore>
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
12
src/v1/schemas/decaying_model.rs
Normal file
12
src/v1/schemas/decaying_model.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct DecayingModel {
|
||||
id: String,
|
||||
name: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
15
src/v1/schemas/decaying_model_parameters.rs
Normal file
15
src/v1/schemas/decaying_model_parameters.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct DecayingModelParameters {
|
||||
lifetime: f64,
|
||||
decay_speed: f64,
|
||||
threshold: f64,
|
||||
default_base_score: f64,
|
||||
base_score_config: Vec<(String, f64)>
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
16
src/v1/schemas/describe_attribute_types_response.rs
Normal file
16
src/v1/schemas/describe_attribute_types_response.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use super::{AttributeType, AttributeCategory};
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct DescribeAttributeTypesResponse {
|
||||
sane_defaults: Vec<(AttributeType, (String, i64))>,
|
||||
types: Vec<AttributeType>,
|
||||
categories: Vec<AttributeCategory>,
|
||||
category_type_mappings: Vec<(AttributeCategory, Vec<AttributeType>)>
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/event.rs
Normal file
11
src/v1/schemas/event.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct Event {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
40
src/v1/schemas/event_attribute_count.rs
Normal file
40
src/v1/schemas/event_attribute_count.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use regex_macro::regex;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct EventAttributeCount {
|
||||
count: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for EventAttributeCount {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let re = regex!("^[[:digit:]]+$");
|
||||
if re.is_match(value) {
|
||||
Ok(EventAttributeCount { count: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse EventId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for EventAttributeCount {
|
||||
fn into(self) -> String {
|
||||
self.count
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let id: Result<EventAttributeCount, _> = "".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let id: Result<EventAttributeCount, _> = "12345".try_into();
|
||||
assert_eq!(id, Ok(EventAttributeCount { count: "12345".to_string() }))
|
||||
}
|
52
src/v1/schemas/event_id.rs
Normal file
52
src/v1/schemas/event_id.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use regex_macro::regex;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct EventId {
|
||||
id: String,
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for EventId {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let re = regex!("^[[:digit:]]+$");
|
||||
if value.len() <= 10 && re.is_match(value) {
|
||||
Ok(EventId { id: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse EventId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for EventId {
|
||||
fn into(self) -> String {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let id: Result<EventId, _> = "".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let id: Result<EventId, _> = "12345678910".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let id: Result<EventId, _> = "12345".try_into();
|
||||
assert_eq!(id, Ok(EventId { id: "12345".to_string() }))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let id: Result<EventId, _> = "0123456789".try_into();
|
||||
assert_eq!(id, Ok(EventId { id: "0123456789".to_string() }))
|
||||
}
|
37
src/v1/schemas/event_info.rs
Normal file
37
src/v1/schemas/event_info.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct EventInfo {
|
||||
text: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for EventInfo {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
if value.len() <= 65535 {
|
||||
Ok(EventInfo { text: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse EventInfo")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for EventInfo {
|
||||
fn into(self) -> String {
|
||||
self.text
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let info: Result<EventInfo, _> = format!("{:>65536}", "Test").as_str().try_into();
|
||||
assert!(info.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let info: Result<EventInfo, _> = "Informational text".try_into();
|
||||
assert_eq!(info, Ok(EventInfo { text: "Informational text".to_string() }))
|
||||
}
|
11
src/v1/schemas/event_no_id.rs
Normal file
11
src/v1/schemas/event_no_id.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct EventWithoutId {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/event_organisation.rs
Normal file
11
src/v1/schemas/event_organisation.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct EventOrganisation {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/event_proposal_email_lock.rs
Normal file
11
src/v1/schemas/event_proposal_email_lock.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct EventProposalEmailLock {
|
||||
lock: bool
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/event_report.rs
Normal file
11
src/v1/schemas/event_report.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct EventReport {
|
||||
//TODO, not described in OpenAPI documentation
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
assert!(true)
|
||||
}
|
11
src/v1/schemas/event_tag.rs
Normal file
11
src/v1/schemas/event_tag.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct EventTag {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
52
src/v1/schemas/event_tag_id.rs
Normal file
52
src/v1/schemas/event_tag_id.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use regex_macro::regex;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct EventTagId {
|
||||
id: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for EventTagId {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let re = regex!("^[[:digit:]]+$");
|
||||
if value.len() <= 10 && re.is_match(value) {
|
||||
Ok(EventTagId { id: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse EventTagId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for EventTagId {
|
||||
fn into(self) -> String {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let id: Result<EventTagId, _> = "".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let id: Result<EventTagId, _> = "12345678910".try_into();
|
||||
assert!(id.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let id: Result<EventTagId, _> = "12345".try_into();
|
||||
assert_eq!(id, Ok(EventTagId { id: "12345".to_string() }))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid2() {
|
||||
let id: Result<EventTagId, _> = "0123456789".try_into();
|
||||
assert_eq!(id, Ok(EventTagId { id: "0123456789".to_string() }))
|
||||
}
|
25
src/v1/schemas/event_tag_list.rs
Normal file
25
src/v1/schemas/event_tag_list.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use super::EventTag;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct EventTagList {
|
||||
event_tags: Vec<EventTag>
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<EventTag>> for EventTagList {
|
||||
fn from(value: Vec<EventTag>) -> Self {
|
||||
EventTagList { event_tags: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<EventTag>> for EventTagList {
|
||||
fn into(self) -> Vec<EventTag> {
|
||||
self.event_tags
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/extended_attribute.rs
Normal file
11
src/v1/schemas/extended_attribute.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct ExtendedAttribute {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
11
src/v1/schemas/full_decaying_model.rs
Normal file
11
src/v1/schemas/full_decaying_model.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
default_derive!{
|
||||
pub struct FullDecayingModel {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
todo!()
|
||||
}
|
36
src/v1/schemas/mod.rs
Normal file
36
src/v1/schemas/mod.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
expose_submodules!(
|
||||
attribute_attachment,
|
||||
attribute_category,
|
||||
attribute_comment,
|
||||
attribute_event_uuid,
|
||||
attribute_id,
|
||||
attribute_list,
|
||||
attribute_no_id,
|
||||
attribute_rest_search_filter,
|
||||
attribute_rest_search_list_item,
|
||||
attribute_rest_search_list,
|
||||
attribute_statistics_response,
|
||||
attribute_type,
|
||||
attribute_value,
|
||||
attribute,
|
||||
decay_score_list,
|
||||
decay_score,
|
||||
decaying_model_parameters,
|
||||
decaying_model,
|
||||
describe_attribute_types_response,
|
||||
event_attribute_count,
|
||||
event_id,
|
||||
event_info,
|
||||
event_no_id,
|
||||
event_organisation,
|
||||
event_proposal_email_lock,
|
||||
event_report,
|
||||
event_tag_id,
|
||||
event_tag_list,
|
||||
event_tag,
|
||||
event,
|
||||
extended_attribute,
|
||||
full_decaying_model,
|
||||
uuid
|
||||
);
|
46
src/v1/schemas/uuid.rs
Normal file
46
src/v1/schemas/uuid.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use regex_macro::regex;
|
||||
|
||||
|
||||
default_derive!{
|
||||
pub struct UUID {
|
||||
id: String
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for UUID {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let re = regex!("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
|
||||
if value.len() <= 36 && re.is_match(value) {
|
||||
Ok(UUID { id: value.to_string() })
|
||||
}
|
||||
else {
|
||||
Err("Failed to parse UUID")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for UUID {
|
||||
fn into(self) -> String {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let uuid: Result<UUID, _> = "".try_into();
|
||||
assert!(uuid.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized() {
|
||||
let uuid: Result<UUID, _> = format!("{:>37}", "Test").as_str().try_into();
|
||||
assert!(uuid.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid1() {
|
||||
let uuid: Result<UUID, _> = "c99506a6-1255-4b71-afa5-7b8ba48c3b1b".try_into();
|
||||
assert_eq!(uuid, Ok(UUID { id: "c99506a6-1255-4b71-afa5-7b8ba48c3b1b".to_string() }))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue