Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm
0

Configure Feed

Select the types of activity you want to include in your feed.

checkpoint: byte encoding helpers

+77 -43
+77 -43
ufos/src/store_types.rs
··· 1 - use crate::Nsid; //, Cursor}; 1 + use crate::{Cursor, Nsid}; 2 2 use bincode::{ 3 3 config::{standard, Config}, 4 - decode_from_slice, encode_to_vec, 4 + de::Decode as BincodeDecode, 5 + decode_from_slice, 6 + enc::Encode as BincodeEncode, 7 + encode_to_vec, 5 8 error::{DecodeError, EncodeError}, 6 9 }; 7 10 use thiserror::Error; 8 11 9 12 #[derive(Error, Debug)] 10 - pub enum BlahError { 11 - #[error("could not convert from utf8: {0}")] 12 - NotUtf8(#[from] std::str::Utf8Error), 13 + pub enum EncodingError { 13 14 #[error("failed to parse NSID: {0}")] 14 15 BadNSID(&'static str), 15 - #[error("failed to encode: {0}")] 16 - EncodeFailed(#[from] EncodeError), 17 - #[error("failed to decode: {0}")] 18 - DecodeFailed(#[from] DecodeError), 16 + #[error("failed to bincode-encode: {0}")] 17 + BincodeEncodeFailed(#[from] EncodeError), 18 + #[error("failed to bincode-decode: {0}")] 19 + BincodeDecodeFailed(#[from] DecodeError), 19 20 #[error("decode missing suffix bytes")] 20 21 DecodeMissingSuffix, 22 + #[error("decode ran out of bytes")] 23 + DecodeNotEnoughBytes, 21 24 } 22 25 23 - fn bconf() -> impl Config { 26 + fn bincode_conf() -> impl Config { 24 27 standard().with_big_endian().with_fixed_int_encoding() 25 28 } 26 29 27 - trait DbBytes { 28 - fn to_bincoded(&self) -> Result<Vec<u8>, BlahError>; 29 - fn from_bincoded(bytes: &[u8]) -> Result<(Self, usize), BlahError> 30 + pub trait DbBytes { 31 + fn to_bytes(&self) -> Result<Vec<u8>, EncodingError>; 32 + fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), EncodingError> 30 33 where 31 34 Self: Sized; 32 35 } 33 36 34 - trait DbStringType: AsRef<str> { 35 - fn from_string(s: String) -> Result<Self, BlahError> 37 + pub trait DbStringType: AsRef<str> { 38 + fn from_string(s: String) -> Result<Self, EncodingError> 36 39 where 37 40 Self: Sized; 38 41 } 39 42 40 - impl<T: DbStringType> DbBytes for T { 41 - fn to_bincoded(&self) -> Result<Vec<u8>, BlahError> { 42 - Ok(encode_to_vec(self.as_ref(), bconf())?) 43 - } 44 - fn from_bincoded(bytes: &[u8]) -> Result<(Self, usize), BlahError> 45 - where 46 - Self: Sized, 47 - { 48 - let (s, n) = decode_from_slice(bytes, bconf())?; 49 - let me = Self::from_string(s)?; 50 - Ok((me, n)) 43 + impl DbBytes for String { 44 + fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> { 45 + Ok(encode_to_vec::<&Self, _>(self, bincode_conf())?) 51 46 } 52 - } 53 - 54 - impl DbStringType for Nsid { 55 - fn from_string(s: String) -> Result<Self, BlahError> { 56 - Self::new(s).map_err(BlahError::BadNSID) 47 + fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), EncodingError> { 48 + Ok(decode_from_slice(bytes, bincode_conf())?) 57 49 } 58 50 } 59 51 60 - struct DbKeyWithPrefix<P: DbBytes, S: DbBytes> { 52 + pub struct DbKeyWithPrefix<P: DbBytes, S: DbBytes> { 61 53 prefix: P, 62 54 suffix: S, 63 55 } 64 56 65 57 impl<P: DbBytes, S: DbBytes> DbKeyWithPrefix<P, S> { 66 - fn to_prefix_bincoded(&self) -> Result<Vec<u8>, BlahError> { 67 - self.prefix.to_bincoded() 58 + pub fn to_prefix_bincoded(&self) -> Result<Vec<u8>, EncodingError> { 59 + self.prefix.to_bytes() 68 60 } 69 61 } 70 62 71 63 impl<P: DbBytes, S: DbBytes> DbBytes for DbKeyWithPrefix<P, S> { 72 - fn to_bincoded(&self) -> Result<Vec<u8>, BlahError> { 73 - let mut combined = self.prefix.to_bincoded()?; 74 - combined.append(&mut self.suffix.to_bincoded()?); 64 + fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> { 65 + let mut combined = self.prefix.to_bytes()?; 66 + combined.append(&mut self.suffix.to_bytes()?); 75 67 Ok(combined) 76 68 } 77 - fn from_bincoded(bytes: &[u8]) -> Result<(Self, usize), BlahError> 69 + fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), EncodingError> 78 70 where 79 71 Self: Sized, 80 72 { 81 - let (prefix, eaten) = P::from_bincoded(bytes)?; 73 + let (prefix, eaten) = P::from_bytes(bytes)?; 82 74 let Some(suffix_bytes) = bytes.get(eaten..) else { 83 - return Err(BlahError::DecodeMissingSuffix); 75 + return Err(EncodingError::DecodeMissingSuffix); 84 76 }; 85 - let (suffix, also_eaten) = S::from_bincoded(suffix_bytes)?; 77 + let (suffix, also_eaten) = S::from_bytes(suffix_bytes)?; 86 78 Ok((Self { prefix, suffix }, eaten + also_eaten)) 87 79 } 88 80 } 89 81 90 - fn blah(nsd: Nsid) { 91 - let _ = nsd.to_bincoded().unwrap(); 82 + trait Bincodeable: BincodeEncode + BincodeDecode<()> + Sized {} 83 + 84 + impl<T> DbBytes for T 85 + where 86 + T: Bincodeable, 87 + { 88 + fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> { 89 + Ok(encode_to_vec(self, bincode_conf())?) 90 + } 91 + fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), EncodingError> { 92 + Ok(decode_from_slice(bytes, bincode_conf())?) 93 + } 94 + } 95 + 96 + ////// 97 + 98 + impl DbBytes for Nsid { 99 + fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), EncodingError> { 100 + let (s, n) = decode_from_slice(bytes, bincode_conf())?; 101 + let me = Self::new(s).map_err(EncodingError::BadNSID)?; 102 + Ok((me, n)) 103 + } 104 + fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> { 105 + Ok(encode_to_vec(self.as_ref(), bincode_conf())?) 106 + } 107 + } 108 + 109 + impl DbBytes for Cursor { 110 + fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> { 111 + Ok(self.to_raw_u64().to_be_bytes().to_vec()) 112 + } 113 + fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), EncodingError> { 114 + let Ok(bytes8) = TryInto::<[u8; 8]>::try_into(bytes) else { 115 + return Err(EncodingError::DecodeNotEnoughBytes); 116 + }; 117 + let cursor = Cursor::from_raw_u64(u64::from_be_bytes(bytes8)); 118 + Ok((cursor, 8)) 119 + } 120 + } 121 + 122 + /////// 123 + 124 + pub fn blah(nsd: Nsid) { 125 + let _ = nsd.to_bytes().unwrap(); 92 126 }