pub mod schema;
pub mod yaml;
pub mod yamlette;
pub mod renderer;
pub mod rope;
pub mod style;
pub mod tagged_value;
extern crate skimmer;
use std::any::Any;
use std::borrow::Cow;
use std::iter::Iterator;
pub use self::renderer::{EncodedString, Node, Renderer};
pub use self::rope::Rope;
pub use self::schema::Schema;
pub use self::style::CommonStyles;
pub use self::tagged_value::TaggedValue;
pub trait Tagged: Any {
fn get_tag(&self) -> Cow<'static, str>;
fn as_any(&self) -> &dyn Any;
fn as_mut_any(&mut self) -> &mut dyn Any;
}
pub trait Model: Send + Sync {
fn get_tag(&self) -> Cow<'static, str>;
fn as_any(&self) -> &dyn Any;
fn as_mut_any(&mut self) -> &mut dyn Any;
fn is_collection(&self) -> bool {
self.is_dictionary() || self.is_sequence()
}
fn is_sequence(&self) -> bool {
false
}
fn is_dictionary(&self) -> bool {
false
}
fn is_metamodel(&self) -> bool {
false
}
fn is_decodable(&self) -> bool {
false
}
fn is_encodable(&self) -> bool {
false
}
fn has_default(&self) -> bool {
false
}
fn get_default(&self) -> TaggedValue {
panic!("Model does not have a default value");
}
fn meta_init(
&self,
_anchor: Option<String>,
_tag: Option<String>,
_value: &[u8],
) -> Result<TaggedValue, ()> {
panic!("Model is not a metamodel");
}
fn decode(&self, _explicit: bool, _value: &[u8]) -> Result<TaggedValue, ()> {
panic!("Model is not decodable");
}
fn decode11(&self, explicit: bool, value: &[u8]) -> Result<TaggedValue, ()> {
self.decode(explicit, value)
}
fn encode(
&self,
_renderer: &Renderer,
_value: TaggedValue,
_tags: &mut dyn Iterator<Item = &(Cow<'static, str>, Cow<'static, str>)>,
) -> Result<Rope, TaggedValue> {
panic!("Model is not encodable");
}
fn compose(
&self,
_renderer: &Renderer,
_value: TaggedValue,
_tags: &mut dyn Iterator<Item = &(Cow<'static, str>, Cow<'static, str>)>,
_children: &mut [Rope],
) -> Rope {
panic!("Model is not composable");
}
}
pub fn model_issue_rope(
model: &dyn Model,
node: Node,
issue_tag: bool,
alias: Option<Cow<'static, str>>,
tags: &mut dyn Iterator<Item = &(Cow<'static, str>, Cow<'static, str>)>,
) -> Rope {
if let Some(alias) = alias {
if issue_tag {
Rope::from(vec![
model_tag(model, tags),
Node::Space,
model_alias(model, alias),
Node::Space,
node,
])
} else {
Rope::from(vec![model_alias(model, alias), Node::Space, node])
}
} else {
if issue_tag {
Rope::from(vec![model_tag(model, tags), Node::Space, node])
} else {
Rope::from(node)
}
}
}
pub fn model_alias(_model: &dyn Model, alias: Cow<'static, str>) -> Node {
match alias {
Cow::Borrowed(alias) => Node::AmpersandString(EncodedString::from(alias.as_bytes())),
Cow::Owned(alias) => Node::AmpersandString(EncodedString::from(alias.into_bytes())),
}
}
pub fn model_tag(
model: &dyn Model,
tags: &mut dyn Iterator<Item = &(Cow<'static, str>, Cow<'static, str>)>,
) -> Node {
match model.get_tag() {
Cow::Borrowed(tag) => _model_tag_static_str(tag, tags),
Cow::Owned(ref tag) => _model_tag_string(tag, tags),
}
}
fn _model_tag_static_str(
tag: &'static str,
tags: &mut dyn Iterator<Item = &(Cow<'static, str>, Cow<'static, str>)>,
) -> Node {
for &(ref shortcut, ref handle) in tags {
let h = handle.as_ref();
if h.len() == 0 || h.contains(' ') {
continue;
}
if tag.starts_with(h) {
return match *shortcut {
Cow::Borrowed(s) => {
let f = s.as_bytes();
let l = tag[h.len()..].as_bytes();
Node::StringConcat(EncodedString::from(f), EncodedString::from(l))
}
Cow::Owned(ref s) => {
let mut string = Vec::with_capacity(s.len() + (tag.len() - h.len()));
string.extend(s.as_bytes());
string.extend(tag[h.len()..].as_bytes());
Node::String(EncodedString::from(string))
}
};
}
}
Node::StringSpecificTag(EncodedString::from(tag.as_bytes()))
}
fn _model_tag_string(
tag: &str,
tags: &mut dyn Iterator<Item = &(Cow<'static, str>, Cow<'static, str>)>,
) -> Node {
for &(ref shortcut, ref handle) in tags {
let h = handle.as_ref();
if h.len() == 0 || h.contains(' ') {
continue;
}
if tag.starts_with(h) {
return match *shortcut {
Cow::Borrowed(s) => {
let f = s.as_bytes();
let l = tag[h.len()..].as_bytes();
let mut string = Vec::with_capacity(f.len() + l.len());
string.extend(f);
string.extend(l);
Node::String(EncodedString::from(string))
}
Cow::Owned(ref s) => {
let mut string = Vec::with_capacity(s.len() + (tag.len() - h.len()));
string.extend(s.as_bytes());
string.extend(tag[h.len()..].as_bytes());
Node::String(EncodedString::from(string))
}
};
}
}
let v: Vec<u8> = Vec::from(tag);
Node::StringSpecificTag(EncodedString::from(v))
}