Expand description
Reader and writer for the 1C:Enterprise bracket format: {1,"text",{nested,list}}.
Input is anything implementing std::io::Read; the result is a Node tree.
The API is built on the standard conversion traits:
use one_brackets::Node;
let node: Node = "\u{feff}{2,c2f34349-b1e0-4060-8abf-3c59f38ac69f,\"ок\"}".parse()?;
assert_eq!(node.try_get(0)?.try_i64()?, 2);
assert!(node[1].as_guid().is_some());
assert_eq!(node[2].as_quoted(), Some("ок"));
// Writing uses the platform layout.
let text: String = (&node).into();
assert_eq!(text, "{2,c2f34349-b1e0-4060-8abf-3c59f38ac69f,\"ок\"}");
// Any `Read` source: file, socket, decompressed stream.
let node = Node::from_reader(std::io::Cursor::new(b"{1,{}}"))?;
assert_eq!(node, Node::list([Node::from(1), Node::list([])]));
// Edit in place and write back: untouched parts keep their text.
let mut node: Node = "{1,\"old\",{2}}".parse()?;
*node.try_get_path_mut(&[2, 0])? = Node::from(3);
node[1] = Node::string("new");
assert_eq!(node.to_string(), "{1,\"new\",\r\n{3}\r\n}");
// Errors carry a position.
let err = Node::try_from("{1,\n{2").unwrap_err();
assert_eq!(
err.to_string(),
"unexpected end of input at line 2, column 3: list opened at line 2, column 1 is not closed",
);Map your own types with impl TryFrom<&Node> using the try_* accessors.
They return an AccessError that names the expected type and points at the node:
use one_brackets::{AccessError, Node};
#[derive(Debug)]
struct FormatVersion { major: u32, build: u64 }
impl TryFrom<&Node> for FormatVersion {
type Error = AccessError;
fn try_from(node: &Node) -> Result<Self, AccessError> {
Ok(FormatVersion {
major: node.try_get_path(&[0, 0])?.try_parse()?,
build: node.try_get_path(&[0, 2, 0])?.try_parse()?,
})
}
}
let node: Node = "{\r\n{216,0,\r\n{x,0}\r\n}\r\n}".parse().unwrap();
let err = FormatVersion::try_from(&node).unwrap_err();
assert_eq!(
err.to_string(),
"expected u64, found value `x` at line 3, column 2: invalid digit found in string",
);Parsing problems are reported as ParseError, structure problems as AccessError;
Error wraps both, so ? works for either in one function.
With the serde feature user types map to lists by field order:
see from_node, to_node, Rest, Counted and atom.
§Performance
Every string and value is a separate String and every list a Vec, so most of
the parsing time of large files (event logs, big forms) goes to the memory allocator.
The library does not pick an allocator; the application can switch to
mimalloc, which works on Windows, Linux and macOS.
In the crate’s measurements it made parsing 1.5–2.7 times faster on Windows,
whose system allocator is the slowest, and 1.2–1.5 times faster on Linux (glibc):
[dependencies]
mimalloc = "0.1"#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;For large inputs prefer Values over parsing one huge list: it keeps only
the current record in memory. cargo bench measures reading and writing speed.
Modules§
- atom
serde - Field helper for
#[serde(with = "one_brackets::atom")].
Structs§
- Access
Error - The text is valid, but a node does not have the expected shape.
- Counted
serde - A counted list
{count,item1,item2,...}, the common 1C shape. - Node
- A node of a bracket file: a
Valueplus the position it was parsed from. - Position
- Position in the input.
- Rest
serde - Remaining items of a list after the preceding fields, kept as is.
- Serialize
Error serde - A value cannot be represented in the bracket format.
- Values
- Comma-separated top-level values read one at a time, e.g. records of an event log
.lgp.
Enums§
- Access
Error Kind - What exactly went wrong in an
AccessError. - Error
- Either kind of error, for code that parses and maps in one function.
- Parse
Error - The input could not be read or is not valid bracket text.
- Value
- Content of a
Node.
Functions§
- from_
node serde - Deserializes a user type from a node;
&strfields can borrow from the node. - from_
reader serde - Reads bracket text from any
Readand deserializes a user type from it. - from_
str serde - Parses bracket text and deserializes a user type from it.
- to_node
serde - Serializes a user type into a node tree.
- to_
string serde - Serializes a user type into bracket text in the platform layout.