paseto_core/paserk/
plaintext.rs1use alloc::boxed::Box;
2use core::fmt;
3use core::marker::PhantomData;
4
5use crate::PasetoError;
6use crate::key::{HasKey, Key, KeyType};
7use crate::version::Version;
8
9pub struct KeyText<V: Version, K: KeyType> {
13 data: Box<[u8]>,
14 _key: PhantomData<(V, K)>,
15}
16
17impl<V: HasKey<K>, K: KeyType> Key<V, K> {
18 pub fn expose_key(&self) -> KeyText<V, K> {
23 KeyText {
24 data: V::encode(&self.0),
25 _key: PhantomData,
26 }
27 }
28}
29
30impl<V: Version, K: KeyType> KeyText<V, K> {
31 pub fn from_raw_bytes(b: &[u8]) -> Self {
33 KeyText {
34 data: b.into(),
35 _key: PhantomData,
36 }
37 }
38
39 pub fn as_raw_bytes(&self) -> &[u8] {
41 &self.data
42 }
43}
44
45impl<V: Version, K: KeyType> PartialEq for KeyText<V, K> {
46 fn eq(&self, other: &Self) -> bool {
47 self.data == other.data
48 }
49}
50
51impl<V: Version, K: KeyType> PartialOrd for KeyText<V, K> {
52 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
53 Some(self.cmp(other))
54 }
55}
56
57impl<V: Version, K: KeyType> Eq for KeyText<V, K> {}
58
59impl<V: Version, K: KeyType> Ord for KeyText<V, K> {
60 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
61 self.data.cmp(&other.data)
62 }
63}
64
65impl<V: Version, K: KeyType> core::hash::Hash for KeyText<V, K> {
66 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
67 self.data.hash(state);
68 }
69}
70
71impl<V: HasKey<K>, K: KeyType> TryFrom<KeyText<V, K>> for Key<V, K> {
72 type Error = PasetoError;
73 fn try_from(value: KeyText<V, K>) -> Result<Key<V, K>, PasetoError> {
74 V::decode(&value.data).map(Key)
75 }
76}
77
78impl<V: Version, K: KeyType> fmt::Display for KeyText<V, K> {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 f.write_str(V::PASERK_HEADER)?;
81 f.write_str(K::HEADER)?;
82 crate::base64::write_to_fmt(&self.data, f)
83 }
84}
85
86impl<V: Version, K: KeyType> core::str::FromStr for KeyText<V, K> {
87 type Err = PasetoError;
88
89 fn from_str(s: &str) -> Result<Self, Self::Err> {
90 let s = s
91 .strip_prefix(V::PASERK_HEADER)
92 .ok_or(PasetoError::InvalidKey)?;
93 let s = s.strip_prefix(K::HEADER).ok_or(PasetoError::InvalidKey)?;
94
95 let data = crate::base64::decode_vec(s)?.into_boxed_slice();
96
97 Ok(Self {
98 data,
99 _key: PhantomData,
100 })
101 }
102}
103
104serde_str!(
105 impl<V, K> KeyText<V, K>
106 where
107 V: Version,
108 K: KeyType,
109 {
110 fn expecting() {
111 format_args!("a {}{} PASERK key", V::PASERK_HEADER, K::HEADER)
112 }
113 }
114);