valico/json_schema/keywords/
content_media.rs1use base64;
2use base64::Engine;
3use serde_json::Value;
4use std::str;
5
6use super::super::schema;
7use super::super::validators;
8
9#[derive(Debug)]
10pub enum ContentMediaType {
11 ApplicationJson,
12}
13
14impl ContentMediaType {
15 pub fn as_str(&self) -> &str {
16 match self {
17 ContentMediaType::ApplicationJson => "application/json",
18 }
19 }
20
21 pub fn validate(&self, val: &str) -> bool {
22 match self {
23 ContentMediaType::ApplicationJson => serde_json::from_str::<Value>(val),
24 }
25 .is_ok()
26 }
27}
28
29impl str::FromStr for ContentMediaType {
30 type Err = ();
31 fn from_str(s: &str) -> Result<ContentMediaType, ()> {
32 match s {
33 "application/json" => Ok(ContentMediaType::ApplicationJson),
34 _ => Err(()),
35 }
36 }
37}
38
39#[derive(Debug)]
40pub enum ContentEncoding {
41 Base64,
42}
43
44impl ContentEncoding {
45 pub fn as_str(&self) -> &str {
46 match self {
47 ContentEncoding::Base64 => "base64",
48 }
49 }
50
51 pub fn decode_val(&self, val: &str) -> Result<String, String> {
52 match self {
53 ContentEncoding::Base64 => {
54 match base64::engine::general_purpose::STANDARD.decode(val) {
55 Ok(v) => match str::from_utf8(&v[..]) {
56 Ok(s) => Ok(s.to_string()),
57 Err(e) => Err(e.to_string()),
58 },
59 Err(e) => Err(e.to_string()),
60 }
61 }
62 }
63 }
64}
65
66impl str::FromStr for ContentEncoding {
67 type Err = ();
68 fn from_str(s: &str) -> Result<ContentEncoding, ()> {
69 match s {
70 "base64" => Ok(ContentEncoding::Base64),
71 _ => Err(()),
72 }
73 }
74}
75
76#[allow(missing_copy_implementations)]
77pub struct ContentMedia;
78impl super::Keyword for ContentMedia {
79 fn compile(&self, def: &Value, ctx: &schema::WalkContext<'_>) -> super::KeywordResult {
80 let maybe_content_media_type = def.get("contentMediaType");
81 let mut type_ = None;
82 if let Some(content_media_type) = maybe_content_media_type {
83 if !content_media_type.is_string() {
84 return Err(schema::SchemaError::Malformed {
85 path: ctx.fragment.join("/"),
86 detail: "contentMediaType MUST be a string.".to_string(),
87 });
88 } else {
89 let media_type = content_media_type.as_str().unwrap().parse().ok();
90 if let Some(media_type) = media_type {
91 type_ = Some(media_type);
92 } else {
93 return Err(schema::SchemaError::Malformed {
94 path: ctx.fragment.join("/"),
95 detail: "contentMediaType MUST be one of [\"application/json\"]"
96 .to_string(),
97 });
98 }
99 }
100 }
101
102 let maybe_content_encoding = def.get("contentEncoding");
103 let mut encoding = None;
104 if let Some(content_encoding) = maybe_content_encoding {
105 if !content_encoding.is_string() {
106 return Err(schema::SchemaError::Malformed {
107 path: ctx.fragment.join("/"),
108 detail: "contentEncoding MUST be a string.".to_string(),
109 });
110 } else {
111 let encoding_ = content_encoding.as_str().unwrap().parse().ok();
112 if let Some(encoding_) = encoding_ {
113 encoding = Some(encoding_);
114 } else {
115 return Err(schema::SchemaError::Malformed {
116 path: ctx.fragment.join("/"),
117 detail: "contentEncoding MUST be one of [\"base64\"]".to_string(),
118 });
119 }
120 }
121 }
122
123 Ok(Some(Box::new(validators::ContentMedia { type_, encoding })))
124 }
125}