#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
pub use rustructure_macros::Walkable;
mod impls;
#[allow(non_camel_case_types)]
pub enum IntegerType {
u8,
i8,
u16,
i16,
u32,
i32,
u64,
i64,
usize,
}
#[cfg(feature = "std")]
#[non_exhaustive]
#[derive(Debug)]
pub enum StdType {
Cell,
RefCell,
Rc,
Arc,
}
pub trait Walker {
fn visit_unit(&mut self);
fn visit_integer(&mut self, itype: IntegerType);
fn visit_str(&mut self);
fn visit_ref<W: Walkable>(&mut self);
fn visit_option<W: Walkable>(&mut self);
fn visit_tuple<W: Walkable>(&mut self);
fn visit_array<W: Walkable>(&mut self, length: usize);
fn visit_slice<W: Walkable>(&mut self);
#[cfg(feature = "std")]
fn visit_vec<W: Walkable>(&mut self);
#[cfg(feature = "std")]
fn visit_std_type<W: Walkable>(&mut self, std: StdType);
fn visit_struct<W: Walkable>(&mut self, struct_name: &'static str);
fn visit_field<W: Walkable>(&mut self, field_name: &'static str);
fn visit_skip_field(&mut self, field_name: &'static str);
fn visit_enum<W: Walkable>(&mut self, enum_name: &'static str);
fn visit_variant<W: Walkable>(&mut self, variant_name: &'static str);
}
pub trait Walkable {
fn walk_with<W: Walker>(walker: &mut W);
}
#[cfg(feature = "std")]
pub use sw::StringWalker;
#[cfg(feature = "std")]
mod sw {
use crate::{IntegerType, Walkable, Walker, StdType};
pub struct StringWalker {
buffer: String,
}
impl StringWalker {
pub fn walk<T: Walkable>() -> String {
let mut sw = Self {
buffer: String::new(),
};
T::walk_with(&mut sw);
if !sw.buffer.is_empty() {
sw.buffer.remove(0);
}
sw.buffer
}
}
impl Walker for StringWalker {
fn visit_unit(&mut self) {
self.buffer += " unit";
}
fn visit_integer(&mut self, _itype: IntegerType) {
self.buffer += " integer";
}
fn visit_str(&mut self) {
self.buffer += " str";
}
fn visit_ref<W: Walkable>(&mut self) {
self.buffer += " (ref";
W::walk_with(self);
self.buffer += ")";
}
fn visit_option<W: Walkable>(&mut self) {
self.buffer += " (option";
W::walk_with(self);
self.buffer += ")";
}
fn visit_tuple<W: Walkable>(&mut self) {
self.buffer += " (tuple";
W::walk_with(self);
self.buffer += ")";
}
fn visit_array<W: Walkable>(&mut self, length: usize) {
self.buffer += format!(" (array:{}", length).as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_slice<W: Walkable>(&mut self) {
self.buffer += format!(" (slice").as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_vec<W: Walkable>(&mut self) {
self.buffer += format!(" (vec").as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_std_type<W: Walkable>(&mut self, std: StdType) {
self.buffer += format!(" (std:{:?}", std).as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_field<W: Walkable>(&mut self, field_name: &'static str) {
self.buffer += format!(" (field:{}", field_name).as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_skip_field(&mut self, field_name: &'static str) {
self.buffer += format!(" (skip_field:{})", field_name).as_str();
}
fn visit_variant<W: Walkable>(&mut self, variant_name: &'static str) {
self.buffer += format!(" (variant:{}", variant_name).as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_struct<W: Walkable>(&mut self, struct_name: &'static str) {
self.buffer += format!(" (struct:{}", struct_name).as_str();
W::walk_with(self);
self.buffer += ")";
}
fn visit_enum<W: Walkable>(&mut self, enum_name: &'static str) {
self.buffer += format!(" (enum:{}", enum_name).as_str();
W::walk_with(self);
self.buffer += ")";
}
}
}