jsonprooftoken/jpt/
payloads.rs

1// Copyright 2023 Fondazione LINKS
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7//     http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::errors::CustomError;
16use serde::{Deserialize, Serialize};
17use serde_json::Value;
18
19///TODO: Not clear what to do with this information
20/// (https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-proof-token#name-payloads)
21#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
22pub enum PayloadType {
23    Disclosed,
24    Undisclosed,
25    ProofMethods,
26}
27
28#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
29pub struct Payloads(pub Vec<(Value, PayloadType)>);
30
31impl Payloads {
32    pub fn to_bytes(&self) -> Result<Vec<Vec<u8>>, CustomError> {
33        let p: Result<Vec<Vec<u8>>, CustomError> = self
34            .0
35            .iter()
36            .map(|v| match serde_json::to_vec(&v.0) {
37                Ok(vec) => Ok(vec),
38                Err(_) => Err(CustomError::SerializationError),
39            })
40            .collect();
41        p
42    }
43    pub fn new_from_values(values: Vec<Value>) -> Self {
44        let mut payloads = Vec::new();
45        for value in values {
46            payloads.push((value, PayloadType::Disclosed));
47        }
48        Payloads(payloads)
49    }
50
51    pub fn get_values(&self) -> Vec<Value> {
52        self.0.clone().into_iter().map(|v| v.0).collect()
53    }
54
55    pub fn get_undisclosed_indexes(&self) -> Vec<usize> {
56        let mut undisclosed_indexes = Vec::new();
57
58        for (index, (_, payload_type)) in self.0.iter().enumerate() {
59            if let PayloadType::Undisclosed = payload_type {
60                undisclosed_indexes.push(index);
61            }
62        }
63
64        undisclosed_indexes
65    }
66
67    pub fn get_disclosed_indexes(&self) -> Vec<usize> {
68        let mut disclosed_indexes = Vec::new();
69
70        for (index, (_, payload_type)) in self.0.iter().enumerate() {
71            if let PayloadType::Disclosed = payload_type {
72                disclosed_indexes.push(index);
73            }
74        }
75
76        disclosed_indexes
77    }
78
79    pub fn get_undisclosed_payloads(&self) -> Vec<Value> {
80        let undisclosed_indexes = self.get_undisclosed_indexes();
81
82        let undisclosed_payloads: Vec<Value> = self
83            .0
84            .iter()
85            .enumerate()
86            .filter(|(index, _)| undisclosed_indexes.contains(index))
87            .map(|(_, payload)| payload.0.clone())
88            .collect();
89
90        undisclosed_payloads
91    }
92
93    pub fn get_disclosed_payloads(&self) -> Payloads {
94        let disclosed_indexes = self.get_disclosed_indexes();
95
96        let disclosed_payloads: Vec<(Value, PayloadType)> = self
97            .0
98            .iter()
99            .enumerate()
100            .filter(|(index, _)| disclosed_indexes.contains(index))
101            .map(|(_, payload)| payload.clone())
102            .collect();
103
104        Payloads(disclosed_payloads)
105    }
106
107    pub fn set_undisclosed(&mut self, index: usize) {
108        self.0.iter_mut().enumerate().for_each(|(i, v)| {
109            if index == i {
110                v.1 = PayloadType::Undisclosed;
111            }
112        });
113    }
114
115    pub fn replace_payload_at_index(
116        &mut self,
117        index: usize,
118        value: Value,
119    ) -> Result<Value, CustomError> {
120        let dest = self.0.get_mut(index).ok_or(CustomError::IndexOutOfBounds)?;
121        let old = std::mem::replace(dest, (value, PayloadType::Disclosed));
122        Ok(old.0)
123    }
124}