1- use alloc:: string :: String ;
1+ use alloc:: borrow :: Cow ;
22use serde:: { Deserialize , Serialize } ;
33
44#[ cfg( feature = "introspection" ) ]
@@ -46,40 +46,68 @@ pub enum Reply<'a> {
4646#[ cfg_attr( feature = "introspection" , derive( introspect:: ReplyError ) ) ]
4747#[ zlink( interface = "org.varlink.service" ) ]
4848#[ cfg_attr( feature = "introspection" , zlink( crate = "crate" ) ) ]
49- pub enum Error {
49+ pub enum Error < ' a > {
5050 /// The requested interface was not found.
5151 InterfaceNotFound {
5252 /// The interface that was not found.
53- interface : String ,
53+ #[ zlink( borrow) ]
54+ interface : Cow < ' a , str > ,
5455 } ,
5556 /// The requested method was not found.
5657 MethodNotFound {
5758 /// The method that was not found.
58- method : String ,
59+ #[ zlink( borrow) ]
60+ method : Cow < ' a , str > ,
5961 } ,
6062 /// The interface defines the requested method, but the service does not implement it.
6163 MethodNotImplemented {
6264 /// The method that is not implemented.
63- method : String ,
65+ #[ zlink( borrow) ]
66+ method : Cow < ' a , str > ,
6467 } ,
6568 /// One of the passed parameters is invalid.
6669 InvalidParameter {
6770 /// The parameter that is invalid.
68- parameter : String ,
71+ #[ zlink( borrow) ]
72+ parameter : Cow < ' a , str > ,
6973 } ,
7074 /// Client is denied access.
7175 PermissionDenied ,
7276 /// Method is expected to be called with 'more' set to true, but wasn't.
7377 ExpectedMore ,
7478}
7579
76- impl core:: error:: Error for Error {
80+ impl Error < ' _ > {
81+ /// Convert this error into an owned version with `'static` lifetime.
82+ ///
83+ /// This is useful when you need to store or propagate the error.
84+ pub fn into_owned ( self ) -> Error < ' static > {
85+ match self {
86+ Error :: InterfaceNotFound { interface } => Error :: InterfaceNotFound {
87+ interface : Cow :: Owned ( interface. into_owned ( ) ) ,
88+ } ,
89+ Error :: MethodNotFound { method } => Error :: MethodNotFound {
90+ method : Cow :: Owned ( method. into_owned ( ) ) ,
91+ } ,
92+ Error :: MethodNotImplemented { method } => Error :: MethodNotImplemented {
93+ method : Cow :: Owned ( method. into_owned ( ) ) ,
94+ } ,
95+ Error :: InvalidParameter { parameter } => Error :: InvalidParameter {
96+ parameter : Cow :: Owned ( parameter. into_owned ( ) ) ,
97+ } ,
98+ Error :: PermissionDenied => Error :: PermissionDenied ,
99+ Error :: ExpectedMore => Error :: ExpectedMore ,
100+ }
101+ }
102+ }
103+
104+ impl core:: error:: Error for Error < ' _ > {
77105 fn source ( & self ) -> Option < & ( dyn core:: error:: Error + ' static ) > {
78106 None
79107 }
80108}
81109
82- impl core:: fmt:: Display for Error {
110+ impl core:: fmt:: Display for Error < ' _ > {
83111 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
84112 match self {
85113 Error :: InterfaceNotFound { interface } => {
@@ -105,17 +133,16 @@ impl core::fmt::Display for Error {
105133}
106134
107135/// Result type for Varlink service methods.
108- pub type Result < T > = core:: result:: Result < T , Error > ;
136+ pub type Result < ' a , T > = core:: result:: Result < T , Error < ' a > > ;
109137
110138#[ cfg( test) ]
111139mod tests {
112140 use super :: * ;
113- use core:: str:: FromStr ;
114141
115142 #[ test]
116143 fn error_serialization ( ) {
117144 let err = Error :: InterfaceNotFound {
118- interface : String :: from_str ( "com.example.missing" ) . unwrap ( ) ,
145+ interface : Cow :: Borrowed ( "com.example.missing" ) ,
119146 } ;
120147
121148 let json = serialize_error ( & err) ;
@@ -130,86 +157,100 @@ mod tests {
130157
131158 #[ test]
132159 fn error_deserialization ( ) {
133- // Test error with parameter
160+ // Test error with parameter.
134161 let json = r#"{"error":"org.varlink.service.InterfaceNotFound","parameters":{"interface":"com.example.missing"}}"# ;
135- let err = deserialize_error ( json) ;
162+ let err: Error < ' _ > = deserialize_error ( json) ;
136163 assert_eq ! (
137164 err,
138165 Error :: InterfaceNotFound {
139- interface: String :: from_str ( "com.example.missing" ) . unwrap ( )
166+ interface: Cow :: Borrowed ( "com.example.missing" )
140167 }
141168 ) ;
142169
143- // Test error without parameters
170+ // Test error without parameters.
144171 let json = r#"{"error":"org.varlink.service.PermissionDenied"}"# ;
145- let err = deserialize_error ( json) ;
172+ let err: Error < ' _ > = deserialize_error ( json) ;
146173 assert_eq ! ( err, Error :: PermissionDenied ) ;
147174
148- // Test MethodNotFound error
175+ // Test MethodNotFound error.
149176 let json = r#"{"error":"org.varlink.service.MethodNotFound","parameters":{"method":"NonExistentMethod"}}"# ;
150- let err = deserialize_error ( json) ;
177+ let err: Error < ' _ > = deserialize_error ( json) ;
151178 assert_eq ! (
152179 err,
153180 Error :: MethodNotFound {
154- method: String :: from_str ( "NonExistentMethod" ) . unwrap ( )
181+ method: Cow :: Borrowed ( "NonExistentMethod" )
155182 }
156183 ) ;
157184
158- // Test InvalidParameter error
185+ // Test InvalidParameter error.
159186 let json = r#"{"error":"org.varlink.service.InvalidParameter","parameters":{"parameter":"invalid_param"}}"# ;
160- let err = deserialize_error ( json) ;
187+ let err: Error < ' _ > = deserialize_error ( json) ;
161188 assert_eq ! (
162189 err,
163190 Error :: InvalidParameter {
164- parameter: String :: from_str ( "invalid_param" ) . unwrap ( )
191+ parameter: Cow :: Borrowed ( "invalid_param" )
165192 }
166193 ) ;
167194
168- // Test MethodNotImplemented error
195+ // Test MethodNotImplemented error.
169196 let json = r#"{"error":"org.varlink.service.MethodNotImplemented","parameters":{"method":"UnimplementedMethod"}}"# ;
170- let err = deserialize_error ( json) ;
197+ let err: Error < ' _ > = deserialize_error ( json) ;
171198 assert_eq ! (
172199 err,
173200 Error :: MethodNotImplemented {
174- method: String :: from_str ( "UnimplementedMethod" ) . unwrap ( )
201+ method: Cow :: Borrowed ( "UnimplementedMethod" )
175202 }
176203 ) ;
177204
178- // Test ExpectedMore error
205+ // Test ExpectedMore error.
179206 let json = r#"{"error":"org.varlink.service.ExpectedMore"}"# ;
180- let err = deserialize_error ( json) ;
207+ let err: Error < ' _ > = deserialize_error ( json) ;
181208 assert_eq ! ( err, Error :: ExpectedMore ) ;
182209 }
183210
184211 #[ test]
185212 fn error_round_trip_serialization ( ) {
186- // Test with error that has parameters
213+ // Test with error that has parameters.
187214 let original = Error :: InterfaceNotFound {
188- interface : String :: from_str ( "com.example.missing" ) . unwrap ( ) ,
215+ interface : Cow :: Borrowed ( "com.example.missing" ) ,
189216 } ;
190217
191218 test_round_trip_serialize ( & original) ;
192219
193- // Test with error that has no parameters
220+ // Test with error that has no parameters.
194221 let original = Error :: PermissionDenied ;
195222
196223 test_round_trip_serialize ( & original) ;
197224 }
198225
199- // Helper function to serialize Error to JSON string, abstracting std vs nostd differences
200- fn serialize_error ( err : & Error ) -> String {
226+ #[ test]
227+ fn into_owned ( ) {
228+ let borrowed = Error :: InterfaceNotFound {
229+ interface : Cow :: Borrowed ( "test.interface" ) ,
230+ } ;
231+ let owned = borrowed. into_owned ( ) ;
232+ assert_eq ! (
233+ owned,
234+ Error :: InterfaceNotFound {
235+ interface: Cow :: Owned ( "test.interface" . into( ) )
236+ }
237+ ) ;
238+ }
239+
240+ // Helper function to serialize Error to JSON string.
241+ fn serialize_error ( err : & Error < ' _ > ) -> String {
201242 serde_json:: to_string ( err) . unwrap ( )
202243 }
203244
204- // Helper function to deserialize JSON string to Error, abstracting std vs nostd differences
205- fn deserialize_error ( json : & str ) -> Error {
245+ // Helper function to deserialize JSON string to Error.
246+ fn deserialize_error ( json : & str ) -> Error < ' _ > {
206247 serde_json:: from_str ( json) . unwrap ( )
207248 }
208249
209- // Helper function for round-trip serialization test, abstracting std vs nostd differences
210- fn test_round_trip_serialize ( original : & Error ) {
250+ // Helper function for round-trip serialization test.
251+ fn test_round_trip_serialize ( original : & Error < ' _ > ) {
211252 let json = serde_json:: to_string ( original) . unwrap ( ) ;
212- let deserialized: Error = serde_json:: from_str ( & json) . unwrap ( ) ;
253+ let deserialized: Error < ' _ > = serde_json:: from_str ( & json) . unwrap ( ) ;
213254 assert_eq ! ( * original, deserialized) ;
214255 }
215256}
0 commit comments