2 use serde_json
::value
::{to_value, Value as Json}
;
4 pub(crate) static DEFAULT_VALUE
: Json
= Json
::Null
;
6 /// A JSON wrapper designed for handlebars internal use case
8 /// * Constant: the JSON value hardcoded into template
9 /// * Context: the JSON value referenced in your provided data context
10 /// * Derived: the owned JSON value computed during rendering process
13 pub enum ScopedJson
<'reg
: 'rc
, 'rc
> {
16 // represents a json reference to context value, its full path
17 Context(&'rc Json
, Vec
<String
>),
21 impl<'reg
: 'rc
, 'rc
> ScopedJson
<'reg
, 'rc
> {
22 /// get the JSON reference
23 pub fn as_json(&self) -> &Json
{
25 ScopedJson
::Constant(j
) => j
,
26 ScopedJson
::Derived(ref j
) => j
,
27 ScopedJson
::Context(j
, _
) => j
,
32 pub fn render(&self) -> String
{
33 self.as_json().render()
36 pub fn is_missing(&self) -> bool
{
38 ScopedJson
::Missing
=> true,
43 pub fn into_derived(self) -> ScopedJson
<'reg
, 'rc
> {
44 let v
= self.as_json();
45 ScopedJson
::Derived(v
.clone())
48 pub fn context_path(&self) -> Option
<&Vec
<String
>> {
50 ScopedJson
::Context(_
, ref p
) => Some(p
),
56 impl<'reg
: 'rc
, 'rc
> From
<Json
> for ScopedJson
<'reg
, 'rc
> {
57 fn from(v
: Json
) -> ScopedJson
<'reg
, 'rc
> {
58 ScopedJson
::Derived(v
)
62 /// Json wrapper that holds the Json value and reference path information
65 pub struct PathAndJson
<'reg
, 'rc
> {
66 relative_path
: Option
<String
>,
67 value
: ScopedJson
<'reg
, 'rc
>,
70 impl<'reg
: 'rc
, 'rc
> PathAndJson
<'reg
, 'rc
> {
72 relative_path
: Option
<String
>,
73 value
: ScopedJson
<'reg
, 'rc
>,
74 ) -> PathAndJson
<'reg
, 'rc
> {
81 /// Returns relative path when the value is referenced
82 /// If the value is from a literal, the path is `None`
83 pub fn relative_path(&self) -> Option
<&String
> {
84 self.relative_path
.as_ref()
87 /// Returns full path to this value if any
88 pub fn context_path(&self) -> Option
<&Vec
<String
>> {
89 self.value
.context_path()
93 pub fn value(&self) -> &Json
{
97 /// Test if value is missing
98 pub fn is_value_missing(&self) -> bool
{
99 self.value
.is_missing()
102 pub fn render(&self) -> String
{
107 /// Render Json data with default format
108 pub trait JsonRender
{
109 fn render(&self) -> String
;
112 pub trait JsonTruthy
{
113 fn is_truthy(&self, include_zero
: bool
) -> bool
;
116 impl JsonRender
for Json
{
117 fn render(&self) -> String
{
119 Json
::String(ref s
) => s
.to_string(),
120 Json
::Bool(i
) => i
.to_string(),
121 Json
::Number(ref n
) => n
.to_string(),
122 Json
::Null
=> "".to_owned(),
123 Json
::Array(ref a
) => {
124 let mut buf
= String
::new();
127 buf
.push_str(i
.render().as_ref());
133 Json
::Object(_
) => "[object]".to_owned(),
138 /// Convert any serializable data into Serde Json type
139 pub fn to_json
<T
>(src
: T
) -> Json
143 to_value(src
).unwrap_or_default()
146 pub fn as_string(src
: &Json
) -> Option
<&str> {
150 impl JsonTruthy
for Json
{
151 fn is_truthy(&self, include_zero
: bool
) -> bool
{
153 Json
::Bool(ref i
) => *i
,
154 Json
::Number(ref n
) => {
156 n
.as_f64().map(|f
| !f
.is_nan()).unwrap_or(false)
158 // there is no inifity in json/serde_json
159 n
.as_f64().map(|f
| f
.is_normal()).unwrap_or(false)
163 Json
::String(ref i
) => !i
.is_empty(),
164 Json
::Array(ref i
) => !i
.is_empty(),
165 Json
::Object(ref i
) => !i
.is_empty(),
171 fn test_json_render() {
172 let raw
= "<p>Hello world</p>\n<p thing=\"hello\"</p>";
173 let thing
= Json
::String(raw
.to_string());
175 assert_eq
!(raw
, thing
.render());
179 fn test_json_number_truthy() {
181 assert
!(json
!(16i16).is_truthy(false));
182 assert
!(json
!(16i16).is_truthy(true));
184 assert
!(json
!(0i16).is_truthy(true));
185 assert
!(!json
!(0i16).is_truthy(false));
187 assert
!(json
!(1.0f64).is_truthy(false));
188 assert
!(json
!(1.0f64).is_truthy(true));
190 assert
!(json
!(Some(16i16)).is_truthy(false));
191 assert
!(json
!(Some(16i16)).is_truthy(true));
193 assert
!(!json
!(None
as Option
<i16>).is_truthy(false));
194 assert
!(!json
!(None
as Option
<i16>).is_truthy(true));
196 assert
!(!json
!(f64::NAN
).is_truthy(false));
197 assert
!(!json
!(f64::NAN
).is_truthy(true));
199 // there is no infinity in json/serde_json
200 // assert!(json!(f64::INFINITY).is_truthy(false));
201 // assert!(json!(f64::INFINITY).is_truthy(true));
203 // assert!(json!(f64::NEG_INFINITY).is_truthy(false));
204 // assert!(json!(f64::NEG_INFINITY).is_truthy(true));