bc_ur/
multipart_decoder.rs

1use dcbor::prelude::*;
2
3use crate::{Error, Result, UR, URType};
4
5pub struct MultipartDecoder {
6    ur_type: Option<URType>,
7    decoder: ur::Decoder,
8}
9
10impl MultipartDecoder {
11    pub fn new() -> Self {
12        Self { ur_type: None, decoder: ur::Decoder::default() }
13    }
14}
15
16impl Default for MultipartDecoder {
17    fn default() -> Self { Self::new() }
18}
19
20impl MultipartDecoder {
21    pub fn receive(&mut self, value: &str) -> Result<()> {
22        let decoded_type = Self::decode_type(value)?;
23        if let Some(ur_type) = &self.ur_type {
24            if ur_type != &decoded_type {
25                return Err(Error::UnexpectedType(
26                    ur_type.string().to_string(),
27                    decoded_type.string().to_string(),
28                ));
29            }
30        } else {
31            self.ur_type = Some(decoded_type);
32        }
33        Ok(self.decoder.receive(value)?)
34    }
35
36    pub fn is_complete(&self) -> bool { self.decoder.complete() }
37
38    pub fn message(&self) -> Result<Option<UR>> {
39        let message_data = self.decoder.message()?;
40        if let Some(data) = message_data {
41            let cbor = CBOR::try_from_data(data)?;
42            let ur_type = self.ur_type.as_ref().unwrap();
43            let ur_type_string = ur_type.string();
44            let ur = UR::new(ur_type_string, cbor)?;
45            Ok(Some(ur))
46        } else {
47            Ok(None)
48        }
49    }
50
51    fn decode_type(ur_string: &str) -> Result<URType> {
52        let without_scheme =
53            ur_string.strip_prefix("ur:").ok_or(Error::InvalidScheme)?;
54        let first_component =
55            without_scheme.split('/').next().ok_or(Error::InvalidType)?;
56        URType::new(first_component)
57    }
58}