ssi_status/impl/bitstring_status_list/syntax/
mod.rsuse std::io::{Read, Write};
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
use multibase::Base;
use serde::{Deserialize, Serialize};
mod status_list;
pub use status_list::*;
mod entry_set;
pub use entry_set::*;
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct EncodedList(String);
impl EncodedList {
pub const MINIMUM_SIZE: usize = 16 * 1024;
pub const DEFAULT_LIMIT: u64 = 16 * 1024 * 1024;
pub fn new(value: String) -> Self {
Self(value)
}
pub fn encode(bytes: &[u8]) -> Self {
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(bytes).unwrap();
const PADDING_BUFFER_LEN: usize = 1024;
let padding = [0; PADDING_BUFFER_LEN];
let mut it = (bytes.len()..Self::MINIMUM_SIZE)
.step_by(PADDING_BUFFER_LEN)
.peekable();
while let Some(start) = it.next() {
let end = it.peek().copied().unwrap_or(Self::MINIMUM_SIZE);
let len = end - start;
encoder.write_all(&padding[..len]).unwrap();
}
let compressed = encoder.finish().unwrap();
Self(multibase::encode(Base::Base64Url, compressed))
}
pub fn decode(&self, limit: Option<u64>) -> Result<Vec<u8>, DecodeError> {
let limit = limit.unwrap_or(Self::DEFAULT_LIMIT);
let (_base, compressed) = multibase::decode(&self.0)?;
let mut decoder = GzDecoder::new(compressed.as_slice()).take(limit);
let mut bytes = Vec::new();
decoder.read_to_end(&mut bytes).map_err(DecodeError::Gzip)?;
Ok(bytes)
}
}