foundation_urtypes/cbor/
timestamp.rs

1// SPDX-FileCopyrightText: © 2023 Foundation Devices, Inc. <hello@foundationdevices.com>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4use minicbor::{
5    data::{IanaTag, Int, Tag, Type},
6    decode::Error,
7    encode::Write,
8    Decode, Decoder, Encode, Encoder,
9};
10
11/// Epoch-Based Date/Time.
12///
13/// See [RFC 8948](https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.2).
14#[derive(Debug)]
15pub enum Timestamp {
16    /// Integer timestamp.
17    Int(Int),
18    /// Floating point timestamp.
19    Float(f64),
20}
21
22#[rustfmt::skip]
23impl<'b, C> Decode<'b, C> for Timestamp {
24    fn decode(d: &mut Decoder<'b>, _ctx: &mut C) -> Result<Self, Error> {
25        if d.tag()? != Tag::from(IanaTag::Timestamp) {
26            return Err(Error::message("invalid timestamp tag"));
27        }
28
29        #[rustfmt::skip]
30        let timestamp = match d.datatype()? {
31            Type::U8 | Type::U16 | Type::U32 | Type::U64 |
32            Type::I8 | Type::I16 | Type::I32 | Type::I64 |
33            Type::Int => Timestamp::Int(d.int()?),
34            Type::F16 | Type::F32 | Type::F64 => Timestamp::Float(d.f64()?),
35            _ => return Err(Error::message("invalid timestamp")),
36        };
37
38        Ok(timestamp)
39    }
40}
41
42impl<C> Encode<C> for Timestamp {
43    fn encode<W: Write>(
44        &self,
45        e: &mut Encoder<W>,
46        _ctx: &mut C,
47    ) -> Result<(), minicbor::encode::Error<W::Error>> {
48        e.tag(IanaTag::Timestamp)?;
49
50        match self {
51            Timestamp::Int(x) => e.int(*x)?,
52            Timestamp::Float(x) => e.f64(*x)?,
53        };
54
55        Ok(())
56    }
57}