Skip to content

Instantly share code, notes, and snippets.

@superhawk610
Created July 11, 2022 07:27
Show Gist options
  • Save superhawk610/748a221404cddabb3b19065170a172a7 to your computer and use it in GitHub Desktop.
Save superhawk610/748a221404cddabb3b19065170a172a7 to your computer and use it in GitHub Desktop.
dtolnay/unsafe-libyaml Example Usage
use std::mem::MaybeUninit;
use unsafe_libyaml::*;
fn main() {
unsafe {
let input = "foo: bar\nbaz: garply\n";
let mut parser: MaybeUninit<yaml_parser_t> = MaybeUninit::uninit();
let mut ev: MaybeUninit<yaml_event_t> = MaybeUninit::uninit();
check_err("[init]", yaml_parser_initialize(parser.as_mut_ptr()));
let mut parser = parser.assume_init();
yaml_parser_set_input_string(&mut parser, input.as_bytes().as_ptr(), input.len() as u64);
// let mut doc: MaybeUninit<yaml_document_t> = MaybeUninit::uninit();
// check_err("[load]", yaml_parser_load(&mut parser, doc.as_mut_ptr()));
// let _doc = doc.assume_init();
let mut done = false;
while !done {
if yaml_parser_parse(&mut parser, ev.as_mut_ptr()) == 0 {
let ev = ev.assume_init();
panic!("parsing failed: {:#?}", ev.to_event());
}
let mut ev = ev.assume_init();
// process the event
dbg!(ev.to_event());
done = matches!(ev.type_, yaml_event_type_t::YAML_STREAM_END_EVENT);
yaml_event_delete(&mut ev);
}
yaml_parser_delete(&mut parser);
}
}
struct Event<'a>(&'a yaml_event_t);
trait ToEvent {
fn to_event(&self) -> Event<'_>;
}
impl ToEvent for yaml_event_t {
fn to_event(&self) -> Event<'_> {
Event(self)
}
}
impl<'a> std::fmt::Debug for Event<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use yaml_event_type_t::*;
match self.0.type_ {
YAML_NO_EVENT => write!(f, "YAML_NO_EVENT"),
YAML_STREAM_START_EVENT => write!(f, "YAML_STREAM_START_EVENT"),
YAML_STREAM_END_EVENT => write!(f, "YAML_STREAM_END_EVENT"),
YAML_DOCUMENT_START_EVENT => write!(f, "YAML_DOCUMENT_START_EVENT"),
YAML_DOCUMENT_END_EVENT => write!(f, "YAML_DOCUMENT_END_EVENT"),
YAML_ALIAS_EVENT => write!(f, "YAML_ALIAS_EVENT"),
YAML_SCALAR_EVENT => f
.debug_struct("Event")
.field("type_", &"YAML_SCALAR_EVENT")
.field("value", &unsafe {
std::str::from_utf8_unchecked(std::slice::from_raw_parts(
self.0.data.scalar.value,
self.0.data.scalar.length as _,
))
})
.finish(),
YAML_SEQUENCE_START_EVENT => write!(f, "YAML_SEQUENCE_START_EVENT"),
YAML_SEQUENCE_END_EVENT => write!(f, "YAML_SEQUENCE_END_EVENT"),
YAML_MAPPING_START_EVENT => write!(f, "YAML_MAPPING_START_EVENT"),
YAML_MAPPING_END_EVENT => write!(f, "YAML_MAPPING_END_EVENT"),
_ => write!(f, "UNKNOWN {}", self.0.type_ as u32),
}
}
}
fn check_err(reason: &str, maybe_err: i32) {
if maybe_err == 0 {
panic!("{}", reason);
}
}
@superhawk610
Copy link
Author

This roughly follows the example given by LibYAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment