gui_server_api/navigation/
qrscanner.rs1use app_manifest::QrPriority;
7use server::rkyv_with::WithAppId;
8use xous::AppId;
9
10#[derive(Debug, Clone, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
23pub struct ScanQrMatchedRule {
24 pub rule_id: String,
25 pub priority: QrPriority,
26 pub sub_rule_id: String,
29}
30
31#[derive(Debug, Clone, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
35pub struct ScanQrMatchingApp {
36 #[rkyv(with = WithAppId)]
37 pub id: AppId,
38 pub matched_rules: Vec<ScanQrMatchedRule>,
39}
40
41#[derive(Debug, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
42pub struct ScanQrOptions {
43 pub header_title: String,
44 pub header_left_icon: String,
45 pub header_left_text: String,
46 pub header_right_icon: String,
47 pub header_right_text: String,
48 pub message: String,
49 pub button_icon: String,
50 pub button_text: String,
51 pub request_matching_apps: bool,
52}
53
54impl Default for ScanQrOptions {
55 fn default() -> Self {
56 Self {
57 header_title: String::new(),
58 header_left_icon: String::from("chevron-left"),
59 header_left_text: String::new(),
60 header_right_icon: String::new(),
61 header_right_text: String::new(),
62 message: String::new(),
63 button_icon: String::new(),
64 button_text: String::new(),
65 request_matching_apps: false,
66 }
67 }
68}
69
70impl ScanQrOptions {
71 pub fn new() -> Self {
72 Self {
73 header_title: String::new(),
74 header_left_icon: String::new(),
75 header_left_text: String::new(),
76 header_right_icon: String::new(),
77 header_right_text: String::new(),
78 message: String::new(),
79 button_icon: String::new(),
80 button_text: String::new(),
81 request_matching_apps: false,
82 }
83 }
84
85 pub fn from_slice(data: &[u8]) -> Option<Self> {
86 let Ok(archived) = rkyv::access::<ArchivedScanQrOptions, rkyv::rancor::Error>(data) else {
87 return None;
88 };
89 rkyv::deserialize::<Self, rkyv::rancor::Error>(archived).ok()
90 }
91
92 pub fn serialize(&self) -> Vec<u8> { rkyv::to_bytes::<rkyv::rancor::Error>(self).unwrap().to_vec() }
93}
94
95#[derive(Debug, Clone, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
96pub struct MatchedQrResult {
97 pub scan_result: ScanQrResult,
98 pub matched_rules: Vec<ScanQrMatchedRule>,
99}
100
101impl MatchedQrResult {
102 pub fn from_slice(data: &[u8]) -> Option<Self> {
103 let Ok(archived) = rkyv::access::<ArchivedMatchedQrResult, rkyv::rancor::Error>(data) else {
104 return None;
105 };
106 rkyv::deserialize::<Self, rkyv::rancor::Error>(archived).ok()
107 }
108
109 pub fn serialize(&self) -> Vec<u8> { rkyv::to_bytes::<rkyv::rancor::Error>(self).unwrap().to_vec() }
110}
111
112#[derive(Debug, Clone, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
113pub enum ScanQrResult {
114 Qr { data: Vec<u8>, matching_apps: Option<Vec<ScanQrMatchingApp>> },
115 Ur2 { ur_type: String, data: Vec<u8>, matching_apps: Option<Vec<ScanQrMatchingApp>> },
116 LeftClicked,
117 RightClicked,
118 ButtonClicked,
119}
120
121impl ScanQrResult {
122 pub fn new_qr(data: &[u8]) -> Self { Self::Qr { data: data.to_vec(), matching_apps: None } }
123
124 pub fn new_ur2(ur_type: String, data: &[u8]) -> Self {
125 Self::Ur2 { ur_type, data: data.to_vec(), matching_apps: None }
126 }
127
128 pub fn with_matching_apps(self, matching_apps: Vec<ScanQrMatchingApp>) -> Self {
129 match self {
130 Self::Qr { data, .. } => Self::Qr { data, matching_apps: Some(matching_apps) },
131 Self::Ur2 { ur_type, data, .. } => {
132 Self::Ur2 { ur_type, data, matching_apps: Some(matching_apps) }
133 }
134 other => other,
135 }
136 }
137
138 pub fn new_cancelled() -> Self { Self::LeftClicked }
139
140 pub fn from_slice(data: &[u8]) -> Option<Self> {
141 let Ok(archived) = rkyv::access::<ArchivedScanQrResult, rkyv::rancor::Error>(data) else {
142 return None;
143 };
144 rkyv::deserialize::<Self, rkyv::rancor::Error>(archived).ok()
145 }
146
147 pub fn serialize(&self) -> Vec<u8> { rkyv::to_bytes::<rkyv::rancor::Error>(self).unwrap().to_vec() }
148}