1use std::{
2 convert::TryInto,
3 time::{SystemTime, UNIX_EPOCH},
4};
5
6use uuid::Uuid;
7
8use crate::{
9 datatypes::{BaseMessage, ExtendedMessage, FromTo},
10 db::{read_db, search_db_keys, write_db},
11};
12
13pub fn vec_to_array<T, const N: usize>(v: Vec<T>) -> Result<[T; N], Box<dyn std::error::Error>> {
21 v.try_into()
22 .map_err(|_e| Box::from("could not format vec to array"))
23}
24
25pub fn get_from_to_from_message(
33 message: &BaseMessage,
34) -> Result<FromTo, Box<dyn std::error::Error>> {
35 let from_did = message.from.as_ref().ok_or("from is required")?;
36
37 let to_vec = message.to.as_ref().ok_or("to is required")?;
38 if to_vec.is_empty() {
39 return Err(Box::from(
40 "DID exchange requires at least one did in the to field.",
41 ));
42 }
43 let to_did = &to_vec[0];
44
45 Ok(FromTo {
46 from: from_did.to_owned(),
47 to: String::from(to_did),
48 })
49}
50
51pub fn write_raw_message_to_db(message: &str) -> Result<(), Box<dyn std::error::Error>> {
56 let parsed_raw_message: ExtendedMessage = serde_json::from_str(message)?;
57
58 write_db(
59 &format!(
60 "message_{}_{}",
61 parsed_raw_message
62 .thid
63 .unwrap_or(parsed_raw_message.id.clone().ok_or("id is missing")?),
64 parsed_raw_message.id.ok_or("id is missing")?
65 ),
66 message,
67 )
68}
69
70pub fn read_raw_message_from_db(
75 prefix: &str,
76 thid: &str,
77 msg_id: &str,
78) -> Result<Vec<String>, Box<dyn std::error::Error>> {
79 let mut key = format!("{}_{}_{}", prefix, thid, msg_id);
80
81 if msg_id == "*" {
82 key = format!("{}_{}", prefix, thid);
83 search_db_keys(&key)
84 } else {
85 let value = read_db(&key)?;
86 Ok(vec![value])
87 }
88}
89
90pub fn fill_message_id_and_timestamps(message: &str) -> Result<String, Box<dyn std::error::Error>> {
98 let mut parsed_message: ExtendedMessage = serde_json::from_str(message)?;
99
100 if parsed_message.id.is_none() {
101 parsed_message.id = Some(Uuid::to_string(&Uuid::new_v4()));
102 }
103
104 if parsed_message.created_time.is_none() {
105 let start = SystemTime::now();
106 let since_the_epoch = start.duration_since(UNIX_EPOCH)?;
107 parsed_message.created_time = Some(since_the_epoch.as_secs());
108 }
109
110 Ok(serde_json::to_string(&parsed_message)?)
111}
112
113pub(crate) mod hex_option {
114 use serde::{Deserialize, Deserializer, Serialize, Serializer};
115
116 pub fn serialize<S: Serializer>(v: &Option<[u8; 32]>, s: S) -> Result<S::Ok, S::Error> {
117 let hex_string = v.as_ref().map(hex::encode);
118 <Option<String>>::serialize(&hex_string, s)
119 }
120
121 pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<[u8; 32]>, D::Error> {
122 let hex_string = <Option<String>>::deserialize(d)?;
123 match hex_string {
124 Some(v) => {
125 let hex_decoded = hex::decode(v).map_err(serde::de::Error::custom)?;
126 let mut arr: [u8; 32] = Default::default();
127 arr.copy_from_slice(&hex_decoded[..32]);
128 Ok(Some(arr))
129 }
130 None => Ok(None),
131 }
132 }
133}