ytsaurus_yson/lib.rs
1//! # ytsaurus-yson
2//!
3//! A Rust library for serializing and deserializing the YSON format.
4
5#![warn(missing_docs)]
6
7// Internal modules hidden from the public API to reduce clutter
8pub(crate) mod access;
9/// Tools for working with YSON attributes and metadata.
10pub mod attributes;
11/// Deserialization logic and types.
12pub mod de;
13/// Error types and handling.
14pub mod error;
15pub(crate) mod lexer;
16/// Abstract Syntax Tree (AST) representation of YSON values.
17pub mod node;
18/// Locating record boundaries in a partially-read buffer.
19pub mod scan;
20/// Serialization logic and types.
21pub mod ser;
22pub(crate) mod varint;
23
24// Public re-exports
25pub use crate::attributes::WithAttributes;
26pub use crate::de::StreamDeserializer;
27pub use crate::error::YsonError;
28pub use crate::node::{YsonNode, YsonValue};
29pub use crate::scan::{Scan, scan_value};
30pub use crate::ser::YsonFormat;
31
32use crate::de::Deserializer;
33use crate::ser::Serializer;
34use serde::{Deserialize, Serialize};
35
36/// Helper to determine if a format is binary.
37fn is_binary(format: YsonFormat) -> bool {
38 match format {
39 YsonFormat::Binary => true,
40 YsonFormat::Text => false,
41 }
42}
43
44/// Deserializes an instance of type `T` from a byte slice in the specified YSON format.
45///
46/// # Examples
47///
48/// ```
49/// use ytsaurus_yson::{from_slice, YsonFormat};
50/// use std::collections::HashMap;
51///
52/// let data = b"{key=\"42\"; status=\"active\"}";
53/// let map: HashMap<String, String> = from_slice(data, YsonFormat::Text).unwrap();
54///
55/// assert_eq!(map.get("key").unwrap(), "42");
56/// ```
57///
58/// # Errors
59///
60/// Returns [`YsonError`] if:
61/// - The input data has invalid YSON syntax.
62/// - The input contains invalid UTF-8 sequences (when in text mode).
63/// - The data structure does not match the requirements of the target type `T`.
64pub fn from_slice<'a, T>(bytes: &'a [u8], format: YsonFormat) -> Result<T, YsonError>
65where
66 T: Deserialize<'a>,
67{
68 let mut de = Deserializer::from_bytes(bytes, is_binary(format));
69 T::deserialize(&mut de)
70}
71
72/// Serializes the given value into a byte vector using the specified YSON format.
73///
74/// # Examples
75///
76/// ```
77/// use ytsaurus_yson::{to_vec, YsonFormat};
78///
79/// let data = vec![1, 2, 3];
80/// let bytes = to_vec(&data, YsonFormat::Binary).unwrap();
81/// assert!(!bytes.is_empty());
82/// ```
83///
84/// # Errors
85///
86/// Returns [`YsonError`] if serialization fails, which can occur due to:
87/// - Recursion depth limits being exceeded.
88/// - Custom serialization errors defined by the type `T`.
89pub fn to_vec<T: Serialize>(value: &T, format: YsonFormat) -> Result<Vec<u8>, YsonError> {
90 let mut ser = Serializer::new(is_binary(format));
91 value.serialize(&mut ser)?;
92 Ok(ser.output)
93}
94
95/// Serializes the given value into a YSON-formatted string.
96///
97/// # Examples
98///
99/// ```
100/// use ytsaurus_yson::{to_string, YsonFormat};
101///
102/// let val = ("answer", 42);
103/// let res = to_string(&val, YsonFormat::Text).unwrap();
104/// assert_eq!(res, "[answer;42]");
105/// ```
106///
107/// # Errors
108///
109/// Returns an error if:
110/// - The format is [`YsonFormat::Binary`] (binary YSON cannot be represented as a UTF-8 string).
111/// - The serialization output contains invalid UTF-8 sequences.
112/// - Serialization fails due to internal structural constraints.
113pub fn to_string<T: Serialize>(value: &T, format: YsonFormat) -> Result<String, YsonError> {
114 if matches!(format, YsonFormat::Binary) {
115 return Err(YsonError::Custom(
116 "Cannot use to_string for binary format".into(),
117 ));
118 }
119 let bytes = to_vec(value, format)?;
120 String::from_utf8(bytes).map_err(|_| YsonError::Custom("Invalid UTF-8 output".into()))
121}