1+ use itertools:: Itertools as _;
2+ use serde:: { Deserialize , Serialize } ;
13use serde_json:: Value ;
2- use serde:: { Serialize , Deserialize } ;
3- use std:: fmt;
44use std:: borrow:: Borrow ;
5- use itertools :: Itertools as _ ;
5+ use std :: fmt ;
66
77/// Prerenedered json.
88///
@@ -24,14 +24,17 @@ impl SortedJson {
2424 }
2525
2626 /// Serializes and sorts
27- pub ( crate ) fn array < T : Borrow < SortedJson > , I : IntoIterator < Item =T > > ( items : I ) -> Self {
28- let items = items. into_iter ( )
27+ pub ( crate ) fn array < T : Borrow < SortedJson > , I : IntoIterator < Item = T > > ( items : I ) -> Self {
28+ let items = items
29+ . into_iter ( )
2930 . sorted_unstable_by ( |a, b| a. borrow ( ) . cmp ( & b. borrow ( ) ) )
3031 . format_with ( "," , |item, f| f ( item. borrow ( ) ) ) ;
3132 SortedJson ( format ! ( "[{}]" , items) )
3233 }
3334
34- pub ( crate ) fn array_unsorted < T : Borrow < SortedJson > , I : IntoIterator < Item =T > > ( items : I ) -> Self {
35+ pub ( crate ) fn array_unsorted < T : Borrow < SortedJson > , I : IntoIterator < Item = T > > (
36+ items : I ,
37+ ) -> Self {
3538 let items = items. into_iter ( ) . format_with ( "," , |item, f| f ( item. borrow ( ) ) ) ;
3639 SortedJson ( format ! ( "[{items}]" ) )
3740 }
@@ -55,6 +58,29 @@ impl From<SortedJson> for Value {
5558 }
5659}
5760
61+ /// For use in JSON.parse('{...}').
62+ ///
63+ /// JSON.parse supposedly loads faster than raw JS source,
64+ /// so this is used for large objects.
65+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
66+ pub ( crate ) struct EscapedJson ( SortedJson ) ;
67+
68+ impl From < SortedJson > for EscapedJson {
69+ fn from ( json : SortedJson ) -> Self {
70+ EscapedJson ( json)
71+ }
72+ }
73+
74+ impl fmt:: Display for EscapedJson {
75+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
76+ // All these `replace` calls are because we have to go through JS string
77+ // for JSON content.
78+ // We need to escape double quotes for the JSON
79+ let json = self . 0 . 0 . replace ( '\\' , r"\\" ) . replace ( '\'' , r"\'" ) . replace ( "\\ \" " , "\\ \\ \" " ) ;
80+ write ! ( f, "{}" , json)
81+ }
82+ }
83+
5884#[ cfg( test) ]
5985mod tests {
6086 use super :: * ;
@@ -76,6 +102,48 @@ mod tests {
76102 assert_eq ! ( serde_json:: to_string( & json) . unwrap( ) , serialized) ;
77103 }
78104
105+ #[ test]
106+ fn escape_json_number ( ) {
107+ let json = SortedJson :: serialize ( 3 ) ;
108+ let json = EscapedJson :: from ( json) ;
109+ assert_eq ! ( format!( "{json}" ) , "3" ) ;
110+ }
111+
112+ #[ test]
113+ fn escape_json_single_quote ( ) {
114+ let json = SortedJson :: serialize ( "he's" ) ;
115+ let json = EscapedJson :: from ( json) ;
116+ assert_eq ! ( dbg!( format!( "{json}" ) ) , r#""he\'s""# ) ;
117+ }
118+
119+ #[ test]
120+ fn escape_json_array ( ) {
121+ let json = SortedJson :: serialize ( [ 1 , 2 , 3 ] ) ;
122+ let json = EscapedJson :: from ( json) ;
123+ assert_eq ! ( dbg!( format!( "{json}" ) ) , r#"[1,2,3]"# ) ;
124+ }
125+
126+ #[ test]
127+ fn escape_json_string ( ) {
128+ let json = SortedJson :: serialize ( r#"he"llo"# ) ;
129+ let json = EscapedJson :: from ( json) ;
130+ assert_eq ! ( dbg!( format!( "{json}" ) ) , r#""he\\\"llo""# ) ;
131+ }
132+
133+ #[ test]
134+ fn escape_json_string_escaped ( ) {
135+ let json = SortedJson :: serialize ( r#"he\"llo"# ) ;
136+ let json = EscapedJson :: from ( json) ;
137+ assert_eq ! ( format!( "{json}" ) , r#""he\\\\\\\"llo""# ) ;
138+ }
139+
140+ #[ test]
141+ fn escape_json_string_escaped_escaped ( ) {
142+ let json = SortedJson :: serialize ( r#"he\\"llo"# ) ;
143+ let json = EscapedJson :: from ( json) ;
144+ assert_eq ! ( format!( "{json}" ) , r#""he\\\\\\\\\\\"llo""# ) ;
145+ }
146+
79147 #[ test]
80148 fn number ( ) {
81149 let json = SortedJson :: serialize ( 3 ) ;
@@ -100,7 +168,7 @@ mod tests {
100168 #[ test]
101169 fn serialize_array ( ) {
102170 let json = SortedJson :: serialize ( [ 3 , 1 , 2 ] ) ;
103- let serialized = "[3,1,2]" ;
171+ let serialized = "[3,1,2]" ;
104172 check ( json, serialized) ;
105173 }
106174
0 commit comments