@@ -77,7 +77,8 @@ macro_rules! new_type {
7777 }
7878 ) => {
7979 $( #[ $attr] ) *
80- #[ derive( Clone , Debug , PartialEq ) ]
80+ #[ derive( Clone , Debug , PartialEq , Eq , Hash , :: serde:: Serialize , :: serde:: Deserialize ) ]
81+ #[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
8182 pub struct $name(
8283 $( #[ $type_attr] ) *
8384 $type
@@ -344,13 +345,29 @@ macro_rules! new_url_type {
344345 }
345346 }
346347 impl Eq for $name { }
348+
349+
350+ #[ cfg( feature = "schemars" ) ]
351+ impl schemars:: JsonSchema for $name {
352+ fn schema_name( ) -> String {
353+ stringify!( $name) . to_owned( )
354+ }
355+
356+ fn schema_id( ) -> std:: borrow:: Cow <' static , str > {
357+ std:: borrow:: Cow :: Borrowed ( concat!( "oauth2::" , stringify!( $name) ) )
358+ }
359+
360+ fn json_schema( gen : & mut schemars:: gen :: SchemaGenerator ) -> schemars:: schema:: Schema {
361+ // HELP(gibbz00): do we want to generate the schema for a URL or a String?
362+ gen . subschema_for:: <String >( )
363+ }
364+ }
347365 } ;
348366}
349367
350368new_type ! [
351369 /// Client identifier issued to the client during the registration process described by
352370 /// [Section 2.2](https://tools.ietf.org/html/rfc6749#section-2.2).
353- #[ derive( Deserialize , Serialize , Eq , Hash ) ]
354371 ClientId ( String )
355372] ;
356373
@@ -385,19 +402,16 @@ new_url_type.
388- #[ derive( Deserialize , Serialize , Eq , Hash ) ]
389405 ResponseType ( String )
390406] ;
391407new_type ! [
392408 /// Resource owner's username used directly as an authorization grant to obtain an access
393409 /// token.
394- #[ derive( Deserialize , Serialize , Eq , Hash ) ]
395410 ResourceOwnerUsername ( String )
396411] ;
397412
398413new_type ! [
399414 /// Access token scope, as defined by the authorization server.
400- #[ derive( Deserialize , Serialize , Eq , Hash ) ]
401415 Scope ( String )
402416] ;
403417impl AsRef < str > for Scope {
@@ -409,7 +423,6 @@ impl AsRef<str> for Scope {
409423new_type ! [
410424 /// Code Challenge Method used for [PKCE](https://tools.ietf.org/html/rfc7636) protection
411425 /// via the `code_challenge_method` parameter.
412- #[ derive( Deserialize , Serialize , Eq , Hash ) ]
413426 PkceCodeChallengeMethod ( String )
414427] ;
415428// This type intentionally does not implement Clone in order to make it difficult to reuse PKCE
@@ -614,7 +627,7 @@ new_secret_type![
614627
615628#[ cfg( test) ]
616629mod tests {
617- use crate :: { ClientSecret , CsrfToken , PkceCodeChallenge , PkceCodeVerifier } ;
630+ use super :: * ;
618631
619632 #[ test]
620633 fn test_secret_conversion ( ) {
@@ -662,4 +675,39 @@ mod tests {
662675 "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM" ,
663676 ) ;
664677 }
678+
679+ #[ cfg( feature = "schemars" ) ]
680+ mod json_schema {
681+ use schemars:: schema_for;
682+ use serde_json:: json;
683+
684+ use super :: * ;
685+
686+ #[ test]
687+ fn generates_new_type_json_schema ( ) {
688+ let expected_schema = json ! ( {
689+ "$schema" : "http://json-schema.org/draft-07/schema#" ,
690+ "title" : "ClientId" ,
691+ "description" : "Client identifier issued to the client during the registration process described by [Section 2.2](https://tools.ietf.org/html/rfc6749#section-2.2)." ,
692+ "type" : "string"
693+ } ) ;
694+
695+ let schema = schema_for ! ( ClientId ) ;
696+ let actual_schema = serde_json:: to_value ( & schema) . unwrap ( ) ;
697+ assert_eq ! ( expected_schema, actual_schema)
698+ }
699+
700+ #[ test]
701+ fn generates_new_url_type_json_schema ( ) {
702+ let expected_schema = json ! ( {
703+ "$schema" : "http://json-schema.org/draft-07/schema#" ,
704+ "title" : "RedirectUrl" ,
705+ "type" : "string"
706+ } ) ;
707+
708+ let schema = schema_for ! ( RedirectUrl ) ;
709+ let actual_schema = serde_json:: to_value ( & schema) . unwrap ( ) ;
710+ assert_eq ! ( expected_schema, actual_schema) ;
711+ }
712+ }
665713}
0 commit comments