1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
// use crate::{Obj, Val};

///
/// ## Value Macro
/// Create json::Val enum from any valid json format
///
/// ### examples
// / ```
// / #[macro_use(val, obj, array)]
// / extern crate json;
// /
// / use json::{Val, Obj};
// /
// / let str = val!("some string");
// / let num = val!(45);
// / let bool = val!(true);
// / let null = val!(null);
// / let array = val!([
// /     "string",
// /     45,
// /     null,
// /     [{key: "val"}, undefined]
// / ]);
// /
// / let json = val!({
// /   key:"string",
// /   num:45
// / });
// / ```
///
#[macro_export(json_macros)]
macro_rules! val {
    ([]) => (Val::Array(arr![]));
    ({}) => (Val::Obj(obj!{}));
    ([$($tt:tt)*]) => (Val::Array(arr![$($tt)*]));
    (null) => (Val::Null);
    (undefined) => (Val::Undef);
    ({$($tt:tt)*}) => (Val::Obj(obj!{$($tt)*}));
    ($val:expr) => ( Val::from($val));

    // call anther macro with next values rules

    // handle with json value
    // the order is important, the rule should be before the next json rule
    // the reason is for the following value:
    // {
    //     nested: {
    //          nested2: {key:val},
    //          key:v
    //     }
    // }
    //
    // the second rule will catch
    // {
    //     nested2: {key:val},
    //
    // instead of
    //      {
    //          nested2: {key:val},
    //          key:v
    //     }
    (@next ({$($val:tt)*}) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ({$($val)*}));
    );
    //handle with array value
    (@next ([$($val:tt)*]) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ([$($val)*]));
    );

    //handle with array value
    (@next ([$($val:tt)*], $($rest:tt)+) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ([$($val)*]) ($($rest)+));
    );
    //handle with json value
    (@next ({$($val:tt)*}, $($rest:tt)+) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ({$($val)*}) ($($rest)+));
    );
    //handle with null value
    (@next (null, $($rest:tt)+) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* (null) ($($rest)+));
    );
     //handle with undefined value
     (@next (undefined, $($rest:tt)+) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* (undefined) ($($rest)+));
    );
    //handle with expression value
    (@next ($val:expr, $($rest:tt)+) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ($val) ($($rest)+));
    );

      // catch the last value
    //handle with json value
    (@next ({$($val:tt)*}) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ({$($val)*}));
    );
    //handle with null value
    (@next (null) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* (null));
    );
    //handle with undefined value
    (@next (undefined) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* (undefined));
    );
    //handle with expression value
    (@next ($val:expr) ($($next:tt)+) ($($args:tt)+)) => (
        $($next)*($($args)* ($val));
    );




}