teo_runtime/value/
file.rs

1use std::collections::HashSet;
2use std::fmt::{Display, Formatter};
3use itertools::Itertools;
4use maplit::hashset;
5use serde::Serialize;
6use serde_json::{Value as JsonValue};
7use teo_result::Error;
8
9#[derive(Debug, Clone, PartialEq, Serialize)]
10pub struct File {
11    pub filepath: String,
12    #[serde(rename(serialize = "contentType"))]
13    pub content_type: Option<String>,
14    pub filename: String,
15    #[serde(rename(serialize = "filenameExt"))]
16    pub filename_ext: Option<String>,
17}
18
19impl File {
20
21    pub fn filepath(&self) -> &str {
22        self.filepath.as_str()
23    }
24
25    pub fn content_type(&self) -> Option<&str> {
26        self.content_type.as_deref()
27    }
28
29    pub fn filename(&self) -> &str {
30        self.filename.as_str()
31    }
32
33    pub fn filename_ext(&self) -> Option<&str> {
34        self.filename_ext.as_deref()
35    }
36}
37
38impl Display for File {
39
40    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41        f.write_str("File(\"")?;
42        f.write_str(&self.filepath.as_str().replace("\"", "\\\""))?;
43        f.write_str("\")")
44    }
45}
46
47impl TryFrom<&JsonValue> for File {
48
49    type Error = Error;
50
51    fn try_from(value: &JsonValue) -> Result<Self, Self::Error> {
52        if let Some(object) = value.as_object() {
53            let keys_set: HashSet<&str> = object.keys().map(|k| k.as_str()).collect();
54            let difference: HashSet<&str> = keys_set.difference(&hashset!{"filepath", "contentType", "filename", "filenameExt"}).map(|s| *s).collect();
55            if !difference.is_empty() {
56                return Err(Error::new(format!("Connot convert json value to file, unexpected key {}", difference.iter().map(|k| format!("`{}`", *k)).join(", "))));
57            }
58            Ok(Self {
59                filepath: if let Some(filepath) = object.get("filepath") {
60                    if let Some(filepath) = filepath.as_str() {
61                        filepath.to_owned()
62                    } else {
63                        Err(Error::new(format!("Cannot convert json value to file, invalid value at `filepath`, expect string")))?
64                    }
65                } else {
66                    Err(Error::new(format!("Cannot convert json value to file, missing key `filepath`")))?
67                },
68                content_type: if let Some(content_type) = object.get("contentType") {
69                    if let Some(content_type) = content_type.as_str() {
70                        Some(content_type.to_owned())
71                    } else if content_type.is_null() {
72                        None
73                    } else {
74                        Err(Error::new(format!("Cannot convert json value to file, invalid value at `contentType`, expect string")))?
75                    }
76                } else {
77                    None
78                },
79                filename: if let Some(filename) = object.get("filename") {
80                    if let Some(filename) = filename.as_str() {
81                        filename.to_owned()
82                    } else {
83                        Err(Error::new(format!("Cannot convert json value to file, invalid value at `filename`, expect string")))?
84                    }
85                } else {
86                    Err(Error::new(format!("Cannot convert json value to file, missing key `filename`")))?
87                },
88                filename_ext: if let Some(filename_ext) = object.get("filenameExt") {
89                    if let Some(filename_ext) = filename_ext.as_str() {
90                        Some(filename_ext.to_owned())
91                    } else if filename_ext.is_null() {
92                        None
93                    } else {
94                        Err(Error::new(format!("Cannot convert json value to file, invalid value at `filenameExt`, expect string")))?
95                    }
96                } else {
97                    None
98                },
99            })
100        } else {
101            Err(Error::new(format!("Cannot convert json value to file, value `{}` is not object", value)))
102        }
103    }
104}