prosa_utils/msg/
tvf.rs

1//!
2//! <svg width="40" height="40">
3#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/doc_assets/tvf.svg"))]
4//! </svg>
5//!
6//! Module to define TVF[^tvfnote] message data strcture
7//!
8//! [^tvfnote]: **T**ag **V**alue **F**ormat
9
10use bytes::Bytes;
11use chrono::{NaiveDate, NaiveDateTime};
12use std::borrow::Cow;
13use std::fmt::Debug;
14use thiserror::Error;
15
16/// Error define for TVF object
17/// Use by several method (serialize/unserialize/getter/setter)
18#[derive(Debug, Eq, Error, PartialOrd, PartialEq)]
19pub enum TvfError {
20    /// Error that indicate the field is not found in the TVF. Missing key
21    #[error("The key `{0}` is not present in the Tvf")]
22    FieldNotFound(usize),
23    /// Error that indicate the field can't be retrieve because the type is not compatible
24    #[error("The type can't be retrieve from the Tvf")]
25    TypeMismatch,
26    /// Error that indicate the field can't be converted due to an other error
27    #[error("The field can't be Converted. {0}")]
28    ConvertionError(String),
29    /// Error encountered during serialization or deserializarion process
30    #[error("Serialization error: {0}")]
31    SerializationError(String),
32}
33
34/// Trait that define a TVF[^tvfnote]
35/// Use to define a key/value object that structure a data
36///
37/// [^tvfnote]: **T**ag **V**alue **F**ormat
38///
39/// ```
40/// use prosa_utils::msg::tvf::Tvf;
41///
42/// fn sample<T: Tvf>(mut tvf: T) {
43///     tvf.put_string(1, "toto");
44///     assert!(tvf.contains(1));
45///     assert_eq!("toto", tvf.get_string(1).unwrap().as_str());
46///
47///     tvf.remove(1);
48///     assert!(!tvf.contains(1));
49/// }
50pub trait Tvf {
51    /// Method to know if the TVF is empty
52    fn is_empty(&self) -> bool;
53    /// Method to know the number of field in the TVF (not recursive)
54    fn len(&self) -> usize;
55
56    /// Method to know is the TVF contain a field the id key
57    fn contains(&self, id: usize) -> bool;
58
59    /// Method to remove a TVF field
60    fn remove(&mut self, id: usize);
61
62    /// Method to convert the TVF into vector ok keys
63    fn into_keys(self) -> Vec<usize>;
64
65    /// Get all the keys for this TVF
66    fn keys(&self) -> Vec<usize>;
67
68    /// Get a sub buffer from a TVF
69    fn get_buffer(&self, id: usize) -> Result<Cow<'_, Self>, TvfError>
70    where
71        Self: Tvf + Clone;
72    /// Get an unsigned value from a TVF
73    fn get_unsigned(&self, id: usize) -> Result<u64, TvfError>;
74    /// Get a signed value from a TVF
75    fn get_signed(&self, id: usize) -> Result<i64, TvfError>;
76    /// Get a byte value from a TVF
77    fn get_byte(&self, id: usize) -> Result<u8, TvfError>;
78    /// Get a float value from a TVF
79    fn get_float(&self, id: usize) -> Result<f64, TvfError>;
80    /// Get a string value from a TVF
81    fn get_string(&self, id: usize) -> Result<Cow<'_, String>, TvfError>;
82    /// Get a buffer of bytes from a TVF
83    fn get_bytes(&self, id: usize) -> Result<Cow<'_, Bytes>, TvfError>;
84    /// Get a date field from a TVF
85    fn get_date(&self, id: usize) -> Result<NaiveDate, TvfError>;
86    /// Get a datetime field from  a TVF.  
87    /// The timestamp is considered to be UTC.
88    fn get_datetime(&self, id: usize) -> Result<NaiveDateTime, TvfError>;
89
90    /// Put a buffer as sub field into a TVF
91    fn put_buffer(&mut self, id: usize, buffer: Self)
92    where
93        Self: Tvf;
94    /// Put an unsigned value to a TVF
95    fn put_unsigned(&mut self, id: usize, unsigned: u64);
96    /// Put a signed value to a TVF
97    fn put_signed(&mut self, id: usize, signed: i64);
98    /// Put a byte into a TVF
99    fn put_byte(&mut self, id: usize, byte: u8);
100    /// Put a float value to a TVF
101    fn put_float(&mut self, id: usize, float: f64);
102    /// Put a string value to a TVF
103    fn put_string<T: Into<String>>(&mut self, id: usize, string: T);
104    /// Put some bytes into a TVF
105    fn put_bytes(&mut self, id: usize, buffer: Bytes);
106    /// Put a date into a TVF
107    fn put_date(&mut self, id: usize, date: NaiveDate);
108    /// Put a datetime into a TVF.  
109    /// The timestamp is considered to be UTC.
110    fn put_datetime(&mut self, id: usize, datetime: NaiveDateTime);
111}
112
113/// Trait to define a TVF[^tvfnote] filter.
114/// Useful to filter sensitive data.
115///
116/// [^tvfnote]: **T**ag **V**alue **F**ormat
117///
118/// ```
119/// use prosa_utils::msg::tvf::{Tvf, TvfFilter};
120/// use prosa_utils::msg::simple_string_tvf::SimpleStringTvf;
121///
122/// enum TvfTestFilter {}
123///
124/// impl TvfFilter for TvfTestFilter {
125///     fn filter<T: Tvf>(mut buf: T) -> T {
126///         buf = <TvfTestFilter as TvfFilter>::mask_tvf_str_field(buf, 1, "*");
127///         <TvfTestFilter as TvfFilter>::mask_tvf_str_field(buf, 2, "0")
128///     }
129/// }
130///
131/// let mut tvf: SimpleStringTvf = Default::default();
132/// tvf.put_string(1, "plain");
133/// tvf.put_string(2, "1234");
134/// tvf.put_string(3, "clear");
135///
136/// let tvf_filtered = TvfTestFilter::filter(tvf);
137/// assert_eq!(Ok(std::borrow::Cow::Owned(String::from("*****"))), tvf_filtered.get_string(1));
138/// assert_eq!(Ok(std::borrow::Cow::Owned(String::from("0000"))), tvf_filtered.get_string(2));
139/// assert_eq!(Ok(std::borrow::Cow::Owned(String::from("clear"))), tvf_filtered.get_string(3));
140/// ```
141pub trait TvfFilter {
142    /// Method to filter the TVF buffer
143    fn filter<T: Tvf>(tvf: T) -> T;
144
145    /// Function to mask a TVF string field
146    ///
147    /// Replace in the TVF buf the string value at the id with a fill character
148    fn mask_tvf_str_field<T: Tvf>(mut tvf: T, id: usize, fill_char: &str) -> T {
149        if tvf.contains(id) {
150            if let Ok(str) = tvf.get_string(id) {
151                tvf.put_string(id, fill_char.repeat(str.len()));
152            } else {
153                // If the field can't be mask, just remove it to prevent any data leak
154                tvf.remove(id);
155            }
156        }
157
158        tvf
159    }
160}