summaryrefslogblamecommitdiffstats
path: root/autoload/vital/_crystal/Web/JSON.vim
blob: 0e42ee0dac8f6cb14008ada9ff4f533397934997 (plain) (tree)















































































































                                                                                                 
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1
  
let s:save_cpo = &cpo
set cpo&vim

function! s:_true() abort
  return 1
endfunction

function! s:_false() abort
  return 0
endfunction

function! s:_null() abort
  return 0
endfunction

let s:const = {}
let s:const.true = function('s:_true')
let s:const.false = function('s:_false')
let s:const.null = function('s:_null')

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
  call extend(a:module, s:const)
endfunction

function! s:_vital_loaded(V) abort
  let s:V = a:V
  let s:string = s:V.import('Data.String')
endfunction

function! s:_vital_depends() abort
  return ['Data.String']
endfunction

" @vimlint(EVL102, 1, l:null)
" @vimlint(EVL102, 1, l:true)
" @vimlint(EVL102, 1, l:false)
function! s:decode(json, ...) abort
  let settings = extend({
        \ 'use_token': 0,
        \}, get(a:000, 0, {}))
  let json = iconv(a:json, "utf-8", &encoding)
  let json = join(split(json, "\n"), '')
  let json = substitute(json, '\\u34;', '\\"', 'g')
  let json = substitute(json, '\\u\(\x\x\x\x\)', '\=s:string.nr2enc_char("0x".submatch(1))', 'g')
  if settings.use_token
    let prefix = '__Web.JSON__'
    while stridx(json, prefix) != -1
      let prefix .= '_'
    endwhile
    let [null,true,false] = map(['null','true','false'], 'prefix . v:val')
    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
endfunction
" @vimlint(EVL102, 0, l:null)
" @vimlint(EVL102, 0, l:true)
" @vimlint(EVL102, 0, l:false)

function! s:encode(val) abort
  if type(a:val) == 0
    return a:val
  elseif type(a:val) == 1
    let json = '"' . escape(a:val, '\"') . '"'
    let json = substitute(json, "\r", '\\r', 'g')
    let json = substitute(json, "\n", '\\n', 'g')
    let json = substitute(json, "\t", '\\t', 'g')
    return iconv(json, &encoding, "utf-8")
  elseif type(a:val) == 2
    if s:const.true == a:val
      return 'true'
    elseif s:const.false == a:val
      return 'false'
    elseif s:const.null == a:val
      return 'null'
    else
      " backward compatibility
      return string(a:val)
    endif
  elseif type(a:val) == 3
    return '[' . join(map(copy(a:val), 's:encode(v:val)'), ',') . ']'
  elseif type(a:val) == 4
    return '{' . join(map(keys(a:val), 's:encode(v:val).":".s:encode(a:val[v:val])'), ',') . '}'
  else
    return string(a:val)
  endif
endfunction

let &cpo = s:save_cpo
unlet s:save_cpo

" vim:set et ts=2 sts=2 sw=2 tw=0:

endif