stam/
cbor.rs

1/*
2    STAM Library (Stand-off Text Annotation Model)
3        by Maarten van Gompel <proycon@anaproy.nl>
4        Digital Infrastucture, KNAW Humanities Cluster
5
6        Licensed under the GNU General Public License v3
7
8        https://github.com/annotation/stam-rust
9*/
10
11//! This module contain some helper functions for serialisation/deserialisation to/from CBOR (the binary representation).
12
13use chrono::{DateTime, FixedOffset};
14use minicbor::{decode::ArrayIterWithCtx, CborLen, Encode};
15use smallvec::SmallVec;
16use std::sync::{Arc, RwLock};
17
18use crate::config::SerializeMode;
19use crate::textselection::TextSelectionHandle;
20
21// we need these three functions and the CborLen implementation because there is no out of the box support for SmallVec
22// these implementations are not very generic (constrainted to a very particular SmallVec usage), but that's okay as
23// long as we don't need to (de)serialize others.
24
25pub(crate) fn cbor_decode_positionitem_smallvec<'b, Ctx>(
26    d: &mut minicbor::decode::Decoder<'b>,
27    ctx: &mut Ctx,
28) -> Result<SmallVec<[(usize, TextSelectionHandle); 1]>, minicbor::decode::Error> {
29    let iter: ArrayIterWithCtx<Ctx, (usize, TextSelectionHandle)> = d.array_iter_with(ctx)?;
30    let mut v = SmallVec::new();
31    for x in iter {
32        v.push(x?)
33    }
34    Ok(v)
35}
36
37pub(crate) fn cbor_encode_positionitem_smallvec<Ctx, W: minicbor::encode::Write>(
38    v: &SmallVec<[(usize, TextSelectionHandle); 1]>,
39    e: &mut minicbor::encode::Encoder<W>,
40    ctx: &mut Ctx,
41) -> Result<(), minicbor::encode::Error<W::Error>> {
42    e.array(v.len() as u64)?;
43    for x in v {
44        x.encode(e, ctx)?
45    }
46    Ok(())
47}
48
49//copied from u32 implementation in minicbor (make sure to update this if TextSelectionHandle ever adopts a bigger/smaller type)
50impl<C> CborLen<C> for TextSelectionHandle {
51    fn cbor_len(&self, _: &mut C) -> usize {
52        match self.0 {
53            0..=0x17 => 1,
54            0x18..=0xff => 2,
55            0x100..=0xffff => 3,
56            _ => 5,
57        }
58    }
59}
60
61/*
62pub(crate) fn cbor_len_positionitem_smallvec<Ctx, W: minicbor::encode::Write>(
63    v: &SmallVec<[(usize, TextSelectionHandle); 1]>,
64    ctx: &mut Ctx,
65) -> usize {
66    let n = v.len();
67    n.cbor_len(ctx) + v.iter().map(|x| x.cbor_len(ctx)).sum::<usize>()
68}
69*/
70
71pub(crate) fn cbor_decode_serialize_mode<'b, Ctx>(
72    _d: &mut minicbor::decode::Decoder<'b>,
73    _ctx: &mut Ctx,
74) -> Result<Arc<RwLock<SerializeMode>>, minicbor::decode::Error> {
75    Ok(Arc::new(RwLock::new(SerializeMode::NoInclude)))
76}
77
78pub(crate) fn cbor_encode_serialize_mode<Ctx, W: minicbor::encode::Write>(
79    _v: &Arc<RwLock<SerializeMode>>,
80    _e: &mut minicbor::encode::Encoder<W>,
81    _ctx: &mut Ctx,
82) -> Result<(), minicbor::encode::Error<W::Error>> {
83    Ok(())
84}
85
86pub(crate) fn cbor_encode_datetime<Ctx, W: minicbor::encode::Write>(
87    v: &DateTime<FixedOffset>,
88    e: &mut minicbor::encode::Encoder<W>,
89    ctx: &mut Ctx,
90) -> Result<(), minicbor::encode::Error<W::Error>> {
91    v.to_rfc3339().encode(e, ctx)
92}
93
94pub(crate) fn cbor_decode_datetime<'b, Ctx>(
95    d: &mut minicbor::decode::Decoder<'b>,
96    _ctx: &mut Ctx,
97) -> Result<DateTime<FixedOffset>, minicbor::decode::Error> {
98    let s: String = d.decode()?;
99    DateTime::parse_from_rfc3339(&s).map_err(|err| minicbor::decode::Error::custom(err))
100}