(ctx: &Ctx<'js>, json: T)
| 11 | } |
| 12 | |
| 13 | pub fn json_parse<'js, T: Into<Vec<u8>>>(ctx: &Ctx<'js>, json: T) -> Result<Value<'js>> { |
| 14 | let mut json: Vec<u8> = json.into(); |
| 15 | let tape = match simd_json::to_tape(&mut json) { |
| 16 | Ok(tape) => tape, |
| 17 | Err(err) => { |
| 18 | // simd_json is strict about lone / unpaired surrogate escapes |
| 19 | // (`\uXXXX` where XXXX is a surrogate code point). Fall back to |
| 20 | // QuickJS's native `JSON.parse`, which is more permissive and is |
| 21 | // needed for spec compliance with content that round-trips |
| 22 | // through `JSON.stringify` of strings containing lone surrogates. |
| 23 | if err.character() == Some('u') { |
| 24 | if let Ok(value) = ctx.json_parse(json.as_slice()) { |
| 25 | return Ok(value); |
| 26 | } |
| 27 | } |
| 28 | let mut itoa = itoa::Buffer::new(); |
| 29 | let mut error_msg = String::with_capacity(256); |
| 30 | let json_length = json.len(); |
| 31 | if json_length < 128 { |
| 32 | error_msg.reserve(json_length); |
| 33 | error_msg.push('\"'); |
| 34 | error_msg.push_str(&std::string::String::from_utf8_lossy(&json)); |
| 35 | error_msg.push_str("\" "); |
| 36 | } |
| 37 | |
| 38 | error_msg.push_str("not valid JSON at index "); |
| 39 | error_msg.push_str(itoa.format(err.index())); |
| 40 | if let Some(char) = err.character() { |
| 41 | error_msg.push_str(" ('"); |
| 42 | error_msg.push(char); |
| 43 | error_msg.push_str("')"); |
| 44 | } |
| 45 | return Err(Exception::throw_syntax(ctx, &error_msg)); |
| 46 | }, |
| 47 | }; |
| 48 | let tape = tape.0; |
| 49 | |
| 50 | if let Some(first) = tape.first() { |
| 51 | return match first { |
| 52 | Node::String(value) => value.into_js(ctx), |
| 53 | Node::Static(node) => static_node_to_value(ctx, *node), |
| 54 | _ => parse_node(ctx, &tape, 0).map(|(value, _)| value), |
| 55 | }; |
| 56 | } |
| 57 | |
| 58 | Undefined.into_js(ctx) |
| 59 | } |
| 60 | |
| 61 | #[inline(always)] |
| 62 | fn static_node_to_value<'js>(ctx: &Ctx<'js>, node: StaticNode) -> Result<Value<'js>> { |
no test coverage detected