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