nmd_core/resource/
source.rs

1use std::{fs::File, io::Read, path::PathBuf, str::FromStr};
2use base64::Engine;
3use url::Url;
4
5use super::ResourceError;
6
7
8#[derive(Debug, Clone)]
9pub enum Source {
10    Remote{ url: Url },
11    Local{ path: PathBuf },
12    Base64String{ base64: String },
13    Bytes{ bytes: Vec<u8> },
14}
15
16impl Source {
17
18    pub fn try_to_base64(&self) -> Result<String, ResourceError> {
19
20        let bytes = self.try_to_bytes()?;
21
22        Ok(base64::engine::general_purpose::STANDARD.encode(bytes))
23    }
24
25    pub fn try_into_base64(self) -> Result<Self, ResourceError> {
26
27        Ok(Self::Base64String { base64: self.try_to_base64()? })
28
29    }
30
31    pub fn try_to_bytes(&self) -> Result<Vec<u8>, ResourceError> {
32        match self {
33            Self::Remote { url } => return Err(ResourceError::WrongElaboration(format!("url '{}' cannot be parsed into bytes", url))),
34            Self::Local { path } => {
35
36                let mut image_file = File::open(path.clone())?;
37                let mut bytes: Vec<u8> = Vec::new();
38                image_file.read_to_end(&mut bytes)?;
39
40                return Ok(bytes)
41            },
42            Self::Base64String { base64 } => Ok(base64::engine::general_purpose::STANDARD.decode(base64).unwrap()),
43            Self::Bytes { bytes } => Ok(bytes.clone()),
44        }
45    }
46
47    pub fn try_into_bytes(self) -> Result<Self, ResourceError> {
48
49        let bytes = self.try_to_bytes()?;
50
51        Ok(Self::Bytes { bytes })
52    }
53}
54
55impl FromStr for Source {
56    type Err = ResourceError;
57
58    fn from_str(s: &str) -> Result<Self, Self::Err> {
59        let source = match reqwest::Url::parse(s) {
60            Ok(url) => Self::Remote { url },
61            Err(_) => Self::Local { path: PathBuf::from(s) },
62        };
63
64        Ok(source)
65    }
66}
67
68impl ToString for Source {
69    fn to_string(&self) -> String {
70        match self {
71            Source::Remote { url } => url.as_str().to_string(),
72            Source::Local { path } => path.to_string_lossy().to_string(),
73            Source::Base64String { base64 } => base64.clone(),
74            Source::Bytes { bytes: base64 } => base64::engine::general_purpose::STANDARD.encode(base64),
75        }
76    }
77}