Skip to main content

loadsmith_core/
source.rs

1use std::{fmt::Display, str::FromStr};
2
3use camino::Utf8PathBuf;
4use serde::{Deserialize, Serialize};
5use url::Url;
6
7use crate::{Error, Result};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(into = "String", try_from = "String")]
11pub enum FileUrl {
12    Url(Url),
13    Path(Utf8PathBuf),
14}
15
16impl FileUrl {
17    pub fn try_from_url(s: &str) -> Result<Self> {
18        let url = Url::parse(s)?;
19        Ok(Self::Url(url))
20    }
21}
22
23impl Display for FileUrl {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        match self {
26            FileUrl::Url(url) => write!(f, "{url}"),
27            FileUrl::Path(path) => write!(f, "file://{path}"),
28        }
29    }
30}
31
32impl From<FileUrl> for String {
33    fn from(source: FileUrl) -> Self {
34        source.to_string()
35    }
36}
37
38impl FromStr for FileUrl {
39    type Err = Error;
40
41    fn from_str(s: &str) -> Result<Self> {
42        if let Some(path) = s.strip_prefix("file://") {
43            Ok(FileUrl::Path(Utf8PathBuf::from(path)))
44        } else {
45            FileUrl::try_from_url(s)
46        }
47    }
48}
49
50impl TryFrom<String> for FileUrl {
51    type Error = Error;
52
53    fn try_from(s: String) -> Result<Self> {
54        s.parse()
55    }
56}
57
58impl From<Url> for FileUrl {
59    fn from(url: Url) -> Self {
60        Self::Url(url)
61    }
62}
63
64impl From<Utf8PathBuf> for FileUrl {
65    fn from(path: Utf8PathBuf) -> Self {
66        Self::Path(path)
67    }
68}