MCPcopy Create free account
hub / github.com/dprint/jsonc-parser / parse_hex_char

Function parse_hex_char

src/string.rs:210–274  ·  view source on GitHub ↗
(chars: &mut T)

Source from the content-addressed store, hash-verified

208}
209
210fn parse_hex_char<'a, T: CharProvider<'a>>(chars: &mut T) -> Result<char, ParseStringErrorKind> {
211 let mut buf1 = [0u8; 4];
212 let hex_value = read_four_hex_digits(chars, &mut buf1)?;
213
214 // check if this is a high surrogate (0xD800-0xDBFF)
215 let hex_char = if (0xD800..=0xDBFF).contains(&hex_value) {
216 // high surrogate - must be followed by low surrogate (\uXXXX)
217 if chars.move_next_char() != Some('\\') {
218 return Err(ParseStringErrorKind::InvalidUnicodeEscapeSequence(format!(
219 "{} (unpaired high surrogate)",
220 hex_buf_to_str(&buf1)
221 )));
222 }
223
224 if chars.move_next_char() != Some('u') {
225 return Err(ParseStringErrorKind::InvalidUnicodeEscapeSequence(format!(
226 "{} (unpaired high surrogate)",
227 hex_buf_to_str(&buf1)
228 )));
229 }
230
231 // parse the second \uXXXX
232 let mut buf2 = [0u8; 4];
233 let hex_value2 = read_four_hex_digits(chars, &mut buf2)?;
234
235 // verify it's a low surrogate (0xDC00-0xDFFF)
236 if !(0xDC00..=0xDFFF).contains(&hex_value2) {
237 return Err(ParseStringErrorKind::InvalidUnicodeEscapeSequence(format!(
238 "{} (high surrogate not followed by low surrogate)",
239 hex_buf_to_str(&buf1)
240 )));
241 }
242
243 // combine surrogate pair using RFC 8259 formula
244 let code_point = ((hex_value - 0xD800) * 0x400) + (hex_value2 - 0xDC00) + 0x10000;
245
246 match std::char::from_u32(code_point) {
247 Some(c) => c,
248 None => {
249 return Err(ParseStringErrorKind::InvalidUnicodeEscapeSequence(format!(
250 "{}\\u{} (invalid surrogate pair)",
251 hex_buf_to_str(&buf1),
252 hex_buf_to_str(&buf2)
253 )));
254 }
255 }
256 } else if (0xDC00..=0xDFFF).contains(&hex_value) {
257 // low surrogate without high surrogate
258 return Err(ParseStringErrorKind::InvalidUnicodeEscapeSequence(format!(
259 "{} (unpaired low surrogate)",
260 hex_buf_to_str(&buf1)
261 )));
262 } else {
263 // normal unicode escape
264 match std::char::from_u32(hex_value) {
265 Some(hex_char) => hex_char,
266 None => {
267 return Err(ParseStringErrorKind::InvalidUnicodeEscapeSequence(hex_buf_to_str(

Callers 1

Calls 3

read_four_hex_digitsFunction · 0.85
hex_buf_to_strFunction · 0.85
move_next_charMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…