@@ -4,8 +4,9 @@ extern crate std;
44
55use ciborium:: cbor;
66use ciborium:: tag:: Required ;
7- use ciborium:: value:: CanonicalValue ;
7+ use ciborium:: value:: { canonical_into_vec , canonical_value , CanonicalValue , Value } ;
88use rand:: prelude:: * ;
9+ use serde:: { Deserialize , Serialize } ;
910use std:: collections:: BTreeMap ;
1011
1112macro_rules! cval {
@@ -109,3 +110,91 @@ fn tagged_option() {
109110 let output = ciborium:: de:: from_reader ( & bytes[ ..] ) . unwrap ( ) ;
110111 assert_eq ! ( opt, output) ;
111112}
113+
114+ #[ test]
115+ fn canonical_value_example ( ) {
116+ let map = Value :: Map ( vec ! [
117+ ( val!( false ) , val!( 2 ) ) ,
118+ ( val!( [ -1 ] ) , val!( 5 ) ) ,
119+ ( val!( -1 ) , val!( 1 ) ) ,
120+ ( val!( 10 ) , val!( 0 ) ) ,
121+ ( val!( 100 ) , val!( 3 ) ) ,
122+ ( val!( [ 100 ] ) , val!( 7 ) ) ,
123+ ( val!( "z" ) , val!( 4 ) ) ,
124+ ( val!( "aa" ) , val!( 6 ) ) ,
125+ ] ) ;
126+
127+ let bytes = canonical_into_vec ( & map) . unwrap ( ) ;
128+ assert_eq ! (
129+ hex:: encode( & bytes) ,
130+ "a80a002001f402186403617a048120056261610681186407"
131+ ) ;
132+
133+ let canonical = canonical_value ( map) ;
134+ let bytes = ciborium:: ser:: into_vec ( & canonical) . unwrap ( ) ;
135+
136+ assert_eq ! (
137+ hex:: encode( & bytes) ,
138+ "a80a002001f402186403617a048120056261610681186407"
139+ ) ;
140+ }
141+
142+ #[ test]
143+ fn canonical_value_nested_structures ( ) {
144+ // Create nested structure with unsorted maps
145+ let nested = Value :: Array ( vec ! [
146+ Value :: Map ( vec![ ( val!( "b" ) , val!( 2 ) ) , ( val!( "a" ) , val!( 1 ) ) ] ) ,
147+ Value :: Tag (
148+ 1 ,
149+ Box :: new( Value :: Map ( vec![
150+ ( val!( 100 ) , val!( "high" ) ) ,
151+ ( val!( 10 ) , val!( "low" ) ) ,
152+ ] ) ) ,
153+ ) ,
154+ ] ) ;
155+
156+ let canonical = canonical_value ( nested) ;
157+
158+ if let Value :: Array ( elements) = canonical {
159+ // Check first map is sorted
160+ if let Value :: Map ( entries) = & elements[ 0 ] {
161+ assert_eq ! ( entries[ 0 ] . 0 , val!( "a" ) ) ;
162+ assert_eq ! ( entries[ 1 ] . 0 , val!( "b" ) ) ;
163+ }
164+
165+ // Check tagged map is sorted
166+ if let Value :: Tag ( _, inner) = & elements[ 1 ] {
167+ if let Value :: Map ( entries) = inner. as_ref ( ) {
168+ assert_eq ! ( entries[ 0 ] . 0 , val!( 10 ) ) ;
169+ assert_eq ! ( entries[ 1 ] . 0 , val!( 100 ) ) ;
170+ }
171+ }
172+ } else {
173+ panic ! ( "Expected Array value" ) ;
174+ }
175+ }
176+
177+ #[ test]
178+ fn canonical_value_struct ( ) {
179+ #[ derive( Clone , Debug , Deserialize , Serialize ) ]
180+ struct T1 {
181+ a : u32 ,
182+ b : u32 ,
183+ c : u32 ,
184+ }
185+
186+ #[ derive( Clone , Debug , Deserialize , Serialize ) ]
187+ struct T2 {
188+ c : u32 ,
189+ b : u32 ,
190+ a : u32 ,
191+ }
192+
193+ let t1 = T1 { a : 1 , b : 2 , c : 3 } ;
194+ let t2 = T2 { c : 3 , b : 2 , a : 1 } ;
195+
196+ assert_eq ! (
197+ canonical_into_vec( & t1) . unwrap( ) ,
198+ canonical_into_vec( & t2) . unwrap( )
199+ ) ;
200+ }
0 commit comments