summaryrefslogtreecommitdiffstats
path: root/autoload/vital/_crystal/Web/JSON.vim
diff options
context:
space:
mode:
Diffstat (limited to 'autoload/vital/_crystal/Web/JSON.vim')
-rw-r--r--autoload/vital/_crystal/Web/JSON.vim112
1 files changed, 112 insertions, 0 deletions
diff --git a/autoload/vital/_crystal/Web/JSON.vim b/autoload/vital/_crystal/Web/JSON.vim
new file mode 100644
index 00000000..0e42ee0d
--- /dev/null
+++ b/autoload/vital/_crystal/Web/JSON.vim
@@ -0,0 +1,112 @@
+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