🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

granit-parser

Package Overview
Dependencies
Maintainers
0
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

granit-parser - cargo Package Compare versions

Comparing version
0.0.1
to
0.0.2
+1
-1
.cargo_vcs_info.json
{
"git": {
"sha1": "d260e5b35b46abcf116846e60aea7042c02da807"
"sha1": "25a68dd9632194904c086e18766c27a249768d87"
},
"path_in_vcs": ""
}

@@ -58,4 +58,4 @@ name: Release

run: |
cargo fetch --locked
cargo +"${MSRV}" fetch --locked
cargo fetch
cargo +"${MSRV}" fetch

@@ -66,21 +66,21 @@ - name: Check formatting

- name: Run clippy
run: cargo clippy --locked --offline --all-targets --all-features -- -D warnings
run: cargo clippy --offline --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --locked --offline
run: cargo test --offline
- name: Run tests with debug_prints
run: cargo test --locked --offline --features debug_prints
run: cargo test --offline --features debug_prints
- name: Run no-default-features library tests
run: cargo test --locked --offline --lib --no-default-features
run: cargo test --offline --lib --no-default-features
- name: Check no_std target
run: cargo check --locked --offline --lib --no-default-features --target wasm32v1-none
run: cargo check --offline --lib --no-default-features --target wasm32v1-none
- name: Check MSRV
run: cargo +"${MSRV}" check --locked --offline --all-targets
run: cargo +"${MSRV}" check --offline --all-targets
- name: Verify crate packaging
run: cargo publish --locked --dry-run
run: cargo publish --dry-run

@@ -117,2 +117,2 @@ publish:

CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish --locked
run: cargo publish

@@ -115,3 +115,3 @@ # This file is automatically @generated by Cargo.

name = "granit-parser"
version = "0.0.1"
version = "0.0.2"
dependencies = [

@@ -118,0 +118,0 @@ "arraydeque",

@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "granit-parser"
version = "0.0.1"
version = "0.0.2"
authors = [

@@ -34,3 +34,3 @@ "Ethiraric <ethiraric@gmail.com>",

autobenches = false
description = "A YAML 1.2 parser in pure Rust with strict compliance"
description = "A YAML parser in pure Rust with strict compliance"
documentation = "https://docs.rs/granit-parser/latest/granit_parser"

@@ -37,0 +37,0 @@ readme = "README.md"

# Changelog
## v0.0.2
**Features**:
- Added `TryEventReceiver`, `TrySpannedEventReceiver`, `TryLoadError`,
`Parser::try_load`, and `ParserTrait::try_load` for receiver-style parsing
that can fail fast with an application error. The existing `load` API remains
unchanged for infallible receivers.
## v0.0.1

@@ -4,0 +13,0 @@

@@ -8,2 +8,3 @@ # granit-parser

[![codecov](https://codecov.io/gh/bourumir-wyngs/granit-parser/graph/badge.svg)](https://codecov.io/gh/bourumir-wyngs/granit-parser)
[![Socket Badge](https://badge.socket.dev/cargo/package/granit-parser/0.0.1)](https://badge.socket.dev/cargo/package/granit-parser/0.0.1)

@@ -17,7 +18,7 @@ [![crates.io](https://img.shields.io/crates/l/granit-parser.svg)](https://crates.io/crates/granit-parser)

>
> — Ethiraric
> — [Ethiraric](https://crates.io/users/Ethiraric)
**granit-parser** is both YAML 1.1 and 1.2 compliant parser in pure Rust with strict compliance, no-std support, and spans for parser events.
This crate started as a fork of [`saphyr-parser`](https://crates.io/crates/saphyr-parser) that descends from [`yaml-rust`](https://github.com/chyh1990/yaml-rust), with influences from `libyaml` and `yaml-cpp`. The project has since diverged significantly and is now maintained as an independent project.
This crate started as a fork of [saphyr-parser](https://crates.io/crates/saphyr-parser) that descends from [yaml-rust](https://github.com/chyh1990/yaml-rust), with influences from [libyaml](https://crates.io/crates/libyaml) and [yaml-cpp](https://github.com/jbeder/yaml-cpp). The project has since diverged significantly and is now maintained as an independent project.

@@ -28,3 +29,3 @@ Its primary goals are:

* compatibility with real-world YAML usage
* quickly incorporate the changes we need for the upstream dependency serde-saphyr
* quickly incorporate the changes we need for the upstream dependency [serde-saphyr](https://crates.io/crates/serde-saphyr).

@@ -106,3 +107,11 @@ `granit-parser`’s public API is very similar to that of `saphyr-parser`, so it is typically an easy replacement. However, some changes are still breaking (crate rename, MSRV bump, lifetimes on events, Cow payloads, etc.).

## Event API choices
Use the iterator API when the caller should pull events and decide when to stop
parsing. Use `Parser::load` for infallible receiver-style event sinks. If a
receiver may return a validation or application error and parsing should stop
immediately, use `Parser::try_load` with `TryEventReceiver` or
`TrySpannedEventReceiver`; it returns `TryLoadError::Scan` for parser errors and
`TryLoadError::Receiver` for receiver errors.
## Key differences from saphyr-parser

@@ -109,0 +118,0 @@

@@ -581,1 +581,57 @@ //! Utilities to create a source of input to the parser.

}
#[cfg(test)]
mod tests {
use super::Input;
struct MinimalInput;
impl Input for MinimalInput {
fn lookahead(&mut self, _count: usize) {}
fn buflen(&self) -> usize {
0
}
fn bufmaxlen(&self) -> usize {
0
}
fn raw_read_ch(&mut self) -> char {
'\0'
}
fn raw_read_non_breakz_ch(&mut self) -> Option<char> {
None
}
fn skip(&mut self) {}
fn skip_n(&mut self, _count: usize) {}
fn peek(&self) -> char {
'\0'
}
fn peek_nth(&self, _n: usize) -> char {
'\0'
}
}
#[test]
fn default_slice_bytes_returns_none() {
let mut input = MinimalInput;
input.lookahead(4);
assert_eq!(input.buflen(), 0);
assert_eq!(input.bufmaxlen(), 0);
assert_eq!(input.raw_read_ch(), '\0');
assert_eq!(input.raw_read_non_breakz_ch(), None);
input.skip();
input.skip_n(2);
assert_eq!(input.peek(), '\0');
assert_eq!(input.peek_nth(1), '\0');
assert_eq!(input.byte_offset(), None);
assert_eq!(input.slice_bytes(0, 0), None);
}
}

@@ -133,2 +133,42 @@ use crate::char_traits::is_breakz;

}
#[test]
fn raw_reads_bypass_buffer_and_report_eof() {
let mut input = BufferedInput::new("a".chars());
assert_eq!(input.raw_read_ch(), 'a');
assert_eq!(input.raw_read_ch(), '\0');
}
#[test]
fn raw_read_non_breakz_pushes_break_back_into_buffer() {
let mut input = BufferedInput::new("a\n".chars());
assert_eq!(input.raw_read_non_breakz_ch(), Some('a'));
assert_eq!(input.raw_read_non_breakz_ch(), None);
assert_eq!(input.buflen(), 1);
assert_eq!(input.peek(), '\n');
let mut empty = BufferedInput::new("".chars());
assert_eq!(empty.raw_read_non_breakz_ch(), None);
}
#[test]
fn skip_n_drains_buffered_characters() {
let mut input = BufferedInput::new("abcdef".chars());
input.lookahead(5);
input.skip_n(2);
assert_eq!(input.buflen(), 3);
assert_eq!(input.peek(), 'c');
assert_eq!(input.peek_nth(2), 'e');
}
#[test]
fn streaming_input_never_borrows_slices() {
let input = BufferedInput::new("abc".chars());
assert_eq!(BorrowedInput::slice_borrowed(&input, 0, 1), None);
}
}

@@ -546,4 +546,6 @@ use crate::{

mod test {
use crate::input::Input;
use alloc::string::String;
use crate::input::{BorrowedInput, Input, SkipTabs};
use super::StrInput;

@@ -582,2 +584,121 @@

}
#[test]
fn raw_reads_track_byte_offsets_and_eof() {
let mut input = StrInput::new("aé");
assert_eq!(input.raw_read_ch(), 'a');
assert_eq!(input.byte_offset(), Some(1));
assert_eq!(input.raw_read_ch(), 'é');
assert_eq!(input.byte_offset(), Some(3));
assert_eq!(input.raw_read_ch(), '\0');
assert_eq!(input.byte_offset(), Some(3));
}
#[test]
fn raw_read_non_breakz_stops_before_breakz() {
let mut input = StrInput::new("a\n");
assert_eq!(input.raw_read_non_breakz_ch(), Some('a'));
assert_eq!(input.raw_read_non_breakz_ch(), None);
assert_eq!(input.peek(), '\n');
let mut empty = StrInput::new("");
assert_eq!(empty.raw_read_non_breakz_ch(), None);
}
#[test]
fn skip_handles_ascii_unicode_and_eof() {
let mut input = StrInput::new("éab");
input.skip();
assert_eq!(input.peek(), 'a');
input.skip_n(8);
assert_eq!(input.peek(), '\0');
input.skip();
assert_eq!(input.peek(), '\0');
}
#[test]
fn peeking_past_end_returns_nul() {
let ascii = StrInput::new("ab");
assert_eq!(ascii.peek_nth(1), 'b');
assert_eq!(ascii.peek_nth(3), '\0');
let unicode = StrInput::new("éab");
assert!(unicode.next_3_are('é', 'a', 'b'));
assert!(!unicode.next_3_are('é', 'a', 'c'));
}
#[test]
fn skip_ws_to_eol_without_tabs_stops_before_tab() {
let mut input = StrInput::new(" \t# comment\n");
let (consumed, result) = input.skip_ws_to_eol(SkipTabs::No);
assert_eq!(consumed, 2);
let result = result.unwrap();
assert!(!result.found_tabs());
assert!(result.has_valid_yaml_ws());
assert_eq!(input.peek(), '\t');
}
#[test]
fn skip_ws_to_eol_skips_comments_after_whitespace() {
let mut input = StrInput::new(" # comment\nnext");
let (consumed, result) = input.skip_ws_to_eol(SkipTabs::Yes);
assert_eq!(consumed, 11);
let result = result.unwrap();
assert!(!result.found_tabs());
assert!(result.has_valid_yaml_ws());
assert_eq!(input.peek(), '\n');
}
#[test]
fn fetch_while_is_alpha_is_ascii_only() {
let mut input = StrInput::new("abc_123-é");
let mut out = String::new();
assert_eq!(input.fetch_while_is_alpha(&mut out), 8);
assert_eq!(out, "abc_123-");
assert_eq!(input.peek(), 'é');
}
#[test]
fn fetch_plain_scalar_chunk_handles_non_ascii_after_colon() {
let mut input = StrInput::new("a:é ");
let mut out = String::new();
assert_eq!(
input.fetch_plain_scalar_chunk(&mut out, 16, false),
(true, 3)
);
assert_eq!(out, "a:é");
assert_eq!(input.peek(), ' ');
}
#[test]
fn fetch_plain_scalar_chunk_stops_at_flow_indicator() {
let mut input = StrInput::new("abc,def");
let mut out = String::new();
assert_eq!(
input.fetch_plain_scalar_chunk(&mut out, 16, true),
(true, 3)
);
assert_eq!(out, "abc");
assert_eq!(input.peek(), ',');
}
#[test]
fn borrowed_slices_use_original_input_lifetime() {
let input = StrInput::new("aéz");
assert_eq!(BorrowedInput::slice_borrowed(&input, 1, 3), Some("é"));
assert_eq!(input.slice_bytes(3, 4), Some("z"));
}
}

@@ -67,3 +67,6 @@ // Copyright 2015, Yuheng Chen.

pub use crate::input::{str::StrInput, BorrowedInput, BufferedInput, Input};
pub use crate::parser::{Event, EventReceiver, Parser, ParserTrait, SpannedEventReceiver, Tag};
pub use crate::parser::{
Event, EventReceiver, Parser, ParserTrait, SpannedEventReceiver, Tag, TryEventReceiver,
TryLoadError, TrySpannedEventReceiver,
};
pub use crate::scanner::{Marker, ScalarStyle, ScanError, Scanner, Span, Token, TokenType};

@@ -67,2 +67,21 @@ #![allow(clippy::bool_assert_comparison)]

#[test]
fn span_helpers_report_length_empty_and_byte_range() {
let span = granit_parser::Span::new(
Marker::new(2, 1, 2).with_byte_offset(Some(5)),
Marker::new(6, 1, 6).with_byte_offset(Some(13)),
);
assert_eq!(span.len(), 4);
assert!(!span.is_empty());
assert_eq!(span.byte_range(), Some(5..13));
let empty = granit_parser::Span::empty(Marker::new(6, 1, 6).with_byte_offset(Some(13)));
assert!(empty.is_empty());
assert_eq!(empty.byte_range(), Some(13..13));
let without_byte_offsets = granit_parser::Span::new(Marker::new(0, 1, 0), Marker::new(1, 1, 1));
assert_eq!(without_byte_offsets.byte_range(), None);
}
#[test]
fn test_plain() {

@@ -69,0 +88,0 @@ assert_eq!(

@@ -12,3 +12,3 @@ extern crate alloc;

BorrowedInput, Event, Marker, Parser, ParserTrait, ScalarStyle, Span, SpannedEventReceiver,
StrInput,
StrInput, TryEventReceiver, TryLoadError,
};

@@ -303,2 +303,20 @@

struct TryTestReceiver<'input> {
events: Vec<Event<'input>>,
}
impl<'input> TryEventReceiver<'input> for TryTestReceiver<'input> {
type Error = &'static str;
fn on_event(&mut self, ev: Event<'input>) -> Result<(), Self::Error> {
let should_fail = matches!(&ev, Event::Scalar(value, ..) if value.as_ref() == "stop");
self.events.push(ev);
if should_fail {
Err("stop requested")
} else {
Ok(())
}
}
}
#[test]

@@ -346,2 +364,25 @@ fn test_parser_stack_load() {

#[test]
fn test_parser_stack_try_load_stops_on_receiver_error() {
let mut stack: MyStack = ParserStack::new();
stack.push_str_parser(
Parser::new_from_str("a: stop\nafter: value\n"),
"p1".to_string(),
);
let mut recv = TryTestReceiver { events: Vec::new() };
let err = stack.try_load(&mut recv, true).unwrap_err();
assert_eq!(err, TryLoadError::Receiver("stop requested"));
assert!(recv
.events
.iter()
.any(|event| matches!(event, Event::Scalar(value, ..) if value == "stop")));
assert!(!recv
.events
.iter()
.any(|event| matches!(event, Event::Scalar(value, ..) if value == "after")));
}
#[test]
fn test_parser_stack_load_single() {

@@ -348,0 +389,0 @@ let mut stack: MyStack = ParserStack::new();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display