@@ -50,14 +50,6 @@ impl TryFrom<char> for Ability {
5050 }
5151}
5252
53- impl TryFrom < String > for Capability {
54- type Error = Error ;
55-
56- fn try_from ( value : String ) -> Result < Self , Error > {
57- value. as_str ( ) . try_into ( )
58- }
59- }
60-
6153impl Display for Capability {
6254 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
6355 write ! (
@@ -69,6 +61,14 @@ impl Display for Capability {
6961 }
7062}
7163
64+ impl TryFrom < String > for Capability {
65+ type Error = Error ;
66+
67+ fn try_from ( value : String ) -> Result < Self , Error > {
68+ value. as_str ( ) . try_into ( )
69+ }
70+ }
71+
7272impl TryFrom < & str > for Capability {
7373 type Error = Error ;
7474
@@ -105,6 +105,28 @@ impl TryFrom<&str> for Capability {
105105 }
106106}
107107
108+ impl Serialize for Capability {
109+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
110+ where
111+ S : serde:: Serializer ,
112+ {
113+ let string = self . to_string ( ) ;
114+
115+ string. serialize ( serializer)
116+ }
117+ }
118+
119+ impl < ' de > Deserialize < ' de > for Capability {
120+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
121+ where
122+ D : serde:: Deserializer < ' de > ,
123+ {
124+ let string: String = Deserialize :: deserialize ( deserializer) ?;
125+
126+ string. try_into ( ) . map_err ( serde:: de:: Error :: custom)
127+ }
128+ }
129+
108130#[ derive( thiserror:: Error , Debug , PartialEq , Eq ) ]
109131pub enum Error {
110132 #[ error( "Capability: Invalid resource path: does not start with `/`" ) ]
@@ -115,25 +137,61 @@ pub enum Error {
115137 InvalidAbility ,
116138}
117139
118- impl Serialize for Capability {
140+ #[ derive( Clone , Default , Debug , PartialEq , Eq ) ]
141+ /// A wrapper around `Vec<Capability>` to enable serialization without
142+ /// a varint. Useful when [Capabilities] are at the end of a struct.
143+ pub struct Capabilities ( pub Vec < Capability > ) ;
144+
145+ impl Capabilities {
146+ pub fn contains ( & self , capability : & Capability ) -> bool {
147+ self . 0 . contains ( capability)
148+ }
149+ }
150+
151+ impl From < Vec < Capability > > for Capabilities {
152+ fn from ( value : Vec < Capability > ) -> Self {
153+ Self ( value)
154+ }
155+ }
156+
157+ impl From < Capabilities > for Vec < Capability > {
158+ fn from ( value : Capabilities ) -> Self {
159+ value. 0
160+ }
161+ }
162+
163+ impl Serialize for Capabilities {
119164 fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
120165 where
121166 S : serde:: Serializer ,
122167 {
123- let string = self . to_string ( ) ;
168+ let string = self
169+ . 0
170+ . iter ( )
171+ . map ( |c| c. to_string ( ) )
172+ . collect :: < Vec < _ > > ( )
173+ . join ( "," ) ;
124174
125175 string. serialize ( serializer)
126176 }
127177}
128178
129- impl < ' de > Deserialize < ' de > for Capability {
179+ impl < ' de > Deserialize < ' de > for Capabilities {
130180 fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
131181 where
132182 D : serde:: Deserializer < ' de > ,
133183 {
134184 let string: String = Deserialize :: deserialize ( deserializer) ?;
135185
136- string. try_into ( ) . map_err ( serde:: de:: Error :: custom)
186+ let mut caps = vec ! [ ] ;
187+
188+ for s in string. split ( ',' ) {
189+ if let Ok ( cap) = Capability :: try_from ( s) {
190+ caps. push ( cap) ;
191+ } ;
192+ }
193+
194+ Ok ( Capabilities ( caps) )
137195 }
138196}
139197
0 commit comments