use crate::*;
#[derive(Clone, Debug)]
pub struct ObjectSigns {
desc_signs: Option<Vec<Signature>>,
body_signs: Option<Vec<Signature>>,
}
pub struct ObjectSignsHelper;
impl ObjectSignsHelper {
pub fn set_sign(list: &mut Option<Vec<Signature>>, sign: Signature) {
if list.is_none() {
*list = Some(vec![]);
}
let list = list.as_mut().unwrap();
list.clear();
list.push(sign);
}
pub fn push_sign(list: &mut Option<Vec<Signature>>, sign: Signature) {
if list.is_none() {
*list = Some(vec![]);
}
let list = list.as_mut().unwrap();
if let Some(cur) = list.iter_mut().find(|v| v.compare_source(&sign)) {
if sign.sign_time() > cur.sign_time() {
info!("desc sign with same source will update! new={:?}, cur={:?}", sign, cur);
*cur = sign;
} else{
warn!("desc sign with same source already exists! sign={:?}", sign);
}
} else {
list.push(sign);
}
}
pub fn latest_sign_time(list: &Option<Vec<Signature>>) -> u64 {
let mut ret = 0;
if let Some(signs) = list.as_ref() {
for sign in signs {
if ret < sign.sign_time() {
ret = sign.sign_time();
}
}
}
ret
}
pub fn merge(dest: &mut Option<Vec<Signature>>, src: &Option<Vec<Signature>>) -> usize {
match src {
Some(src) => {
match dest {
Some(dest) => {
let mut ret = 0;
for src_item in src {
match dest.iter_mut().find(|s| s.compare_source(src_item)) {
Some(dest_item) => {
if src_item.sign_time() > dest_item.sign_time() {
*dest_item = src_item.clone();
}
}
None => {
dest.push(src_item.clone());
ret += 1;
}
}
}
ret
}
None => {
let mut ret = 0;
let mut dest_list: Vec<Signature> = Vec::new();
for src_item in src {
match dest_list.iter_mut().find(|s| s.compare_source(src_item)) {
Some(dest_item) => {
if src_item.sign_time() > dest_item.sign_time() {
*dest_item = src_item.clone();
}
}
None => {
dest_list.push(src_item.clone());
ret += 1;
}
}
}
if !dest_list.is_empty() {
*dest = Some(dest_list);
}
ret
}
}
}
None => 0,
}
}
}
#[derive(Clone)]
pub struct ObjectSignsBuilder {
desc_signs: Option<Vec<Signature>>,
body_signs: Option<Vec<Signature>>,
}
impl ObjectSignsBuilder {
pub fn new() -> Self {
Self {
desc_signs: None,
body_signs: None,
}
}
pub fn set_desc_sign(mut self, sign: Signature) -> Self {
ObjectSignsHelper::set_sign(&mut self.desc_signs, sign);
self
}
pub fn set_body_sign(mut self, sign: Signature) -> Self {
ObjectSignsHelper::set_sign(&mut self.body_signs, sign);
self
}
pub fn push_desc_sign(mut self, sign: Signature) -> Self {
ObjectSignsHelper::push_sign(&mut self.desc_signs, sign);
self
}
pub fn push_body_sign(mut self, sign: Signature) -> Self {
ObjectSignsHelper::push_sign(&mut self.body_signs, sign);
self
}
pub fn build(self) -> ObjectSigns {
ObjectSigns {
desc_signs: self.desc_signs,
body_signs: self.body_signs,
}
}
}
impl ObjectSigns {
pub fn new() -> ObjectSignsBuilder {
ObjectSignsBuilder::new()
}
pub fn is_desc_signs_empty(&self) -> bool {
if let Some(signs) = &self.desc_signs {
signs.len() == 0
} else {
true
}
}
pub fn is_body_signs_empty(&self) -> bool {
if let Some(signs) = &self.body_signs {
signs.len() == 0
} else {
true
}
}
pub fn is_empty(&self) -> bool {
self.is_desc_signs_empty() && self.is_body_signs_empty()
}
pub fn desc_signs(&self) -> Option<&Vec<Signature>> {
self.desc_signs.as_ref()
}
pub fn body_signs(&self) -> Option<&Vec<Signature>> {
self.body_signs.as_ref()
}
pub fn set_desc_sign(&mut self, sign: Signature) {
ObjectSignsHelper::set_sign(&mut self.desc_signs, sign)
}
pub fn set_body_sign(&mut self, sign: Signature) {
ObjectSignsHelper::set_sign(&mut self.body_signs, sign)
}
pub fn push_desc_sign(&mut self, sign: Signature) {
ObjectSignsHelper::push_sign(&mut self.desc_signs, sign)
}
pub fn push_body_sign(&mut self, sign: Signature) {
ObjectSignsHelper::push_sign(&mut self.body_signs, sign)
}
pub fn clear_desc_signs(&mut self) {
self.desc_signs.take();
}
pub fn clear_body_signs(&mut self) {
self.body_signs.take();
}
pub fn latest_body_sign_time(&self) -> u64 {
ObjectSignsHelper::latest_sign_time(&self.body_signs)
}
pub fn latest_desc_sign_time(&self) -> u64 {
ObjectSignsHelper::latest_sign_time(&self.desc_signs)
}
pub fn latest_sign_time(&self) -> u64 {
std::cmp::max(self.latest_desc_sign_time(), self.latest_body_sign_time())
}
pub fn merge(&mut self, other: &ObjectSigns) -> usize {
ObjectSignsHelper::merge(&mut self.desc_signs, &other.desc_signs)
+ ObjectSignsHelper::merge(&mut self.body_signs, &other.body_signs)
}
pub fn merge_ex(&mut self, other: &ObjectSigns, desc: bool, body: bool) -> usize {
let mut ret = 0;
if desc {
ret += ObjectSignsHelper::merge(&mut self.desc_signs, &other.desc_signs);
}
if body {
ret += ObjectSignsHelper::merge(&mut self.body_signs, &other.body_signs);
}
ret
}
}
impl Default for ObjectSigns {
fn default() -> Self {
Self {
desc_signs: None,
body_signs: None,
}
}
}
impl RawEncodeWithContext<NamedObjectContext> for ObjectSigns {
fn raw_measure_with_context(
&self,
ctx: &mut NamedObjectContext,
purpose: &Option<RawEncodePurpose>,
) -> BuckyResult<usize> {
let mut size = 0;
if self.desc_signs.is_some() {
ctx.with_desc_signs();
assert!(ctx.has_desc_signs());
size = size
+ self
.desc_signs
.as_ref()
.unwrap()
.raw_measure(purpose)
.map_err(|e| {
log::error!(
"ObjectSigns::raw_measure_with_context/desc_signs error:{}",
e
);
e
})?;
}
if self.body_signs.is_some() {
ctx.with_body_signs();
assert!(ctx.has_body_signs());
size = size
+ self
.body_signs
.as_ref()
.unwrap()
.raw_measure(purpose)
.map_err(|e| {
log::error!(
"ObjectSigns::raw_measure_with_context/body_signs error:{}",
e
);
e
})?;
}
Ok(size)
}
fn raw_encode_with_context<'a>(
&self,
buf: &'a mut [u8],
ctx: &mut NamedObjectContext,
purpose: &Option<RawEncodePurpose>,
) -> BuckyResult<&'a mut [u8]> {
let buf = if self.desc_signs.is_some() {
assert!(ctx.has_desc_signs());
self.desc_signs
.as_ref()
.unwrap()
.raw_encode(buf, purpose)
.map_err(|e| {
log::error!(
"ObjectSigns::raw_encode_with_context/desc_signs error:{}",
e
);
e
})?
} else {
buf
};
let buf = if self.body_signs.is_some() {
assert!(ctx.has_body_signs());
self.body_signs
.as_ref()
.unwrap()
.raw_encode(buf, purpose)
.map_err(|e| {
log::error!(
"ObjectSigns::raw_encode_with_context/body_signs error:{}",
e
);
e
})?
} else {
buf
};
Ok(buf)
}
}
impl<'de> RawDecodeWithContext<'de, &NamedObjectContext> for ObjectSigns {
fn raw_decode_with_context(
buf: &'de [u8],
ctx: &NamedObjectContext,
) -> BuckyResult<(Self, &'de [u8])> {
let (desc_signs, buf) = if ctx.has_desc_signs() {
let (desc_signs, buf) = Vec::<Signature>::raw_decode(buf).map_err(|e| {
log::error!(
"ObjectSigns::raw_decode_with_context/desc_signs error:{}",
e
);
e
})?;
(Some(desc_signs), buf)
} else {
(None, buf)
};
let (body_signs, buf) = if ctx.has_body_signs() {
let (body_signs, buf) = Vec::<Signature>::raw_decode(buf).map_err(|e| {
log::error!(
"ObjectSigns::raw_decode_with_context/body_signs error:{}",
e
);
e
})?;
(Some(body_signs), buf)
} else {
(None, buf)
};
Ok((
Self {
desc_signs,
body_signs,
},
buf,
))
}
}