1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2023 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker //! Library for custom implementations of serialize/deserialize.
6*bb4ee6a4SAndroid Build Coastguard Worker
7*bb4ee6a4SAndroid Build Coastguard Worker use std::result::Result;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
9*bb4ee6a4SAndroid Build Coastguard Worker
10*bb4ee6a4SAndroid Build Coastguard Worker use serde::de::Error;
11*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
12*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserializer;
13*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
14*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serializer;
15*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex;
16*bb4ee6a4SAndroid Build Coastguard Worker
17*bb4ee6a4SAndroid Build Coastguard Worker /// Serialize data `T` inside an `Arc<Mutex<T>>`. `T` must be serializable.
18*bb4ee6a4SAndroid Build Coastguard Worker ///
19*bb4ee6a4SAndroid Build Coastguard Worker /// NOTE: This does not validate already serialized Mutexes and data. If multiple structs contain a
20*bb4ee6a4SAndroid Build Coastguard Worker /// clone of the Arc, and they are all being serialized, this will result in the same data being
21*bb4ee6a4SAndroid Build Coastguard Worker /// serialized, once per clone.
serialize_arc_mutex<S: Serializer, T: Serialize + ?Sized>( item: &Arc<Mutex<T>>, serializer: S, ) -> Result<S::Ok, S::Error>22*bb4ee6a4SAndroid Build Coastguard Worker pub fn serialize_arc_mutex<S: Serializer, T: Serialize + ?Sized>(
23*bb4ee6a4SAndroid Build Coastguard Worker item: &Arc<Mutex<T>>,
24*bb4ee6a4SAndroid Build Coastguard Worker serializer: S,
25*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<S::Ok, S::Error> {
26*bb4ee6a4SAndroid Build Coastguard Worker let lock = item.lock();
27*bb4ee6a4SAndroid Build Coastguard Worker serde::Serialize::serialize(&*lock, serializer)
28*bb4ee6a4SAndroid Build Coastguard Worker }
29*bb4ee6a4SAndroid Build Coastguard Worker
30*bb4ee6a4SAndroid Build Coastguard Worker /// Serialize data T inside arrays as a seq instead of a tuple. T must be serializable.
31*bb4ee6a4SAndroid Build Coastguard Worker /// When deserializing, an array size validation is required to transform the slice to an array.
32*bb4ee6a4SAndroid Build Coastguard Worker ///
33*bb4ee6a4SAndroid Build Coastguard Worker /// This approach is used to go around serde's limitation of serializable array sizes.
serialize_arr<S, T: Sized + Serialize, const SIZE: usize>( data: &[T; SIZE], serializer: S, ) -> Result<S::Ok, S::Error> where S: Serializer,34*bb4ee6a4SAndroid Build Coastguard Worker pub fn serialize_arr<S, T: Sized + Serialize, const SIZE: usize>(
35*bb4ee6a4SAndroid Build Coastguard Worker data: &[T; SIZE],
36*bb4ee6a4SAndroid Build Coastguard Worker serializer: S,
37*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<S::Ok, S::Error>
38*bb4ee6a4SAndroid Build Coastguard Worker where
39*bb4ee6a4SAndroid Build Coastguard Worker S: Serializer,
40*bb4ee6a4SAndroid Build Coastguard Worker {
41*bb4ee6a4SAndroid Build Coastguard Worker serde::Serialize::serialize(&data[..], serializer)
42*bb4ee6a4SAndroid Build Coastguard Worker }
43*bb4ee6a4SAndroid Build Coastguard Worker
44*bb4ee6a4SAndroid Build Coastguard Worker /// Deserialize sequence of T into an Array of SIZE == Size of sequence.
45*bb4ee6a4SAndroid Build Coastguard Worker /// This function is a workaround to the serde limitation on array size (32) deserialization.
deserialize_seq_to_arr< 'de, D, T: Sized + Deserialize<'de> + std::fmt::Debug, const SIZE: usize, >( deserializer: D, ) -> Result<[T; SIZE], D::Error> where D: Deserializer<'de>,46*bb4ee6a4SAndroid Build Coastguard Worker pub fn deserialize_seq_to_arr<
47*bb4ee6a4SAndroid Build Coastguard Worker 'de,
48*bb4ee6a4SAndroid Build Coastguard Worker D,
49*bb4ee6a4SAndroid Build Coastguard Worker T: Sized + Deserialize<'de> + std::fmt::Debug,
50*bb4ee6a4SAndroid Build Coastguard Worker const SIZE: usize,
51*bb4ee6a4SAndroid Build Coastguard Worker >(
52*bb4ee6a4SAndroid Build Coastguard Worker deserializer: D,
53*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<[T; SIZE], D::Error>
54*bb4ee6a4SAndroid Build Coastguard Worker where
55*bb4ee6a4SAndroid Build Coastguard Worker D: Deserializer<'de>,
56*bb4ee6a4SAndroid Build Coastguard Worker {
57*bb4ee6a4SAndroid Build Coastguard Worker let vals_vec: Vec<T> = serde::Deserialize::deserialize(deserializer)?;
58*bb4ee6a4SAndroid Build Coastguard Worker let vals_arr: [T; SIZE] = vals_vec.try_into().map_err(|_| {
59*bb4ee6a4SAndroid Build Coastguard Worker <D as Deserializer>::Error::custom("failed to convert vector to array while deserializing")
60*bb4ee6a4SAndroid Build Coastguard Worker })?;
61*bb4ee6a4SAndroid Build Coastguard Worker Ok(vals_arr)
62*bb4ee6a4SAndroid Build Coastguard Worker }
63*bb4ee6a4SAndroid Build Coastguard Worker
serialize_map_as_kv_vec< 'se, MapKeyType: 'se + Serialize, MapValType: 'se + Serialize, MapType: std::iter::IntoIterator<Item = (&'se MapKeyType, &'se MapValType)>, S, >( map: MapType, serializer: S, ) -> Result<S::Ok, S::Error> where S: Serializer,64*bb4ee6a4SAndroid Build Coastguard Worker pub fn serialize_map_as_kv_vec<
65*bb4ee6a4SAndroid Build Coastguard Worker 'se,
66*bb4ee6a4SAndroid Build Coastguard Worker MapKeyType: 'se + Serialize,
67*bb4ee6a4SAndroid Build Coastguard Worker MapValType: 'se + Serialize,
68*bb4ee6a4SAndroid Build Coastguard Worker MapType: std::iter::IntoIterator<Item = (&'se MapKeyType, &'se MapValType)>,
69*bb4ee6a4SAndroid Build Coastguard Worker S,
70*bb4ee6a4SAndroid Build Coastguard Worker >(
71*bb4ee6a4SAndroid Build Coastguard Worker map: MapType,
72*bb4ee6a4SAndroid Build Coastguard Worker serializer: S,
73*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<S::Ok, S::Error>
74*bb4ee6a4SAndroid Build Coastguard Worker where
75*bb4ee6a4SAndroid Build Coastguard Worker S: Serializer,
76*bb4ee6a4SAndroid Build Coastguard Worker {
77*bb4ee6a4SAndroid Build Coastguard Worker let kv_vec: Vec<(&MapKeyType, &MapValType)> = map.into_iter().collect();
78*bb4ee6a4SAndroid Build Coastguard Worker serde::Serialize::serialize(&kv_vec, serializer)
79*bb4ee6a4SAndroid Build Coastguard Worker }
80*bb4ee6a4SAndroid Build Coastguard Worker
deserialize_map_from_kv_vec< 'de, MapKeyType: Deserialize<'de>, MapValType: Deserialize<'de>, MapType: std::iter::FromIterator<(MapKeyType, MapValType)>, D, >( deserializer: D, ) -> Result<MapType, D::Error> where D: Deserializer<'de>,81*bb4ee6a4SAndroid Build Coastguard Worker pub fn deserialize_map_from_kv_vec<
82*bb4ee6a4SAndroid Build Coastguard Worker 'de,
83*bb4ee6a4SAndroid Build Coastguard Worker MapKeyType: Deserialize<'de>,
84*bb4ee6a4SAndroid Build Coastguard Worker MapValType: Deserialize<'de>,
85*bb4ee6a4SAndroid Build Coastguard Worker MapType: std::iter::FromIterator<(MapKeyType, MapValType)>,
86*bb4ee6a4SAndroid Build Coastguard Worker D,
87*bb4ee6a4SAndroid Build Coastguard Worker >(
88*bb4ee6a4SAndroid Build Coastguard Worker deserializer: D,
89*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<MapType, D::Error>
90*bb4ee6a4SAndroid Build Coastguard Worker where
91*bb4ee6a4SAndroid Build Coastguard Worker D: Deserializer<'de>,
92*bb4ee6a4SAndroid Build Coastguard Worker {
93*bb4ee6a4SAndroid Build Coastguard Worker let kv_vec: Vec<(MapKeyType, MapValType)> = serde::Deserialize::deserialize(deserializer)?;
94*bb4ee6a4SAndroid Build Coastguard Worker Ok(MapType::from_iter(kv_vec))
95*bb4ee6a4SAndroid Build Coastguard Worker }
96