use bytes::Bytes; use serde::{Deserialize, Serialize}; use std::{convert::TryFrom, fmt::Formatter, ops::RangeInclusive}; #[derive(PartialEq, Eq, Clone, Default, Serialize, Deserialize)] pub struct Revision { pub base_rev_id: i64, pub rev_id: i64, pub bytes: Vec, pub md5: String, pub object_id: String, } impl std::convert::From> for Revision { fn from(data: Vec) -> Self { let bytes = Bytes::from(data); Revision::try_from(bytes).unwrap() } } impl std::convert::TryFrom for Revision { type Error = serde_json::Error; fn try_from(bytes: Bytes) -> Result { serde_json::from_slice(&bytes) } } impl Revision { pub fn new>( object_id: &str, base_rev_id: i64, rev_id: i64, bytes: Bytes, md5: T, ) -> Revision { let object_id = object_id.to_owned(); let bytes = bytes.to_vec(); let base_rev_id = base_rev_id; let rev_id = rev_id; if base_rev_id != 0 { debug_assert!(base_rev_id <= rev_id); } Self { base_rev_id, rev_id, bytes, md5: md5.into(), object_id, } } pub fn is_empty(&self) -> bool { self.base_rev_id == self.rev_id } pub fn pair_rev_id(&self) -> (i64, i64) { (self.base_rev_id, self.rev_id) } pub fn is_initial(&self) -> bool { self.rev_id == 0 } pub fn initial_revision(object_id: &str, bytes: Bytes) -> Self { let md5 = format!("{:x}", md5::compute(&bytes)); Self::new(object_id, 0, 0, bytes, md5) } pub fn to_bytes(&self) -> Bytes { let bytes = serde_json::to_vec(self).unwrap(); Bytes::from(bytes) } } impl std::fmt::Debug for Revision { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { f.write_fmt(format_args!("object_id {}, ", self.object_id))?; f.write_fmt(format_args!("base_rev_id {}, ", self.base_rev_id))?; f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?; Ok(()) } } #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct RevisionRange { pub start: i64, pub end: i64, } impl std::fmt::Display for RevisionRange { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("[{},{}]", self.start, self.end)) } } impl RevisionRange { pub fn len(&self) -> u64 { debug_assert!(self.end >= self.start); if self.end >= self.start { (self.end - self.start + 1) as u64 } else { 0 } } pub fn is_empty(&self) -> bool { self.end == self.start } pub fn iter(&self) -> RangeInclusive { // debug_assert!(self.start != self.end); RangeInclusive::new(self.start, self.end) } pub fn to_rev_ids(&self) -> Vec { self.iter().collect::>() } }