use std::sync::Arc;
use containers::{Container, Queue, Set};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum NodeType {
Directory,
Blob,
Queue,
Set
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Node {
pub path: String,
pub version: u64,
pub content: Content
}
impl Node {
pub fn new<S>(path: S, content: Content) -> Node
where S: Into<String>
{
Node {
path: path.into(),
version: 0,
content: content
}
}
pub fn get_type(&self) -> NodeType {
match self.content {
Content::Directory(_) => NodeType::Directory,
Content::Container(Container::Blob(_)) => NodeType::Blob,
Content::Container(Container::Queue(_)) => NodeType::Queue,
Content::Container(Container::Set(_)) => NodeType::Set,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum Content {
Directory(Vec<Edge>),
Container(Container)
}
impl Content {
pub fn new(ty: NodeType) -> Content {
match ty {
NodeType::Directory => Content::Directory(vec![]),
NodeType::Blob => Content::Container(Container::Blob(Vec::new())),
NodeType::Queue => Content::Container(Container::Queue(Queue::new())),
NodeType::Set => Content::Container(Container::Set(Set::new())),
}
}
pub fn is_dir(&self) -> bool {
if let Content::Directory(_) = *self {
return true;
}
false
}
pub fn get_blob(&self) -> Option<&[u8]> {
if let Content::Container(Container::Blob(ref blob)) = *self {
return Some(blob);
}
None
}
pub fn get_queue(&self) -> Option<&Queue> {
if let Content::Container(Container::Queue(ref queue)) = *self {
return Some(queue);
}
None
}
pub fn get_set(&self) -> Option<&Set> {
if let Content::Container(Container::Set(ref set)) = *self {
return Some(set);
}
None
}
pub fn get_dir_edges_mut(&mut self) -> Option<&mut Vec<Edge>> {
if let Content::Directory(ref mut edges) = *self {
return Some(edges);
}
None
}
pub fn get_queue_mut(&mut self) -> Option<&mut Queue> {
if let Content::Container(Container::Queue(ref mut queue)) = *self {
return Some(queue);
}
None
}
pub fn get_set_mut(&mut self) -> Option<&mut Set> {
if let Content::Container(Container::Set(ref mut set)) = *self {
return Some(set);
}
None
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Edge {
pub label: String,
pub node: Arc<Node>
}
impl Edge {
pub fn new(label: &str, node: Node) -> Edge {
Edge {
label: label.to_string(),
node: Arc::new(node)
}
}
}
impl Serialize for Edge {
#[inline]
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.node.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Edge {
#[inline]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let node = Node::deserialize(deserializer)?;
let label = if let Some(pos) = node.path.rfind('/') {
node.path[pos + 1..].to_string()
} else {
node.path.clone()
};
Ok(Edge {
label: label,
node: Arc::new(node),
})
}
}