Skip to content

Commit

Permalink
Web.JSON: Obsolute constants true, false and null.
Browse files Browse the repository at this point in the history
  • Loading branch information
Milly committed Nov 11, 2019
1 parent 7dcd77d commit 38d8f09
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 82 deletions.
45 changes: 5 additions & 40 deletions autoload/vital/__vital__/Web/JSON.vim
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,13 @@ let s:control_chars = {
lockvar s:float_constants s:float_nan s:float_inf
lockvar s:special_constants s:control_chars

function! s:_true() abort
return v:true
endfunction

function! s:_false() abort
return v:false
endfunction

function! s:_null() abort
return v:null
endfunction

function! s:_resolve(val, prefix) abort
let t = type(a:val)
if t == type('')
let m = matchlist(a:val, '^' . a:prefix . '\(null\|true\|false\)$')
if !empty(m)
return s:const[m[1]]
endif
elseif t == type([]) || t == type({})
return map(a:val, 's:_resolve(v:val, a:prefix)')
endif
return a:val
endfunction

function! s:_vital_created(module) abort
" define constant variables
if !exists('s:const')
let s:const = {}
let s:const.true = function('s:_true')
let s:const.false = function('s:_false')
let s:const.null = function('s:_null')
let s:const.true = v:true
let s:const.false = v:false
let s:const.null = v:null
lockvar s:const
endif
call extend(a:module, s:const)
Expand All @@ -107,7 +82,6 @@ endfunction
" @vimlint(EVL102, 1, l:Infinity)
function! s:decode(json, ...) abort
let settings = extend({
\ 'use_token': 0,
\ 'allow_nan': 1,
\}, get(a:000, 0, {}))
let json = iconv(a:json, 'utf-8', &encoding)
Expand All @@ -121,17 +95,8 @@ function! s:decode(json, ...) abort
if settings.allow_nan
let [NaN,Infinity] = [s:float_nan,s:float_inf]
endif
if settings.use_token
let prefix = '__Web.JSON__'
while stridx(json, prefix) != -1
let prefix .= '_'
endwhile
let [null,true,false] = [prefix.'null',prefix.'true',prefix.'false']
sandbox return s:_resolve(eval(json), prefix)
else
let [null,true,false] = [s:const.null(),s:const.true(),s:const.false()]
sandbox return eval(json)
endif
let [null, true, false] = [v:null, v:true, v:false]
sandbox return eval(json)
endfunction
" @vimlint(EVL102, 0, l:null)
" @vimlint(EVL102, 0, l:true)
Expand Down
54 changes: 24 additions & 30 deletions doc/vital/Web/JSON.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,39 @@ INTERFACE *Vital.Web.JSON-interface*
CONSTS *Vital.Web.JSON-consts*

true *Vital.Web.JSON.true*
It is used to indicate 'true' in JSON string. It is represented as a
|Funcref| thus if you assign the value to a variable which name does not
start with a capital, "s:", "w:", "t:" or "b:" will raise an exception.
This returns 1 when you use it as a function.
It is |v:true|. This is left for backward compatibility.

false *Vital.Web.JSON.false*
It is used to indicate 'false' in JSON string. It is represented as a
|Funcref| thus if you assign the value to a variable which name does not
start with a capital, "s:", "w:", "t:" or "b:" will raise an exception.
This returns 0 when you use it as a function.
It is |v:false|. This is left for backward compatibility.

null *Vital.Web.JSON.null*
It is used to indicate 'null' in JSON string. It is represented as a
|Funcref| thus if you assign the value to a variable which name does not
start with a capital, "s:", "w:", "t:" or "b:" will raise an exception.
This returns 0 when you use it as a function.
It is |v:null|. This is left for backward compatibility.

------------------------------------------------------------------------------
FUNCTIONS *Vital.Web.JSON-functions*

encode({object}[, {settings}]) *Vital.Web.JSON.encode()*
Encode an object into a JSON string. Special tokens
(e.g. |Vital.Web.JSON.true|) are encoded into corresponding javascript
tokens (e.g. 'true').
>
echo s:JSON.encode([s:JSON.true, s:JSON.false, s:JSON.null])
" => '[true, false, null]'
<
Encode an object into a JSON string.
Vim values are converted as follows:
|Number| decimal number
|Float| floating point number
Float nan "NaN"
Float inf "Infinity"
Float -inf "-Infinity"
|String| in double quotes (possibly null)
|List| as an array (possibly null); when
used recursively: []
|Dict| as an object (possibly null); when
used recursively: {}
|Blob| as an array of the individual bytes
v:false "false"
v:true "true"
v:none "null"
v:null "null"
|Funcref| not possible, error
|job| not possible, error
|channel| not possible, error

{settings} is a |Dictionary| which allows the following:

'indent'
Expand Down Expand Up @@ -94,17 +99,6 @@ decode({json}[, {settings}]) *Vital.Web.JSON.decode()*
Decode a JSON string into an object that vim can treat.
{settings} is a |Dictionary| which allows the following:

'use_token'
Use special tokens (e.g. |Vital.Web.JSON.true|) to represent
corresponding javascript tokens (e.g. 'true').
Otherwise |v:true|, |v:false| or |v:null| are used to represent these.
The default value is 0.
>
echo s:JSON.decode('[true, false, null]')
" => [1, 0, 0]
echo s:JSON.decode('[true, false, null]', {'use_token': 1})
" => [s:JSON.true, s:JSON.false, s:JSON.null]
<
'allow_nan'
If 'allows_nan' is 0, it will raise an exception when deserializing
float constants ('NaN', 'Infinity', '-Infinity').
Expand Down
15 changes: 3 additions & 12 deletions test/Web/JSON.vimspec
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Describe Web.JSON

Describe .constants()
It should have constant variables which indicate the special tokens
Assert Match(string(JSON.true), "function('\.*_true')")
Assert Match(string(JSON.false), "function('\.*_false')")
Assert Match(string(JSON.null), "function('\.*_null')")
Assert Same(JSON.true, v:true)
Assert Same(JSON.false, v:false)
Assert Same(JSON.null, v:null)
End
End

Expand Down Expand Up @@ -85,18 +85,9 @@ Describe Web.JSON
End

It decodes special tokens (true/false/null)
" true/false/null
Assert Equals(JSON.decode('true'), 1)
Assert Equals(JSON.decode('false'), 0)
Assert Equals(JSON.decode('null'), 0)
Assert Same(JSON.decode('true'), v:true)
Assert Same(JSON.decode('false'), v:false)
Assert Same(JSON.decode('null'), v:null)

let s = { 'use_token': 1 }
Assert Equals(JSON.decode('true', s), JSON.true)
Assert Equals(JSON.decode('false', s), JSON.false)
Assert Equals(JSON.decode('null', s), JSON.null)
End

It decodes special floats (NaN/Infinity/-Infinity)
Expand Down

0 comments on commit 38d8f09

Please sign in to comment.