@@ -33,7 +33,7 @@ use serde_json::{
3333 to_vec, Deserializer , Number , Value ,
3434} ;
3535use std:: collections:: BTreeMap ;
36- #[ cfg( feature = "raw_value" ) ]
36+ #[ cfg( any ( feature = "raw_value" , feature = "spanned" ) ) ]
3737use std:: collections:: HashMap ;
3838use std:: fmt:: { self , Debug } ;
3939use std:: hash:: BuildHasher ;
@@ -43,6 +43,8 @@ use std::io;
4343use std:: iter;
4444use std:: marker:: PhantomData ;
4545use std:: mem;
46+ #[ cfg( feature = "spanned" ) ]
47+ use std:: ops:: Range ;
4648use std:: str:: FromStr ;
4749use std:: { f32, f64} ;
4850
@@ -2558,3 +2560,138 @@ fn test_control_character_search() {
25582560 "control character (\\ u0000-\\ u001F) found while parsing a string at line 1 column 2" ,
25592561 ) ] ) ;
25602562}
2563+
2564+ #[ cfg( feature = "spanned" ) ]
2565+ fn format_span ( json : & str , span : Range < usize > ) -> String {
2566+ format ! (
2567+ "{}\n {}{}" ,
2568+ json,
2569+ " " . repeat( span. start) ,
2570+ "^" . repeat( span. end - span. start)
2571+ )
2572+ }
2573+
2574+ #[ cfg( feature = "spanned" ) ]
2575+ #[ track_caller]
2576+ fn assert_span_eq ( json : & str , expected : Range < usize > , actual : Range < usize > ) {
2577+ let expected_str = format_span ( json, expected. clone ( ) ) ;
2578+ let actual_str = format_span ( json, actual. clone ( ) ) ;
2579+
2580+ assert_eq ! (
2581+ expected, actual,
2582+ "Expected span:\n {}\n Actual span:\n {}" ,
2583+ expected_str, actual_str
2584+ ) ;
2585+ }
2586+
2587+ #[ cfg( feature = "spanned" ) ]
2588+ #[ test]
2589+ fn test_spanned_string ( ) {
2590+ use serde_spanned:: Spanned ;
2591+
2592+ #[ derive( Deserialize ) ]
2593+ struct SpannedStruct {
2594+ field : Spanned < String > ,
2595+ }
2596+
2597+ let json = r#"{"field": "value"}"# ;
2598+ let result: SpannedStruct = serde_json:: from_str ( json) . unwrap ( ) ;
2599+ assert_eq ! ( result. field. as_ref( ) , "value" ) ;
2600+ assert_span_eq ( json, result. field . span ( ) , 10 ..17 ) ;
2601+ }
2602+
2603+ #[ cfg( feature = "spanned" ) ]
2604+ #[ test]
2605+ fn test_spanned_number ( ) {
2606+ use serde_spanned:: Spanned ;
2607+
2608+ #[ derive( Deserialize ) ]
2609+ struct SpannedStruct {
2610+ field : Spanned < f64 > ,
2611+ }
2612+
2613+ let json = r#"{"field": -2.718e28}"# ;
2614+ let result: SpannedStruct = serde_json:: from_str ( json) . unwrap ( ) ;
2615+ assert_eq ! ( * result. field. as_ref( ) , -2.718e28 ) ;
2616+ assert_span_eq ( json, result. field . span ( ) , 10 ..19 ) ;
2617+ }
2618+
2619+ #[ cfg( feature = "spanned" ) ]
2620+ #[ test]
2621+ fn test_spanned_whole_array ( ) {
2622+ use serde_spanned:: Spanned ;
2623+
2624+ #[ derive( Deserialize ) ]
2625+ struct SpannedStruct {
2626+ field : Spanned < Vec < i32 > > ,
2627+ }
2628+
2629+ let json = r#"{"field": [1, 2, 3, 4]}"# ;
2630+ let result: SpannedStruct = serde_json:: from_str ( json) . unwrap ( ) ;
2631+ assert_eq ! ( result. field. as_ref( ) , & [ 1 , 2 , 3 , 4 ] ) ;
2632+ assert_span_eq ( json, result. field . span ( ) , 10 ..22 ) ;
2633+ }
2634+
2635+ #[ cfg( feature = "spanned" ) ]
2636+ #[ test]
2637+ fn test_spanned_array_items ( ) {
2638+ use serde_spanned:: Spanned ;
2639+
2640+ #[ derive( Deserialize ) ]
2641+ struct SpannedStruct {
2642+ field : Vec < Spanned < i32 > > ,
2643+ }
2644+
2645+ let json = r#"{"field": [1, 2, 3, 4]}"# ;
2646+ let result: SpannedStruct = serde_json:: from_str ( json) . unwrap ( ) ;
2647+ assert_eq ! ( result. field. len( ) , 4 ) ;
2648+
2649+ assert_eq ! ( * result. field[ 0 ] . as_ref( ) , 1 ) ;
2650+ assert_span_eq ( json, result. field [ 0 ] . span ( ) , 11 ..12 ) ;
2651+
2652+ assert_eq ! ( * result. field[ 1 ] . as_ref( ) , 2 ) ;
2653+ assert_span_eq ( json, result. field [ 1 ] . span ( ) , 14 ..15 ) ;
2654+
2655+ assert_eq ! ( * result. field[ 2 ] . as_ref( ) , 3 ) ;
2656+ assert_span_eq ( json, result. field [ 2 ] . span ( ) , 17 ..18 ) ;
2657+
2658+ assert_eq ! ( * result. field[ 3 ] . as_ref( ) , 4 ) ;
2659+ assert_span_eq ( json, result. field [ 3 ] . span ( ) , 20 ..21 ) ;
2660+ }
2661+
2662+ #[ cfg( feature = "spanned" ) ]
2663+ #[ test]
2664+ fn test_spanned_whole_map ( ) {
2665+ use serde_spanned:: Spanned ;
2666+
2667+ #[ derive( Deserialize ) ]
2668+ struct SpannedStruct {
2669+ field : Spanned < HashMap < i32 , String > > ,
2670+ }
2671+
2672+ let json = r#"{"field": {"1": "one", "2": "two"}}"# ;
2673+ let result: SpannedStruct = serde_json:: from_str ( json) . unwrap ( ) ;
2674+ assert_span_eq ( json, result. field . span ( ) , 10 ..34 ) ;
2675+ let mut map = result. field . into_inner ( ) ;
2676+ let one = map. remove ( & 1 ) . unwrap ( ) ;
2677+ assert_eq ! ( one, "one" ) ;
2678+ let two = map. remove ( & 2 ) . unwrap ( ) ;
2679+ assert_eq ! ( two, "two" ) ;
2680+ assert ! ( map. is_empty( ) ) ;
2681+ }
2682+
2683+ #[ cfg( feature = "spanned" ) ]
2684+ #[ test]
2685+ fn test_spanned_whitespace ( ) {
2686+ use serde_spanned:: Spanned ;
2687+
2688+ #[ derive( Deserialize ) ]
2689+ struct SpannedStruct {
2690+ field : Spanned < f64 > ,
2691+ }
2692+
2693+ let json = r#"{"field": -2.718e28 }"# ;
2694+ let result: SpannedStruct = serde_json:: from_str ( json) . unwrap ( ) ;
2695+ assert_eq ! ( * result. field. as_ref( ) , -2.718e28 ) ;
2696+ assert_span_eq ( json, result. field . span ( ) , 15 ..24 ) ;
2697+ }
0 commit comments