1 use super::L64; 2 /// A unique identifier for files or directories in the actual 3 /// file system, to map "files from the graph" to real files. 4 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] 5 pub struct Inode(pub super::L64); 6 use byteorder::{BigEndian, ByteOrder}; 7 use std::str::FromStr; 8 9 impl std::fmt::Debug for Inode { fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result10 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { 11 let mut b = [0; 8]; 12 BigEndian::write_u64(&mut b, (self.0).0); 13 write!(fmt, "Inode({})", data_encoding::BASE32_NOPAD.encode(&b)) 14 } 15 } 16 17 impl Inode { 18 pub const ROOT: Inode = Inode(L64(0u64)); is_root(&self) -> bool19 pub fn is_root(&self) -> bool { 20 *self == Inode::ROOT 21 } 22 } 23 24 impl FromStr for Inode { 25 type Err = <u64 as FromStr>::Err; from_str(x: &str) -> Result<Self, Self::Err>26 fn from_str(x: &str) -> Result<Self, Self::Err> { 27 Ok(x.parse::<u64>()?.into()) 28 } 29 } 30 31 impl From<u64> for Inode { from(x: u64) -> Inode32 fn from(x: u64) -> Inode { 33 Inode(x.into()) 34 } 35 } 36 37 impl From<Inode> for u64 { from(x: Inode) -> u6438 fn from(x: Inode) -> u64 { 39 x.0.into() 40 } 41 } 42 43 use super::Base32; 44 45 impl Base32 for Inode { to_base32(&self) -> String46 fn to_base32(&self) -> String { 47 let inode: u64 = self.0.into(); 48 let mut b = [0; 8]; 49 BigEndian::write_u64(&mut b, inode); 50 let mut bb = [0; 13]; 51 data_encoding::BASE32_NOPAD.encode_mut(&b, &mut bb); 52 let b = std::str::from_utf8(&bb).unwrap(); 53 b.to_string() 54 } from_base32(s: &[u8]) -> Option<Self>55 fn from_base32(s: &[u8]) -> Option<Self> { 56 let mut b = [0; 8]; 57 if data_encoding::BASE32_NOPAD.decode_mut(s, &mut b).is_ok() { 58 Some(Inode(BigEndian::read_u64(&b).into())) 59 } else { 60 None 61 } 62 } 63 } 64 65 pub mod inode_base32_serde { 66 use super::*; 67 use serde::*; 68 69 pub struct InodeDe {} 70 71 impl<'de> serde::de::Visitor<'de> for InodeDe { 72 type Value = Inode; 73 expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result74 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { 75 write!(formatter, "a base32-encoded string") 76 } 77 visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: de::Error,78 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> 79 where 80 E: de::Error, 81 { 82 let mut b = [0; 8]; 83 if data_encoding::BASE32_NOPAD 84 .decode_mut(s.as_bytes(), &mut b) 85 .is_ok() 86 { 87 let b: u64 = BigEndian::read_u64(&b); 88 Ok(Inode(b.into())) 89 } else { 90 Err(de::Error::invalid_value( 91 serde::de::Unexpected::Str(s), 92 &self, 93 )) 94 } 95 } 96 } 97 deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Inode, D::Error>98 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Inode, D::Error> { 99 d.deserialize_str(InodeDe {}) 100 } 101 serialize<S: Serializer>(inode: &Inode, s: S) -> Result<S::Ok, S::Error>102 pub fn serialize<S: Serializer>(inode: &Inode, s: S) -> Result<S::Ok, S::Error> { 103 let inode: u64 = inode.0.into(); 104 let mut b = [0; 8]; 105 BigEndian::write_u64(&mut b, inode); 106 let mut bb = [0; 13]; 107 data_encoding::BASE32_NOPAD.encode_mut(&b, &mut bb); 108 let b = std::str::from_utf8(&bb).unwrap(); 109 s.serialize_str(b) 110 } 111 } 112