wnfs_unixfs_file/
protobufs.rs

1use bytes::Bytes;
2use prost::{Enumeration, Message};
3
4/// An IPFS MerkleDAG Link
5#[derive(Clone, PartialEq, Eq, Message)]
6pub struct PbLink {
7    /// multihash of the target object
8    #[prost(bytes = "vec", optional, tag = "1")]
9    pub hash: Option<Vec<u8>>,
10    /// utf string name. should be unique per object
11    #[prost(string, optional, tag = "2")]
12    pub name: Option<String>,
13    /// cumulative size of target object
14    #[prost(uint64, optional, tag = "3")]
15    pub tsize: Option<u64>,
16}
17
18/// An IPFS MerkleDAG Node
19#[derive(Clone, PartialEq, Eq, Message)]
20pub struct PbNode {
21    /// refs to other objects
22    #[prost(message, repeated, tag = "2")]
23    pub links: Vec<PbLink>,
24    /// opaque user data
25    #[prost(bytes = "bytes", optional, tag = "1")]
26    pub data: Option<Bytes>,
27}
28
29#[derive(Clone, PartialEq, Eq, Message)]
30pub struct Data {
31    #[prost(enumeration = "DataType", tag = "1")]
32    pub r#type: i32,
33    #[prost(bytes = "bytes", optional, tag = "2")]
34    pub data: Option<Bytes>,
35    #[prost(uint64, optional, tag = "3")]
36    pub filesize: Option<u64>,
37    #[prost(uint64, repeated, tag = "4")]
38    pub blocksizes: Vec<u64>,
39    #[prost(uint64, optional, tag = "5")]
40    pub hash_type: Option<u64>,
41    #[prost(uint64, optional, tag = "6")]
42    pub fanout: Option<u64>,
43}
44/// Nested message and enum types in `Data`.
45#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
46#[repr(i32)]
47pub enum DataType {
48    Raw = 0,
49    Directory = 1,
50    File = 2,
51    Metadata = 3,
52    Symlink = 4,
53    HamtShard = 5,
54}
55
56impl DataType {
57    /// String value of the enum field names used in the ProtoBuf definition.
58    ///
59    /// The values are not transformed in any way and thus are considered stable
60    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
61    pub fn as_str_name(&self) -> &'static str {
62        match self {
63            DataType::Raw => "Raw",
64            DataType::Directory => "Directory",
65            DataType::File => "File",
66            DataType::Metadata => "Metadata",
67            DataType::Symlink => "Symlink",
68            DataType::HamtShard => "HAMTShard",
69        }
70    }
71    /// Creates an enum from field names used in the ProtoBuf definition.
72    pub fn from_str_name(value: &str) -> Option<Self> {
73        match value {
74            "Raw" => Some(Self::Raw),
75            "Directory" => Some(Self::Directory),
76            "File" => Some(Self::File),
77            "Metadata" => Some(Self::Metadata),
78            "Symlink" => Some(Self::Symlink),
79            "HAMTShard" => Some(Self::HamtShard),
80            _ => None,
81        }
82    }
83}
84
85#[derive(Clone, PartialEq, Message)]
86pub struct Metadata {
87    #[prost(string, optional, tag = "1")]
88    pub mime_type: Option<String>,
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94    use prost::Message;
95    use testresult::TestResult;
96
97    #[test]
98    fn test_parse_data_example() -> TestResult {
99        let examples = [
100            "CAIYy4USIICAECDLhQI",
101            "CAIYwtqZKSCAgOAVIMLauRM",
102            "CAIYgIDgFSCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAECCAgBAggIAQIICAEA",
103        ];
104        for example in examples {
105            let data = data_encoding::BASE64URL_NOPAD.decode(example.as_ref())?;
106            let d = Data::decode(data.as_ref())?;
107
108            assert_eq!(d.blocksizes.iter().sum::<u64>(), d.filesize.unwrap());
109
110            println!("{d:#?}");
111        }
112
113        Ok(())
114    }
115}