osom_lib_primitives/
kvp.rs1use core::fmt::Display;
3
4use osom_lib_reprc::traits::ReprC;
5use osom_lib_try_clone::TryClone;
6
7#[repr(C)]
9#[repr(u8)]
10#[derive(Debug, PartialEq, Eq, Hash, Clone)]
11#[must_use]
12#[allow(clippy::upper_case_acronyms)]
13pub enum KVPTryCloneError<TKeyError, TValueError> {
14 KeyCloneError(TKeyError) = 0,
16
17 ValueError(TValueError) = 1,
19}
20
21#[repr(C)]
23#[must_use]
24#[derive(Debug, PartialEq, Eq, Hash)]
25#[allow(clippy::upper_case_acronyms)]
26pub struct KVP<TKey, TValue> {
27 pub key: TKey,
28 pub value: TValue,
29}
30
31unsafe impl<TKey: ReprC, TValue: ReprC> ReprC for KVP<TKey, TValue> {
32 const CHECK: () = const {
33 osom_lib_reprc::hidden::is_reprc::<TKey>();
34 osom_lib_reprc::hidden::is_reprc::<TValue>();
35 };
36}
37
38impl<TKey, TValue> KVP<TKey, TValue> {
39 #[inline]
41 #[must_use]
42 pub const fn unpack(self) -> (TKey, TValue) {
43 let key = unsafe { core::ptr::read(&raw const self.key) };
44 let value = unsafe { core::ptr::read(&raw const self.value) };
45 core::mem::forget(self);
46 (key, value)
47 }
48
49 #[inline(always)]
55 #[must_use]
56 pub const unsafe fn unpack_ptr(ptr: *mut Self) -> (*mut TKey, *mut TValue) {
57 unsafe {
58 let mut_ref = ptr.as_mut_unchecked();
59 (&raw mut mut_ref.key, &raw mut mut_ref.value)
60 }
61 }
62
63 #[inline(always)]
65 pub const fn as_ref_kvp(&self) -> KVP<&TKey, &TValue> {
66 KVP {
67 key: &self.key,
68 value: &self.value,
69 }
70 }
71
72 #[inline(always)]
75 pub const fn as_mut_kvp(&mut self) -> KVP<&TKey, &mut TValue> {
76 KVP {
77 key: &self.key,
78 value: &mut self.value,
79 }
80 }
81
82 #[inline]
84 #[must_use]
85 pub const fn as_tuple(&self) -> (&TKey, &TValue) {
86 (&self.key, &self.value)
87 }
88
89 #[inline]
91 #[must_use]
92 pub const fn as_mut_tuple(&mut self) -> (&mut TKey, &mut TValue) {
93 (&mut self.key, &mut self.value)
94 }
95}
96
97impl<TKey: Display, TValue: Display> Display for KVP<TKey, TValue> {
98 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
99 write!(f, "KVP(key: {}, value: {})", self.key, self.value)
100 }
101}
102
103impl<TKey, TValue> From<(TKey, TValue)> for KVP<TKey, TValue> {
104 fn from((key, value): (TKey, TValue)) -> Self {
105 Self { key, value }
106 }
107}
108
109impl<TKey, TValue> From<KVP<TKey, TValue>> for (TKey, TValue) {
110 fn from(kvp: KVP<TKey, TValue>) -> Self {
111 kvp.unpack()
112 }
113}
114
115impl<TKey: TryClone, TValue: TryClone> TryClone for KVP<TKey, TValue> {
116 type Error = KVPTryCloneError<TKey::Error, TValue::Error>;
117
118 fn try_clone(&self) -> Result<Self, Self::Error> {
119 Ok(Self {
120 key: self.key.try_clone().map_err(KVPTryCloneError::KeyCloneError)?,
121 value: self.value.try_clone().map_err(KVPTryCloneError::ValueError)?,
122 })
123 }
124}
125
126impl<TKey: TryClone, TValue: TryClone> Clone for KVP<TKey, TValue> {
127 fn clone(&self) -> Self {
128 self.try_clone().expect("[KVP::clone] failure")
129 }
130}