1use crate::utils::Vec;
4use crate::{Key, KeyError, KeyRing, KeySerialId, KeyType, Metadata};
5use core::cmp::PartialEq;
6use core::ops::Deref;
7
8#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11pub enum LinkNode {
12 KeyRing(KeyRing),
13 Key(Key),
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
36pub struct Links(Vec<LinkNode>);
37
38impl PartialEq<Key> for LinkNode {
39 fn eq(&self, other: &Key) -> bool {
40 matches!(self, LinkNode::Key(x) if x == other)
41 }
42}
43
44impl PartialEq<Key> for &LinkNode {
45 fn eq(&self, other: &Key) -> bool {
46 matches!(self, LinkNode::Key(x) if x == other)
47 }
48}
49
50impl PartialEq<KeyRing> for LinkNode {
51 fn eq(&self, other: &KeyRing) -> bool {
52 matches!(self, LinkNode::KeyRing(x) if x == other)
53 }
54}
55
56impl PartialEq<KeyRing> for &LinkNode {
57 fn eq(&self, other: &KeyRing) -> bool {
58 matches!(self, LinkNode::KeyRing(x) if x == other)
59 }
60}
61
62impl LinkNode {
63 pub(crate) fn from_id(id: KeySerialId) -> Result<Self, KeyError> {
65 let metadata = Metadata::from_id(id)?;
66 let node = match metadata.get_type() {
67 KeyType::KeyRing => Self::KeyRing(KeyRing::from_id(id)),
68 KeyType::User => Self::Key(Key::from_id(id)),
69 _ => return Err(KeyError::OperationNotSupported),
70 };
71 Ok(node)
72 }
73
74 pub fn as_key(&self) -> Option<Key> {
78 match self {
79 Self::Key(inner) => Some(*inner),
80 _ => None,
81 }
82 }
83
84 pub fn as_ring(&self) -> Option<KeyRing> {
88 match self {
89 Self::KeyRing(inner) => Some(*inner),
90 _ => None,
91 }
92 }
93}
94
95impl Deref for Links {
96 type Target = Vec<LinkNode>;
97
98 fn deref(&self) -> &Self::Target {
99 &self.0
100 }
101}
102
103impl FromIterator<LinkNode> for Links {
104 fn from_iter<T>(iter: T) -> Self
105 where
106 T: IntoIterator<Item = LinkNode>,
107 {
108 Self(iter.into_iter().collect())
109 }
110}
111
112impl Links {
113 pub fn new(inner: Vec<LinkNode>) -> Self {
115 Self(inner)
116 }
117
118 pub fn get<T>(&self, entry: &T) -> Option<&LinkNode>
120 where
121 LinkNode: PartialEq<T>,
122 {
123 self.0.iter().find(|v| *v == entry)
124 }
125
126 pub fn contains<T>(&self, entry: &T) -> bool
128 where
129 LinkNode: PartialEq<T>,
130 {
131 self.0.iter().any(|v| v == entry)
132 }
133}