Skip to content

Commit

Permalink
read simple strings
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa committed Apr 6, 2024
1 parent 193331c commit f014d55
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 20 deletions.
44 changes: 38 additions & 6 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,39 @@ where
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// Represents the different element types in the JSONB format.
pub enum ElementType {
/// The element is a JSON "null".
Null,
/// The element is a JSON "true".
True,
/// The element is a JSON "false".
False,
/// The element is a JSON integer value in the canonical RFC 8259 format.
Int,
/// The element is a JSON integer value that is not in the canonical format.
Int5,
/// The element is a JSON floating-point value in the canonical RFC 8259 format.
Float,
/// The element is a JSON floating-point value that is not in the canonical format.
Float5,
/// The element is a JSON string value that does not contain any escapes.
Text,
/// The element is a JSON string value that contains RFC 8259 character escapes.
TextJ,
/// The element is a JSON string value that contains character escapes, including some from JSON5.
Text5,
/// The element is a JSON string value that contains UTF8 characters that need to be escaped.
TextRaw,
/// The element is a JSON array.
Array,
/// The element is a JSON object.
Object,
/// Reserved for future expansion.
Reserved13,
/// Reserved for future expansion.
Reserved14,
/// Reserved for future expansion.
Reserved15,
}

Expand Down Expand Up @@ -136,11 +153,10 @@ impl<R: Read> Deserializer<R> {
})
}

fn read_header_with_payload(&mut self) -> Result<(ElementType, Vec<u8>)> {
let header = self.read_header()?;
fn read_payload(&mut self, header: Header) -> Result<Vec<u8>> {
let mut buf = vec![0; header.payload_size];
self.reader.read_exact(&mut buf)?;
Ok((header.element_type, buf))
Ok(buf)
}

fn drop_payload(&mut self, header: Header) -> Result<ElementType> {
Expand Down Expand Up @@ -203,6 +219,16 @@ impl<R: Read> Deserializer<R> {
t => Err(Error::UnexpectedType(t)),
}
}

fn read_string(&mut self, header: Header) -> Result<String> {
let body = self.read_payload(header)?;
match header.element_type {
ElementType::Text => Ok(String::from_utf8(body)?),
ElementType::TextJ => todo!("json str"),
ElementType::Text5 => todo!("json5 str"),
t => Err(Error::UnexpectedType(t)),
}
}
}

fn usize_conversion(e: std::num::TryFromIntError) -> Error {
Expand Down Expand Up @@ -442,14 +468,15 @@ impl<'de, 'a, R: Read> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: Visitor<'de>,
{
todo!()
todo!("Borrowed string deserialization is not supported")
}

fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value>
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
todo!()
let header = self.read_header()?;
visitor.visit_string(self.read_string(header)?)
}

fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
Expand Down Expand Up @@ -569,4 +596,9 @@ mod tests {
from_bytes::<()>(b"\x00").unwrap();
assert_eq!(from_bytes::<Option<u64>>(b"\x00").unwrap(), None);
}

#[test]
fn test_string() {
assert_eq!(from_bytes::<String>(b"\x57hello").unwrap(), "hello");
}
}
24 changes: 12 additions & 12 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use serde::{de, ser};
use std::fmt::{self, Display};

Expand All @@ -23,6 +15,7 @@ pub enum Error {
UnexpectedType(ElementType),
Io(std::io::Error),
TrailingCharacters,
Utf8(std::string::FromUtf8Error),
}

impl ser::Error for Error {
Expand All @@ -41,16 +34,17 @@ impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Message(m) => write!(f, "{}", m),
Error::JsonError(e) => write!(f, "json error: {}", e),
Error::Json5Error(e) => write!(f, "json5 error: {}", e),
Error::JsonError(_) => write!(f, "json error"),
Error::Json5Error(_) => write!(f, "json5 error"),
Error::InvalidElementType(t) => {
write!(f, "{t} is not a valid jsonb element type code")
}
Error::UnexpectedType(t) => write!(f, "unexpected type: {t:?}"),
Error::Io(e) => write!(f, "io error: {}", e),
Error::Io(_) => write!(f, "io error"),
Error::TrailingCharacters => {
write!(f, "trailing data after the end of the jsonb value")
}
Error::Utf8(_) => write!(f, "invalid utf8 in string"),
}
}
}
Expand All @@ -61,6 +55,7 @@ impl std::error::Error for Error {
Error::JsonError(e) => Some(e),
Error::Json5Error(e) => Some(e),
Error::Io(e) => Some(e),
Error::Utf8(e) => Some(e),
_ => None,
}
}
Expand All @@ -72,14 +67,19 @@ impl From<std::io::Error> for Error {
}
}

impl From<std::string::FromUtf8Error> for Error {
fn from(err: std::string::FromUtf8Error) -> Self {
Error::Utf8(err)
}
}

#[cfg(feature = "serde_json")]
impl From<crate::json::JsonError> for Error {
fn from(err: crate::json::JsonError) -> Error {
Error::JsonError(err)
}
}

#[cfg(feature = "serde_json5")]
impl From<crate::json::Json5Error> for Error {
fn from(err: crate::json::Json5Error) -> Error {
Error::Json5Error(err)
Expand Down
4 changes: 2 additions & 2 deletions src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub(crate) type JsonError = serde_json5::Error;
pub(crate) use serde_json5::from_reader as parse_json5;

#[cfg(not(feature = "serde_json5"))]
pub(crate) fn parse_json5<I, T>(_input: I) -> crate::Result<T> {
Err(crate::Error::Json5Error(Json5Error))
pub(crate) fn parse_json5<I, T>(_input: I) -> Result<T, Json5Error> {
Err(Json5Error)
}

#[cfg(feature = "serde_json5")]
Expand Down

0 comments on commit f014d55

Please sign in to comment.