Skip to content

Commit 6385d1d

Browse files
authored
Merge pull request #43 from ahassany/parse-schema-module
Allow schema modules to be parsed directly
2 parents 4a2abdf + eff4881 commit 6385d1d

2 files changed

Lines changed: 98 additions & 1 deletion

File tree

src/schema.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,76 @@ impl<'a> SchemaModule<'a> {
461461
let ptr_size = mem::size_of::<ffi::lysp_import>();
462462
Array::new(self.context, array as *mut _, ptr_size)
463463
}
464+
465+
/// Parse a schema module from a string
466+
pub fn parse_string(
467+
context: &'a Context,
468+
data: &str,
469+
schema_input_format: SchemaInputFormat,
470+
) -> Result<Self> {
471+
let mut raw: *mut ffi::lys_module = std::ptr::null_mut();
472+
let data = CString::new(data).unwrap();
473+
let ret = unsafe {
474+
ffi::lys_parse_mem(
475+
context.raw,
476+
data.as_ptr(),
477+
schema_input_format as u32,
478+
&mut raw,
479+
)
480+
};
481+
if ret != ffi::LY_ERR::LY_SUCCESS {
482+
return Err(Error::new(context));
483+
}
484+
Ok(Self { context, raw })
485+
}
486+
487+
/// Parse a schema module from a file
488+
#[cfg(not(target_os = "windows"))]
489+
pub fn parse_file<F: std::os::unix::io::AsRawFd>(
490+
context: &'a Context,
491+
fd: F,
492+
schema_input_format: SchemaInputFormat,
493+
) -> Result<Self> {
494+
let mut raw: *mut ffi::lys_module = std::ptr::null_mut();
495+
let ret = unsafe {
496+
ffi::lys_parse_fd(
497+
context.raw,
498+
fd.as_raw_fd(),
499+
schema_input_format as u32,
500+
&mut raw,
501+
)
502+
};
503+
if ret != ffi::LY_ERR::LY_SUCCESS {
504+
return Err(Error::new(context));
505+
}
506+
Ok(Self { context, raw })
507+
}
508+
509+
/// Parse a schema module from a file
510+
#[cfg(target_os = "windows")]
511+
pub fn parse_file<F: std::os::unix::io::AsRawFd>(
512+
context: &'a Context,
513+
file: impl std::os::windows::io::AsRawHandle,
514+
schema_input_format: SchemaInputFormat,
515+
) -> Result<Self> {
516+
use libc::open_osfhandle;
517+
let raw_handle = file.as_raw_handle();
518+
let fd = unsafe { open_osfhandle(raw_handle as isize, 0) };
519+
520+
let mut raw: *mut ffi::lys_module = std::ptr::null_mut();
521+
let ret = unsafe {
522+
ffi::lys_parse_fd(
523+
context.raw,
524+
fd.as_raw_fd(),
525+
schema_input_format as u32,
526+
&mut raw,
527+
)
528+
};
529+
if ret != ffi::LY_ERR::LY_SUCCESS {
530+
return Err(Error::new(context));
531+
}
532+
Ok(Self { context, raw })
533+
}
464534
}
465535

466536
unsafe impl<'a> Binding<'a> for SchemaModule<'a> {

tests/schema.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use std::collections::BTreeSet;
2+
use std::path::Path;
23
use yang3::context::{Context, ContextFlags};
34
use yang3::data::DataFormat;
45
use yang3::iter::IterSchemaFlags;
56
use yang3::schema::{
6-
DataValue, DataValueType, SchemaNodeKind, SchemaPathFormat,
7+
DataValue, DataValueType, SchemaInputFormat, SchemaModule, SchemaNodeKind,
8+
SchemaPathFormat,
79
};
810

911
static SEARCH_DIR: &str = "./assets/yang/";
@@ -668,3 +670,28 @@ fn schema_module_imports() {
668670
let module_imports: Vec<_> = module.imports().collect();
669671
assert_eq!(module_imports.len(), 0);
670672
}
673+
674+
#[test]
675+
fn test_parse_schema_from_str() {
676+
let ctx = create_context();
677+
let valid_schema_str = std::fs::read_to_string(
678+
Path::new(SEARCH_DIR).join("ietf-routing@2018-01-25.yang"),
679+
)
680+
.expect("failed to read schema file");
681+
let invalid_schema = std::fs::read_to_string(YANG_LIBRARY_FILE)
682+
.expect("failed to read data file");
683+
684+
let valid_module = SchemaModule::parse_string(
685+
&ctx,
686+
&valid_schema_str,
687+
SchemaInputFormat::YANG,
688+
);
689+
let invalid_module = SchemaModule::parse_string(
690+
&ctx,
691+
&invalid_schema,
692+
SchemaInputFormat::YANG,
693+
);
694+
695+
assert!(valid_module.is_ok_and(|x| x.name() == "ietf-routing"));
696+
assert!(invalid_module.is_err());
697+
}

0 commit comments

Comments
 (0)