valico/json_schema/
helpers.rs
1use serde_json::{Value};
2use url::{Url};
3use url::percent_encoding;
4use uuid::{Uuid};
5
6use super::schema;
7
8pub fn generate_id() -> Url {
9 let uuid = Uuid::new_v4();
10 Url::parse(&format!("json-schema://{}", uuid)).unwrap()
11}
12
13pub fn encode(string: &str) -> String {
15 percent_encoding::percent_encode(
16 string
17 .replace("~", "~0")
18 .replace("/", "~1")
19 .replace("%", "%25")
20 .as_bytes(),
21 percent_encoding::QUERY_ENCODE_SET
22 ).to_string()
23}
24
25pub fn connect(strings: &[&str]) -> String {
27 strings.iter().map(|s| encode(s)).collect::<Vec<String>>().join("/")
28}
29
30pub fn parse_url_key(key: &str, obj: &Value) -> Result<Option<Url>, schema::SchemaError> {
31 match obj.get(key) {
32 Some(value) => {
33 match value.as_str() {
34 Some(string) => Url::parse(string)
35 .map(|url| Some(url))
36 .map_err(|err| schema::SchemaError::UrlParseError(err)),
37 None => Ok(None)
38 }
39 },
40 None => Ok(None)
41 }
42}
43
44pub fn parse_url_key_with_base(key: &str, obj: &Value, base: &Url) -> Result<Option<Url>, schema::SchemaError> {
45 match obj.get(key) {
46 Some(value) => {
47 match value.as_str() {
48 Some(string) => Url::options()
49 .base_url(Some(base))
50 .parse(string)
51 .map(|url| Some(url))
52 .map_err(|err| schema::SchemaError::UrlParseError(err)),
53 None => Ok(None)
54 }
55 },
56 None => Ok(None)
57 }
58}
59
60pub fn alter_fragment_path(mut url: Url, new_fragment: String) -> Url {
61
62 let normalized_fragment = if new_fragment.starts_with("/") {
63 &new_fragment[1..]
64 } else {
65 new_fragment.as_ref()
66 };
67
68 let result_fragment = match url.fragment() {
69 Some(ref fragment) if fragment.len() > 0 => {
70 if !fragment.starts_with("/") {
71 let mut result_fragment = "".to_string();
72 let mut fragment_parts = fragment.split("/").map(|s| s.to_string());
73 result_fragment.push_str("#");
74 result_fragment.push_str(fragment_parts.next().unwrap().as_ref());
75 result_fragment.push_str("/");
76 result_fragment.push_str(normalized_fragment.as_ref());
77 result_fragment
78 } else {
79 "/".to_string() + normalized_fragment
80 }
81 },
82 _ => "/".to_string() + normalized_fragment
83 };
84
85 url.set_fragment(Some(&result_fragment));
86 url
87}
88
89pub fn serialize_schema_path(url: &Url) -> (String, Option<String>) {
90 let mut url_without_fragment = url.clone();
91 url_without_fragment.set_fragment(None);
92 let mut url_str = url_without_fragment.into_string();
93
94 match url.fragment().as_ref() {
95 Some(fragment) if fragment.len() > 0 => {
96 if !fragment.starts_with("/") {
97 let fragment_parts = fragment.split("/").map(|s| s.to_string()).collect::<Vec<String>>();
98 url_str.push_str("#");
99 url_str.push_str(fragment_parts[0].as_ref());
100 let fragment = if fragment_parts.len() > 1 {
101 Some("/".to_string() + fragment_parts[1..].join("/").as_ref())
102 } else {
103 None
104 };
105 (url_str, fragment)
106 } else {
107 (url_str, Some(fragment.to_string()))
108 }
109
110 },
111 _ => (url_str, None)
112 }
113}