diff --git a/src/de.rs b/src/de.rs index 9500172..c51f77c 100644 --- a/src/de.rs +++ b/src/de.rs @@ -111,7 +111,7 @@ impl<'a> Decoder<'a> { FALSE_TAG => Ok(Value::Bool(false)), STRING_TAG => { let offset = jentry.length as usize; - let s = std::str::from_utf8(&self.buf[..offset]).unwrap(); + let s = unsafe { std::str::from_utf8_unchecked(&self.buf[..offset]) }; self.buf = &self.buf[offset..]; Ok(Value::String(Cow::Borrowed(s))) } diff --git a/src/functions.rs b/src/functions.rs index ff7113e..2b002e2 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -792,10 +792,16 @@ pub fn as_str(value: &[u8]) -> Option> { pub fn to_str(value: &[u8]) -> Result { if let Some(v) = as_str(value) { return Ok(v.to_string()); - } else if is_null(value) { - return Err(Error::InvalidCast); + } else if let Some(v) = as_bool(value) { + if v { + return Ok("true".to_string()); + } else { + return Ok("false".to_string()); + } + } else if let Some(v) = as_number(value) { + return Ok(format!("{}", v)); } - Ok(to_string(value)) + Err(Error::InvalidCast) } /// Returns true if the `JSONB` is An Array. Returns false otherwise. @@ -878,9 +884,7 @@ fn container_to_string(value: &[u8], offset: &mut usize, json: &mut String) { json.push(','); } let key = keys.pop_front().unwrap(); - json.push('\"'); - json.push_str(key); - json.push('\"'); + json.extend(format!("{:?}", key).chars()); json.push(':'); scalar_to_string(value, &mut jentry_offset, &mut value_offset, json); } @@ -911,9 +915,7 @@ fn scalar_to_string( let val = unsafe { std::str::from_utf8_unchecked(&value[*value_offset..*value_offset + length]) }; - json.push('\"'); - json.push_str(val); - json.push('\"'); + json.extend(format!("{:?}", val).chars()); } CONTAINER_TAG => { container_to_string(value, value_offset, json); diff --git a/src/value.rs b/src/value.rs index b895be8..69959ef 100644 --- a/src/value.rs +++ b/src/value.rs @@ -69,9 +69,7 @@ impl<'a> Display for Value<'a> { } Value::Number(ref v) => write!(f, "{}", v), Value::String(ref v) => { - write!(f, "\"")?; - write!(f, "{v}")?; - write!(f, "\"") + write!(f, "{:?}", v) } Value::Array(ref vs) => { let mut first = true; diff --git a/tests/it/functions.rs b/tests/it/functions.rs index af2ffed..63f4d57 100644 --- a/tests/it/functions.rs +++ b/tests/it/functions.rs @@ -654,26 +654,31 @@ fn test_to_type() { #[test] fn test_to_string() { let sources = vec![ - r#"null"#, - r#"true"#, - r#"false"#, - r#"1234567"#, - r#"-1234567"#, - r#"123.4567"#, - r#""abcdef""#, - r#"[1,2,3,4]"#, - r#"["a","b",true,false,[1,2,3],{"a":"b"}]"#, - r#"{"k1":"v1","k2":[1,2,3],"k3":{"a":"b"}}"#, + (r#"null"#, r#"null"#), + (r#"true"#, r#"true"#), + (r#"false"#, r#"false"#), + (r#"1234567"#, r#"1234567"#), + (r#"-1234567"#, r#"-1234567"#), + (r#"123.4567"#, r#"123.4567"#), + (r#""abcdef""#, r#""abcdef""#), + (r#""ab\n\"\uD83D\uDC8E测试""#, r#""ab\n\"💎测试""#), + (r#"[1,2,3,4]"#, r#"[1,2,3,4]"#), + ( + r#"["a","b",true,false,[1,2,3],{"a":"b"}]"#, + r#"["a","b",true,false,[1,2,3],{"a":"b"}]"#, + ), + ( + r#"{"k1":"v1","k2":[1,2,3],"k3":{"a":"b"}}"#, + r#"{"k1":"v1","k2":[1,2,3],"k3":{"a":"b"}}"#, + ), ]; let mut buf: Vec = Vec::new(); - for s in sources { - let res = to_string(s.as_bytes()); - assert_eq!(res, s.to_string()); - + for (s, expect) in sources { let value = parse_value(s.as_bytes()).unwrap(); + assert_eq!(format!("{}", value), expect); value.write_to_vec(&mut buf); let res = to_string(&buf); - assert_eq!(res, s.to_string()); + assert_eq!(res, expect); buf.clear(); } }