triphosphate_vocab/
lib.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5#[cfg(test)]
6mod tests;
7
8#[derive(Debug, Clone, Deserialize, Serialize, libipld::DagCbor, PartialEq)]
9pub struct Uri;
10
11#[derive(Debug, Clone, Deserialize, Serialize, libipld::DagCbor, PartialEq)]
12pub struct Blob;
13
14// TODO: Should this be pub?
15// TODO: Require Serde+CBOR traits?
16pub trait StringFormat: Sized {
17    fn as_str(&self) -> &str;
18
19    type Error: std::error::Error;
20
21    fn from_str(s: &str) -> Result<Self, Self::Error>;
22}
23
24#[derive(Debug)]
25pub struct ParseError(());
26impl fmt::Display for ParseError {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        write!(f, "failed to parse NSID")
29    }
30}
31impl std::error::Error for ParseError {}
32
33mod any;
34mod at_identifer;
35mod at_uri;
36mod bytes;
37mod cid;
38mod cid_link;
39mod datetime;
40mod did;
41mod handle;
42mod language;
43mod nsid;
44mod parsing;
45
46pub use self::cid::Cid;
47pub use any::{from_any, to_any, Any};
48pub use at_identifer::AtIdentifier;
49pub use at_uri::AtUri;
50pub use bytes::Bytes;
51pub use cid_link::CidLink;
52pub use datetime::Datetime;
53pub use did::Did;
54pub use handle::Handle;
55pub use language::Language;
56pub use nsid::Nsid;
57
58macro_rules! serde_impls {
59    ($($name:path)*) => {$(
60        impl ::serde::Serialize for $name {
61            fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
62                ::serde::Serialize::serialize($crate::StringFormat::as_str(self), serializer)
63            }
64        }
65
66        impl<'de> ::serde::Deserialize<'de> for $name {
67            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68            where
69                D: serde::Deserializer<'de>,
70            {
71                struct Visitor;
72
73                impl<'de> ::serde::de::Visitor<'de> for Visitor {
74                    type Value = $name;
75
76                    fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
77                        ::std::write!(f, concat!("a string for ", stringify!($name)))
78                    }
79
80                    fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
81                        $crate::StringFormat::from_str(v).map_err(E::custom)
82                    }
83                }
84
85                ::serde::Deserializer::deserialize_str(deserializer, Visitor)
86            }
87        }
88
89        impl libipld::codec::Encode<libipld::cbor::DagCborCodec> for $name {
90            fn encode<W: std::io::Write>(
91                &self,
92                c: libipld::cbor::DagCborCodec,
93                w: &mut W,
94            ) -> libipld::Result<()> {
95                self.as_str().encode(c, w)
96            }
97        }
98
99        impl libipld::codec::Decode<libipld::cbor::DagCborCodec> for $name {
100            fn decode<R: std::io::Read + std::io::Seek>(
101                c: libipld::cbor::DagCborCodec,
102                r: &mut R,
103            ) -> libipld::Result<Self> {
104                let s = String::decode(c, r)?;
105                let this = Self::from_str(&s)?;
106
107                Ok(this)
108            }
109        }
110    )*};
111}
112
113serde_impls! {
114    AtIdentifier
115    AtUri
116    Cid
117    Datetime
118    Did
119    Handle
120    Language
121    Nsid
122}