nmd_core/resource/
source.rs1use 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}