1use std::{str::FromStr, sync::Arc};
2
3use crate::{
4 FetchError, LocatorError,
5 Resource::Unresolved,
6 modules::{arweave::Arweave, ethereum::Ethereum, http::Http, ipfs::Ipfs, swarm::Swarm},
7};
8
9pub type Dyncoder = Arc<dyn Decoder>;
10
11pub trait Decoder: Send + Sync + 'static {
12 fn decode(&self, bytes: Vec<u8>) -> Result<Resource, FetchError>;
13}
14
15pub trait Locator: Sized + Send + Sync + 'static + FromStr<Err = LocatorError> + PartialEq {
16 fn of(resource: &Resource) -> Option<&Self>;
17}
18
19pub enum Resource {
20 Raw(Vec<u8>),
21 Unresolved(String),
22 Http(Http),
23 Ipfs(Ipfs),
24 Swarm(Swarm),
25 Arweave(Arweave),
26 Ethereum(Ethereum),
27 Decode {
28 source: Box<Resource>,
29 decoder: Dyncoder,
30 },
31}
32
33impl From<Vec<u8>> for Resource {
34 fn from(bytes: Vec<u8>) -> Self {
35 Self::Raw(bytes)
36 }
37}
38
39impl From<Http> for Resource {
40 fn from(http: Http) -> Self {
41 Self::Http(http)
42 }
43}
44
45impl From<Ipfs> for Resource {
46 fn from(ipfs: Ipfs) -> Self {
47 Self::Ipfs(ipfs)
48 }
49}
50
51impl From<Swarm> for Resource {
52 fn from(swarm: Swarm) -> Self {
53 Self::Swarm(swarm)
54 }
55}
56
57impl From<Arweave> for Resource {
58 fn from(arweave: Arweave) -> Self {
59 Self::Arweave(arweave)
60 }
61}
62
63impl From<Ethereum> for Resource {
64 fn from(ethereum: Ethereum) -> Self {
65 Self::Ethereum(ethereum)
66 }
67}
68
69impl FromStr for Resource {
70 type Err = LocatorError;
71
72 fn from_str(s: &str) -> Result<Self, Self::Err> {
73 let (schema, _) = s.split_once(':').ok_or(LocatorError::NoSchema)?;
74
75 match schema.to_lowercase().as_str() {
76 "ipfs" | "ipns" => s.parse().map(Resource::Ipfs),
77 "bzz" => s.parse().map(Resource::Swarm),
78 "ar" => s.parse().map(Resource::Arweave),
79 "eip155" => s.parse().map(Resource::Ethereum),
80 "http" | "https" => s.parse().map(Resource::Http),
81 _ => Ok(Unresolved(s.to_string())),
83 }
84 }
85}
86
87impl Resource {
88 pub fn decoded_by(self, decoder: impl Decoder) -> Self {
89 Self::Decode {
90 source: Box::new(self),
91 decoder: Arc::new(decoder),
92 }
93 }
94}