Skip to content

Commit 1cf2235

Browse files
committed
Web.JSON: Convert encoding. Add 'from_encoding' setting to encode().
1 parent 34afccc commit 1cf2235

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed

autoload/vital/__vital__/Web/JSON.vim

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,19 @@ function! s:encode(val, ...) abort
145145
let settings = extend({
146146
\ 'indent': 0,
147147
\ 'allow_nan': 1,
148+
\ 'from_encoding': &encoding,
148149
\}, get(a:000, 0, {})
149150
\)
151+
return s:_encode(a:val, settings)
152+
endfunction
153+
154+
function! s:_encode(val, settings) abort
150155
let t = type(a:val)
151156
if t == 0
152157
return a:val
153158
elseif t == 1
154-
let s = substitute(a:val, '[\x01-\x1f\\"]', '\=s:control_chars[submatch(0)]', 'g')
155-
let s = iconv(s, &encoding, 'utf-8')
159+
let s = iconv(a:val, a:settings.from_encoding, 'utf-8')
160+
let s = substitute(s, '[\x01-\x1f\\"]', '\=s:control_chars[submatch(0)]', 'g')
156161
return '"' . s . '"'
157162
elseif t == 2
158163
if s:const.true == a:val
@@ -166,12 +171,12 @@ function! s:encode(val, ...) abort
166171
return string(a:val)
167172
endif
168173
elseif t == 3
169-
return s:_encode_list(a:val, settings)
174+
return s:_encode_list(a:val, a:settings)
170175
elseif t == 4
171-
return s:_encode_dict(a:val, settings)
176+
return s:_encode_dict(a:val, a:settings)
172177
elseif t == 5
173178
let val = string(a:val)
174-
if settings.allow_nan
179+
if a:settings.allow_nan
175180
let val = get(s:float_constants, val, val)
176181
elseif has_key(s:float_constants, val)
177182
throw 'vital: Web.JSON: Invalid float value: ' . val
@@ -189,7 +194,7 @@ function! s:_encode_list(val, settings) abort
189194
if empty(a:val)
190195
return '[]'
191196
elseif !a:settings.indent
192-
let encoded_candidates = map(copy(a:val), 's:encode(v:val, a:settings)')
197+
let encoded_candidates = map(copy(a:val), 's:_encode(v:val, a:settings)')
193198
return printf('[%s]', join(encoded_candidates, ','))
194199
else
195200
let previous_indent = get(a:settings, '_previous_indent')
@@ -199,7 +204,7 @@ function! s:_encode_list(val, settings) abort
199204
\})
200205
let encoded_candidates = map(
201206
\ copy(a:val),
202-
\ printf('''%s'' . s:encode(v:val, ns)', repeat(' ', indent)),
207+
\ printf('''%s'' . s:_encode(v:val, ns)', repeat(' ', indent)),
203208
\)
204209
return printf(
205210
\ "[\n%s\n%s]",
@@ -216,7 +221,7 @@ function! s:_encode_dict(val, settings) abort
216221
return '{}'
217222
elseif !a:settings.indent
218223
let encoded_candidates = map(keys(a:val),
219-
\ 's:encode(v:val, a:settings) . '':'' . s:encode(a:val[v:val], a:settings)'
224+
\ 's:_encode(v:val, a:settings) . '':'' . s:_encode(a:val[v:val], a:settings)'
220225
\)
221226
return printf('{%s}', join(encoded_candidates, ','))
222227
else
@@ -227,7 +232,7 @@ function! s:_encode_dict(val, settings) abort
227232
\})
228233
let encoded_candidates = map(keys(a:val),
229234
\ printf(
230-
\ '''%s'' . s:encode(v:val, ns) . '': '' . s:encode(a:val[v:val], ns)',
235+
\ '''%s'' . s:_encode(v:val, ns) . '': '' . s:_encode(a:val[v:val], ns)',
231236
\ repeat(' ', indent),
232237
\ ),
233238
\)

test/Web/JSON.vimspec

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ Describe Web.JSON
4242
Assert Equals(JSON.decode('"\ud83c\u00a0"'), "\ud83c\u00a0")
4343
End
4444

45+
It decodes strings with character encoding
46+
let expected_utf8 = "sあc漢g"
47+
Assert Equals(JSON.decode('"sあc漢g"'), expected_utf8)
48+
49+
let expected_sjis = iconv("sあc漢g", 'utf-8', 'sjis')
50+
try
51+
let &encoding = 'sjis'
52+
let res = JSON.decode('"sあc漢g"')
53+
finally
54+
let &encoding = 'utf-8'
55+
endtry
56+
Assert Equals(res, expected_sjis)
57+
End
58+
4559
It decodes lists
4660
Assert Equals(JSON.decode('[]'), [])
4761
Assert Equals(JSON.decode('[0, 1, 2]'), [0, 1, 2])
@@ -126,6 +140,23 @@ Describe Web.JSON
126140
Assert Equals(JSON.encode("\xf0\x9f\x8d\xa3"), "\"\xf0\x9f\x8d\xa3\"")
127141
End
128142

143+
It encodes strings with character encoding
144+
let str_utf8 = "sあc漢g"
145+
Assert Equals(JSON.encode(str_utf8), '"sあc漢g"')
146+
147+
let str_sjis = iconv("sあc漢g", 'utf-8', 'sjis')
148+
try
149+
let &encoding = 'sjis'
150+
let res = JSON.encode(str_sjis)
151+
finally
152+
let &encoding = 'utf-8'
153+
endtry
154+
Assert Equals(res, '"sあc漢g"')
155+
156+
let s = { 'from_encoding': 'sjis' }
157+
Assert Equals(JSON.encode(str_sjis, s), '"sあc漢g"')
158+
End
159+
129160
It encodes lists
130161
Assert Equals(JSON.encode([]), '[]')
131162
Assert Equals(JSON.encode([0, 1, 2]), '[0,1,2]')

0 commit comments

Comments
 (0)