use bitflags::bitflags;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::ffi::CString;
use std::mem;
use std::os::raw::{c_char, c_void};
use std::os::unix::io::AsRawFd;
use std::slice;
use crate::context::Context;
use crate::error::{Error, Result};
use crate::iter::{Ancestors, Array, NodeIterable, Set, Siblings, Traverse};
use crate::utils::*;
use libyang2_sys as ffi;
#[derive(Clone, Debug)]
pub struct SchemaModule<'a> {
context: &'a Context,
raw: *mut ffi::lys_module,
}
#[allow(clippy::upper_case_acronyms)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SchemaInputFormat {
YANG = ffi::LYS_INFORMAT::LYS_IN_YANG,
YIN = ffi::LYS_INFORMAT::LYS_IN_YIN,
}
#[allow(clippy::upper_case_acronyms)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SchemaOutputFormat {
YANG = ffi::LYS_OUTFORMAT::LYS_OUT_YANG,
YIN = ffi::LYS_OUTFORMAT::LYS_OUT_YIN,
TREE = ffi::LYS_OUTFORMAT::LYS_OUT_TREE,
}
#[allow(clippy::upper_case_acronyms)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SchemaPathFormat {
LOG = ffi::LYSC_PATH_TYPE::LYSC_PATH_LOG,
DATA = ffi::LYSC_PATH_TYPE::LYSC_PATH_DATA,
}
bitflags! {
pub struct SchemaPrinterFlags: u32 {
const SHRINK = ffi::LYS_PRINT_SHRINK;
const NO_SUBSTMT = ffi::LYS_PRINT_NO_SUBSTMT;
}
}
#[derive(Clone, Debug)]
pub struct SchemaNode<'a> {
context: &'a Context,
raw: *mut ffi::lysc_node,
kind: SchemaNodeKind,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SchemaNodeKind {
Container,
Case,
Choice,
Leaf,
LeafList,
List,
AnyData,
Rpc,
Input,
Output,
Action,
Notification,
}
#[derive(Clone, Debug)]
pub struct SchemaStmtMust<'a> {
raw: *mut ffi::lysc_must,
_marker: std::marker::PhantomData<&'a Context>,
}
#[derive(Clone, Debug)]
pub struct SchemaStmtWhen<'a> {
raw: *mut ffi::lysc_when,
_marker: std::marker::PhantomData<&'a Context>,
}
#[derive(Copy, Clone, Debug, PartialEq, FromPrimitive)]
pub enum DataValueType {
Unknown = 0,
Binary = 1,
Uint8 = 2,
Uint16 = 3,
Uint32 = 4,
Uint64 = 5,
String = 6,
Bits = 7,
Bool = 8,
Dec64 = 9,
Empty = 10,
Enum = 11,
IdentityRef = 12,
InstanceId = 13,
LeafRef = 14,
Union = 15,
Int8 = 16,
Int16 = 17,
Int32 = 18,
Int64 = 19,
}
#[derive(Clone, Debug, PartialEq)]
pub enum DataValue {
Uint8(u8),
Uint16(u16),
Uint32(u32),
Uint64(u64),
Bool(bool),
Empty,
Int8(i8),
Int16(i16),
Int32(i32),
Int64(i64),
Other(String),
}
impl<'a> SchemaModule<'a> {
pub fn name(&self) -> &str {
char_ptr_to_str(unsafe { (*self.raw).name })
}
pub fn revision(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).revision })
}
pub fn namespace(&self) -> &str {
char_ptr_to_str(unsafe { (*self.raw).ns })
}
pub fn prefix(&self) -> &str {
char_ptr_to_str(unsafe { (*self.raw).prefix })
}
pub fn filepath(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).filepath })
}
pub fn organization(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).org })
}
pub fn contact(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).contact })
}
pub fn description(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).dsc })
}
pub fn reference(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).ref_ })
}
pub fn set_implemented(&self) -> Result<()> {
let ret =
unsafe { ffi::lys_set_implemented(self.raw, std::ptr::null_mut()) };
if ret != ffi::LY_ERR::LY_SUCCESS {
return Err(Error::new(self.context));
}
Ok(())
}
pub fn is_implemented(&self) -> bool {
unsafe { (*self.raw).implemented != 0 }
}
pub fn feature_value(&self, feature: &str) -> Result<bool> {
let feature = CString::new(feature).unwrap();
let ret = unsafe { ffi::lys_feature_value(self.raw, feature.as_ptr()) };
match ret {
ffi::LY_ERR::LY_SUCCESS => Ok(true),
ffi::LY_ERR::LY_ENOT => Ok(false),
_ => Err(Error::new(self.context)),
}
}
pub fn print_file<F: AsRawFd>(
&self,
fd: F,
format: SchemaOutputFormat,
options: SchemaPrinterFlags,
) -> Result<()> {
let ret = unsafe {
ffi::lys_print_fd(
fd.as_raw_fd(),
self.raw,
format as u32,
options.bits(),
)
};
if ret != ffi::LY_ERR::LY_SUCCESS {
return Err(Error::new(self.context));
}
Ok(())
}
pub fn print_string(
&self,
format: SchemaOutputFormat,
options: SchemaPrinterFlags,
) -> Result<String> {
let mut cstr = std::ptr::null_mut();
let cstr_ptr = &mut cstr;
let ret = unsafe {
ffi::lys_print_mem(
cstr_ptr,
self.raw,
format as u32,
options.bits(),
)
};
if ret != ffi::LY_ERR::LY_SUCCESS {
return Err(Error::new(self.context));
}
Ok(char_ptr_to_string(cstr))
}
pub fn data(&self) -> Siblings<'a, SchemaNode<'a>> {
let compiled = unsafe { (*self.raw).compiled };
let rdata = if compiled.is_null() {
std::ptr::null()
} else {
unsafe { (*compiled).data }
};
let data = SchemaNode::from_raw_opt(self.context, rdata as *mut _);
Siblings::new(data)
}
pub fn rpcs(&self) -> Siblings<'a, SchemaNode<'a>> {
let compiled = unsafe { (*self.raw).compiled };
let rdata = if compiled.is_null() {
std::ptr::null()
} else {
unsafe { (*compiled).rpcs }
};
let rpcs = SchemaNode::from_raw_opt(self.context, rdata as *mut _);
Siblings::new(rpcs)
}
pub fn notifications(&self) -> Siblings<'a, SchemaNode<'a>> {
let compiled = unsafe { (*self.raw).compiled };
let rdata = if compiled.is_null() {
std::ptr::null()
} else {
unsafe { (*compiled).notifs }
};
let notifications =
SchemaNode::from_raw_opt(self.context, rdata as *mut _);
Siblings::new(notifications)
}
pub fn traverse(&self) -> impl Iterator<Item = SchemaNode<'a>> {
let data = self.data().flat_map(|snode| snode.traverse());
let rpcs = self.rpcs().flat_map(|snode| snode.traverse());
let notifications =
self.notifications().flat_map(|snode| snode.traverse());
data.chain(rpcs).chain(notifications)
}
}
impl<'a> Binding<'a> for SchemaModule<'a> {
type CType = ffi::lys_module;
type Container = Context;
fn from_raw(
context: &'a Context,
raw: *mut ffi::lys_module,
) -> SchemaModule<'_> {
SchemaModule { context, raw }
}
}
impl<'a> PartialEq for SchemaModule<'a> {
fn eq(&self, other: &SchemaModule<'_>) -> bool {
self.raw == other.raw
}
}
unsafe impl Send for SchemaModule<'_> {}
unsafe impl Sync for SchemaModule<'_> {}
impl<'a> SchemaNode<'a> {
#[doc(hidden)]
fn check_flag(&self, flag: u32) -> bool {
let flags = unsafe { (*self.raw).flags } as u32;
flags & flag != 0
}
pub fn module(&self) -> SchemaModule<'_> {
let module = unsafe { (*self.raw).module };
SchemaModule::from_raw(self.context, module)
}
pub fn kind(&self) -> SchemaNodeKind {
self.kind
}
pub fn name(&self) -> &str {
char_ptr_to_str(unsafe { (*self.raw).name })
}
pub fn description(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).dsc })
}
pub fn reference(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).ref_ })
}
pub fn path(&self, format: SchemaPathFormat) -> String {
let buf = std::mem::MaybeUninit::<[c_char; 4096]>::uninit();
let mut buf = unsafe { buf.assume_init() };
let ret = unsafe {
ffi::lysc_path(
self.raw,
format as u32,
buf.as_mut_ptr(),
buf.len() as u64,
)
};
if ret.is_null() {
panic!("Failed to generate path of the schema node");
}
char_ptr_to_string(buf.as_ptr())
}
pub fn find_xpath(&self, xpath: &str) -> Result<Set<'_, SchemaNode<'_>>> {
let xpath = CString::new(xpath).unwrap();
let mut set = std::ptr::null_mut();
let set_ptr = &mut set;
let options = 0u32;
let ret = unsafe {
ffi::lys_find_xpath(
std::ptr::null(),
self.raw,
xpath.as_ptr(),
options,
set_ptr,
)
};
if ret != ffi::LY_ERR::LY_SUCCESS {
return Err(Error::new(self.context));
}
let rnodes_count = unsafe { (*set).count } as usize;
let slice = if rnodes_count == 0 {
&[]
} else {
let rnodes = unsafe { (*set).__bindgen_anon_1.snodes };
unsafe { slice::from_raw_parts(rnodes, rnodes_count) }
};
Ok(Set::new(self.context, slice))
}
pub fn find_path(&self, path: &str) -> Result<SchemaNode<'_>> {
let path = CString::new(path).unwrap();
let rnode = unsafe {
ffi::lys_find_path(std::ptr::null(), self.raw, path.as_ptr(), 0)
};
if rnode.is_null() {
return Err(Error::new(self.context));
}
Ok(SchemaNode::from_raw(self.context, rnode as *mut _))
}
pub fn is_config(&self) -> bool {
match self.kind {
SchemaNodeKind::Container
| SchemaNodeKind::Case
| SchemaNodeKind::Choice
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList
| SchemaNodeKind::List
| SchemaNodeKind::AnyData => self.check_flag(ffi::LYS_CONFIG_W),
_ => false,
}
}
pub fn is_state(&self) -> bool {
match self.kind {
SchemaNodeKind::Container
| SchemaNodeKind::Case
| SchemaNodeKind::Choice
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList
| SchemaNodeKind::List
| SchemaNodeKind::AnyData => self.check_flag(ffi::LYS_CONFIG_R),
_ => false,
}
}
pub fn is_status_current(&self) -> bool {
self.check_flag(ffi::LYS_STATUS_CURR)
}
pub fn is_status_deprecated(&self) -> bool {
self.check_flag(ffi::LYS_STATUS_DEPRC)
}
pub fn is_status_obsolete(&self) -> bool {
self.check_flag(ffi::LYS_STATUS_OBSLT)
}
pub fn is_mandatory(&self) -> bool {
match self.kind {
SchemaNodeKind::Container
| SchemaNodeKind::Choice
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList
| SchemaNodeKind::List
| SchemaNodeKind::AnyData => self.check_flag(ffi::LYS_MAND_TRUE),
_ => false,
}
}
pub fn is_np_container(&self) -> bool {
match self.kind {
SchemaNodeKind::Container => !self.check_flag(ffi::LYS_PRESENCE),
_ => false,
}
}
pub fn is_list_key(&self) -> bool {
match self.kind {
SchemaNodeKind::Leaf => self.check_flag(ffi::LYS_KEY),
_ => false,
}
}
pub fn is_keyless_list(&self) -> bool {
match self.kind {
SchemaNodeKind::List => self.check_flag(ffi::LYS_KEYLESS),
_ => false,
}
}
pub fn is_user_ordered(&self) -> bool {
match self.kind {
SchemaNodeKind::LeafList | SchemaNodeKind::List => {
self.check_flag(ffi::LYS_ORDBY_USER)
}
_ => false,
}
}
pub fn is_schema_only(&self) -> bool {
matches!(self.kind(), SchemaNodeKind::Choice | SchemaNodeKind::Case)
}
pub fn is_within_input(&self) -> bool {
match self.kind {
SchemaNodeKind::Container
| SchemaNodeKind::Case
| SchemaNodeKind::Choice
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList
| SchemaNodeKind::List
| SchemaNodeKind::AnyData => self.check_flag(ffi::LYS_IS_INPUT),
_ => false,
}
}
pub fn is_within_output(&self) -> bool {
match self.kind {
SchemaNodeKind::Container
| SchemaNodeKind::Case
| SchemaNodeKind::Choice
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList
| SchemaNodeKind::List
| SchemaNodeKind::AnyData => self.check_flag(ffi::LYS_IS_OUTPUT),
_ => false,
}
}
pub fn is_within_notification(&self) -> bool {
match self.kind {
SchemaNodeKind::Container
| SchemaNodeKind::Case
| SchemaNodeKind::Choice
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList
| SchemaNodeKind::List
| SchemaNodeKind::AnyData => self.check_flag(ffi::LYS_IS_NOTIF),
_ => false,
}
}
pub fn has_default(&self) -> bool {
match self.kind {
SchemaNodeKind::Case
| SchemaNodeKind::Leaf
| SchemaNodeKind::LeafList => self.check_flag(ffi::LYS_SET_DFLT),
_ => false,
}
}
pub fn default_value_canonical(&self) -> Option<&str> {
let default = unsafe {
match self.kind() {
SchemaNodeKind::Leaf => {
(*(*(self.raw as *mut ffi::lysc_node_leaf)).dflt)._canonical
}
_ => return None,
}
};
char_ptr_to_opt_str(default)
}
pub fn default_value(&self) -> Option<DataValue> {
match self.kind() {
SchemaNodeKind::Leaf => {
let default = unsafe {
let rvalue =
(*(self.raw as *const ffi::lysc_node_leaf)).dflt;
if rvalue.is_null() {
return None;
}
DataValue::from_raw(rvalue)
};
Some(default)
}
_ => None,
}
}
pub fn default_case(&self) -> Option<SchemaNode<'_>> {
let default = unsafe {
match self.kind() {
SchemaNodeKind::Choice => {
(*(self.raw as *mut ffi::lysc_node_choice)).dflt
}
_ => return None,
}
};
SchemaNode::from_raw_opt(self.context, default as *mut _)
}
pub fn base_type(&self) -> Option<DataValueType> {
let ltype = unsafe {
match self.kind() {
SchemaNodeKind::Leaf => {
(*(self.raw as *mut ffi::lysc_node_leaf)).type_
}
SchemaNodeKind::LeafList => {
(*(self.raw as *mut ffi::lysc_node_leaflist)).type_
}
_ => return None,
}
};
let ltype = unsafe { (*ltype).basetype };
Some(DataValueType::from_u32(ltype).unwrap())
}
pub fn units(&self) -> Option<&str> {
let units = unsafe {
match self.kind() {
SchemaNodeKind::Leaf => {
(*(self.raw as *mut ffi::lysc_node_leaf)).units
}
SchemaNodeKind::LeafList => {
(*(self.raw as *mut ffi::lysc_node_leaflist)).units
}
_ => return None,
}
};
char_ptr_to_opt_str(units)
}
pub fn min_elements(&self) -> Option<u32> {
let min = unsafe {
match self.kind() {
SchemaNodeKind::LeafList => {
(*(self.raw as *mut ffi::lysc_node_leaflist)).min
}
SchemaNodeKind::List => {
(*(self.raw as *mut ffi::lysc_node_list)).min
}
_ => return None,
}
};
if min != 0 {
Some(min)
} else {
None
}
}
pub fn max_elements(&self) -> Option<u32> {
let max = unsafe {
match self.kind() {
SchemaNodeKind::LeafList => {
(*(self.raw as *mut ffi::lysc_node_leaflist)).max
}
SchemaNodeKind::List => {
(*(self.raw as *mut ffi::lysc_node_list)).max
}
_ => return None,
}
};
if max != std::u32::MAX {
Some(max)
} else {
None
}
}
pub fn musts(&self) -> Option<Array<'_, SchemaStmtMust<'_>>> {
let array = unsafe { ffi::lysc_node_musts(self.raw) };
let ptr_size = mem::size_of::<ffi::lysc_must>();
Some(Array::new(self.context, array as *mut _, ptr_size))
}
pub fn whens(&self) -> Array<'_, SchemaStmtWhen<'_>> {
let array = unsafe { ffi::lysc_node_when(self.raw) };
let ptr_size = mem::size_of::<ffi::lysc_when>();
Array::new(self.context, array as *mut _, ptr_size)
}
pub fn actions(&self) -> Option<Array<'_, SchemaNode<'_>>> {
let array = unsafe {
match self.kind {
SchemaNodeKind::Container => {
(*(self.raw as *mut ffi::lysc_node_container)).actions
}
SchemaNodeKind::List => {
(*(self.raw as *mut ffi::lysc_node_list)).actions
}
_ => return None,
}
};
let ptr_size = mem::size_of::<ffi::lysc_node_action>();
Some(Array::new(self.context, array as *mut _, ptr_size))
}
pub fn notifications(&self) -> Option<Array<'_, SchemaNode<'_>>> {
let array = unsafe {
match self.kind {
SchemaNodeKind::Container => {
(*(self.raw as *mut ffi::lysc_node_container)).notifs
}
SchemaNodeKind::List => {
(*(self.raw as *mut ffi::lysc_node_list)).notifs
}
_ => return None,
}
};
let ptr_size = mem::size_of::<ffi::lysc_node_notif>();
Some(Array::new(self.context, array as *mut _, ptr_size))
}
pub fn input(
&self,
) -> Option<(Siblings<'_, SchemaNode<'_>>, Array<'_, SchemaStmtMust<'_>>)>
{
match self.kind {
SchemaNodeKind::Rpc | SchemaNodeKind::Action => {
let raw = self.raw as *mut ffi::lysc_node_action;
let input = unsafe { (*raw).input };
let rnode = input.child;
let rmusts = input.musts;
let node = SchemaNode::from_raw_opt(self.context, rnode);
let nodes = Siblings::new(node);
let ptr_size = mem::size_of::<ffi::lysc_must>();
let musts = Array::new(self.context, rmusts, ptr_size);
Some((nodes, musts))
}
_ => None,
}
}
pub fn output(
&self,
) -> Option<(Siblings<'_, SchemaNode<'_>>, Array<'_, SchemaStmtMust<'_>>)>
{
match self.kind {
SchemaNodeKind::Rpc | SchemaNodeKind::Action => {
let raw = self.raw as *mut ffi::lysc_node_action;
let output = unsafe { (*raw).output };
let rnode = output.child;
let rmusts = output.musts;
let node = SchemaNode::from_raw_opt(self.context, rnode);
let nodes = Siblings::new(node);
let ptr_size = mem::size_of::<ffi::lysc_must>();
let musts = Array::new(self.context, rmusts, ptr_size);
Some((nodes, musts))
}
_ => None,
}
}
pub fn ancestors(&self) -> Ancestors<'a, SchemaNode<'a>> {
let parent = self.parent();
Ancestors::new(parent)
}
pub fn inclusive_ancestors(&self) -> Ancestors<'a, SchemaNode<'a>> {
Ancestors::new(Some(self.clone()))
}
pub fn siblings(&self) -> Siblings<'a, SchemaNode<'a>> {
let sibling = self.next_sibling();
Siblings::new(sibling)
}
pub fn inclusive_siblings(&self) -> Siblings<'a, SchemaNode<'a>> {
Siblings::new(Some(self.clone()))
}
pub fn children(&self) -> Siblings<'a, SchemaNode<'a>> {
let child = self.first_child();
Siblings::new(child)
}
pub fn traverse(&self) -> Traverse<'a, SchemaNode<'a>> {
Traverse::new(self.clone())
}
pub fn list_keys(&self) -> impl Iterator<Item = SchemaNode<'a>> {
self.children().filter(|snode| snode.is_list_key())
}
pub unsafe fn set_private(&self, ptr: *mut c_void) {
(*self.raw).priv_ = ptr;
}
pub fn get_private(&self) -> Option<*mut c_void> {
let priv_ = unsafe { (*self.raw).priv_ };
if priv_.is_null() {
None
} else {
Some(priv_)
}
}
}
impl<'a> Binding<'a> for SchemaNode<'a> {
type CType = ffi::lysc_node;
type Container = Context;
fn from_raw(
context: &'a Context,
raw: *mut ffi::lysc_node,
) -> SchemaNode<'_> {
let nodetype = unsafe { (*raw).nodetype } as u32;
let kind = match nodetype {
ffi::LYS_CONTAINER => SchemaNodeKind::Container,
ffi::LYS_CASE => SchemaNodeKind::Case,
ffi::LYS_CHOICE => SchemaNodeKind::Choice,
ffi::LYS_LEAF => SchemaNodeKind::Leaf,
ffi::LYS_LEAFLIST => SchemaNodeKind::LeafList,
ffi::LYS_LIST => SchemaNodeKind::List,
ffi::LYS_ANYDATA => SchemaNodeKind::AnyData,
ffi::LYS_ACTION => SchemaNodeKind::Action,
ffi::LYS_RPC => SchemaNodeKind::Rpc,
ffi::LYS_INPUT => SchemaNodeKind::Input,
ffi::LYS_OUTPUT => SchemaNodeKind::Output,
ffi::LYS_NOTIF => SchemaNodeKind::Notification,
_ => panic!("unknown node type"),
};
SchemaNode { context, raw, kind }
}
}
impl<'a> NodeIterable<'a> for SchemaNode<'a> {
fn parent(&self) -> Option<SchemaNode<'a>> {
let rparent = unsafe { (*self.raw).parent };
SchemaNode::from_raw_opt(self.context, rparent)
}
fn next_sibling(&self) -> Option<SchemaNode<'a>> {
let rnext = unsafe { (*self.raw).next };
SchemaNode::from_raw_opt(self.context, rnext)
}
fn first_child(&self) -> Option<SchemaNode<'a>> {
let rchild = unsafe { ffi::lysc_node_child(&*self.raw) };
SchemaNode::from_raw_opt(self.context, rchild as *mut _)
}
}
impl<'a> PartialEq for SchemaNode<'a> {
fn eq(&self, other: &SchemaNode<'_>) -> bool {
self.raw == other.raw
}
}
unsafe impl Send for SchemaNode<'_> {}
unsafe impl Sync for SchemaNode<'_> {}
impl<'a> SchemaStmtMust<'a> {
pub fn description(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).dsc })
}
pub fn reference(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).ref_ })
}
pub fn error_msg(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).emsg })
}
pub fn error_apptag(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).eapptag })
}
}
impl<'a> Binding<'a> for SchemaStmtMust<'a> {
type CType = ffi::lysc_must;
type Container = Context;
fn from_raw(
_context: &'a Context,
raw: *mut ffi::lysc_must,
) -> SchemaStmtMust<'_> {
SchemaStmtMust {
raw,
_marker: std::marker::PhantomData,
}
}
}
unsafe impl Send for SchemaStmtMust<'_> {}
unsafe impl Sync for SchemaStmtMust<'_> {}
impl<'a> SchemaStmtWhen<'a> {
pub fn description(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).dsc })
}
pub fn reference(&self) -> Option<&str> {
char_ptr_to_opt_str(unsafe { (*self.raw).ref_ })
}
}
impl<'a> Binding<'a> for SchemaStmtWhen<'a> {
type CType = *mut ffi::lysc_when;
type Container = Context;
fn from_raw(
_context: &'a Context,
raw: *mut *mut ffi::lysc_when,
) -> SchemaStmtWhen<'_> {
let raw = unsafe { *raw };
SchemaStmtWhen {
raw,
_marker: std::marker::PhantomData,
}
}
}
unsafe impl Send for SchemaStmtWhen<'_> {}
unsafe impl Sync for SchemaStmtWhen<'_> {}
impl DataValue {
pub(crate) unsafe fn from_raw(raw: *const ffi::lyd_value) -> DataValue {
let rtype = (*(*raw).realtype).basetype;
match rtype {
ffi::LY_DATA_TYPE::LY_TYPE_UINT8 => {
let value = (*raw).__bindgen_anon_1.uint8;
DataValue::Uint8(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_UINT16 => {
let value = (*raw).__bindgen_anon_1.uint16;
DataValue::Uint16(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_UINT32 => {
let value = (*raw).__bindgen_anon_1.uint32;
DataValue::Uint32(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_UINT64 => {
let value = (*raw).__bindgen_anon_1.uint64;
DataValue::Uint64(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_BOOL => {
let value = (*raw).__bindgen_anon_1.boolean != 0;
DataValue::Bool(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_INT8 => {
let value = (*raw).__bindgen_anon_1.int8;
DataValue::Int8(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_INT16 => {
let value = (*raw).__bindgen_anon_1.int16;
DataValue::Int16(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_INT32 => {
let value = (*raw).__bindgen_anon_1.int32;
DataValue::Int32(value)
}
ffi::LY_DATA_TYPE::LY_TYPE_INT64 => {
let value = (*raw).__bindgen_anon_1.int64;
DataValue::Int64(value)
}
_ => {
let canonical = (*raw)._canonical;
DataValue::Other(char_ptr_to_string(canonical))
}
}
}
}