forma_json 0.1.0

JSON serialization and deserialization for forma_core.
Documentation
//! JSON serialization and deserialization for the Forma framework.
//!
//! # Quick start
//!
//! ```
//! use forma_json::{to_string, from_str};
//! use forma_core::ser::Serialize;
//! use forma_core::de::Deserialize;
//!
//! // Serialize
//! let v: Vec<i32> = vec![1, 2, 3];
//! let json = to_string(&v).unwrap();
//! assert_eq!(json, "[1,2,3]");
//!
//! // Deserialize
//! let v: Vec<i32> = from_str(&json).unwrap();
//! assert_eq!(v, [1, 2, 3]);
//! ```

pub mod de;
pub mod error;
pub mod ser;
pub mod value;

pub use error::Error;
pub use value::Value;

use forma_core::de::Deserialize;
use forma_core::ser::Serialize;

/// Serialize a value to a JSON string.
pub fn to_string<T: Serialize>(value: &T) -> Result<String, Error> {
    let mut buf = Vec::new();
    to_writer(&mut buf, value)?;
    // SAFETY: the serializer only writes valid UTF-8
    Ok(unsafe { String::from_utf8_unchecked(buf) })
}

/// Serialize a value to a JSON byte vector.
pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, Error> {
    let mut buf = Vec::new();
    to_writer(&mut buf, value)?;
    Ok(buf)
}

/// Serialize a value as JSON into an `io::Write`.
pub fn to_writer<W: std::io::Write, T: Serialize>(writer: W, value: &T) -> Result<(), Error> {
    let mut ser = ser::Serializer::new(writer);
    value.serialize(&mut ser)
}

/// Serialize a value to a pretty-printed JSON string with 2-space indentation.
pub fn to_string_pretty<T: Serialize>(value: &T) -> Result<String, Error> {
    let mut buf = Vec::new();
    to_writer_pretty(&mut buf, value)?;
    // SAFETY: the serializer only writes valid UTF-8
    Ok(unsafe { String::from_utf8_unchecked(buf) })
}

/// Serialize a value as pretty-printed JSON into an `io::Write` with 2-space indentation.
pub fn to_writer_pretty<W: std::io::Write, T: Serialize>(
    writer: W,
    value: &T,
) -> Result<(), Error> {
    let mut ser = ser::Serializer::pretty(writer, "  ");
    value.serialize(&mut ser)
}

/// Deserialize a value from a JSON string.
pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
    let mut de = de::Deserializer::from_str(s);
    let value = T::deserialize(&mut de)?;
    de.end_of_input()?;
    Ok(value)
}

/// Deserialize a value from JSON bytes.
pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
    let mut de = de::Deserializer::new(bytes);
    let value = T::deserialize(&mut de)?;
    de.end_of_input()?;
    Ok(value)
}

/// Deserialize a value from a JSON string with lenient type coercion.
///
/// In lenient mode, the deserializer accepts compatible types:
/// - Strings `"42"` accepted as numbers
/// - Strings `"true"`/`"false"` accepted as bools
/// - Single values wrapped into one-element arrays
pub fn from_str_lenient<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
    let mut de = de::Deserializer::from_str(s);
    de.set_lenient(true);
    let value = T::deserialize(&mut de)?;
    de.end_of_input()?;
    Ok(value)
}

/// Deserialize a value from JSON bytes with lenient type coercion.
pub fn from_slice_lenient<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
    let mut de = de::Deserializer::new(bytes);
    de.set_lenient(true);
    let value = T::deserialize(&mut de)?;
    de.end_of_input()?;
    Ok(value)
}

/// Deserialize a value from a JSON `io::Read` source.
///
/// Reads the entire input into memory, then parses. For large inputs where
/// you already have the bytes in memory, prefer [`from_slice`] or [`from_str`]
/// to avoid the copy.
pub fn from_reader<R: std::io::Read, T: forma_core::de::DeserializeOwned>(
    mut reader: R,
) -> Result<T, Error> {
    let mut buf = Vec::new();
    reader.read_to_end(&mut buf)?;
    let mut de = de::Deserializer::new(&buf);
    let value = T::deserialize(&mut de)?;
    de.end_of_input()?;
    Ok(value)
}