1
+ use itertools:: Itertools as _;
2
+ use serde:: { Deserialize , Serialize } ;
1
3
use serde_json:: Value ;
2
- use serde:: { Serialize , Deserialize } ;
3
- use std:: fmt;
4
4
use std:: borrow:: Borrow ;
5
- use itertools :: Itertools as _ ;
5
+ use std :: fmt ;
6
6
7
7
/// Prerenedered json.
8
8
///
@@ -24,14 +24,17 @@ impl SortedJson {
24
24
}
25
25
26
26
/// 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 ( )
29
30
. sorted_unstable_by ( |a, b| a. borrow ( ) . cmp ( & b. borrow ( ) ) )
30
31
. format_with ( "," , |item, f| f ( item. borrow ( ) ) ) ;
31
32
SortedJson ( format ! ( "[{}]" , items) )
32
33
}
33
34
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 {
35
38
let items = items. into_iter ( ) . format_with ( "," , |item, f| f ( item. borrow ( ) ) ) ;
36
39
SortedJson ( format ! ( "[{items}]" ) )
37
40
}
@@ -55,6 +58,29 @@ impl From<SortedJson> for Value {
55
58
}
56
59
}
57
60
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
+
58
84
#[ cfg( test) ]
59
85
mod tests {
60
86
use super :: * ;
@@ -76,6 +102,48 @@ mod tests {
76
102
assert_eq ! ( serde_json:: to_string( & json) . unwrap( ) , serialized) ;
77
103
}
78
104
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
+
79
147
#[ test]
80
148
fn number ( ) {
81
149
let json = SortedJson :: serialize ( 3 ) ;
@@ -100,7 +168,7 @@ mod tests {
100
168
#[ test]
101
169
fn serialize_array ( ) {
102
170
let json = SortedJson :: serialize ( [ 3 , 1 , 2 ] ) ;
103
- let serialized = "[3,1,2]" ;
171
+ let serialized = "[3,1,2]" ;
104
172
check ( json, serialized) ;
105
173
}
106
174
0 commit comments