<commit_before>use crate::methods::utils::derefs_to_slice;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{get_parent_expr, higher};
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::symbol::sym;

use super::ITER_NEXT_SLICE;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
    let caller_expr = &iter_args[0];

    // Skip lint if the `iter().next()` expression is a for loop argument,
    // since it is already covered by `&loops::ITER_NEXT_LOOP`
    let mut parent_expr_opt = get_parent_expr(cx, expr);
    while let Some(parent_expr) = parent_expr_opt {
        if higher::for_loop(parent_expr).is_some() {
            return;
        }
        parent_expr_opt = get_parent_expr(cx, parent_expr);
    }

    if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {
        // caller is a Slice
        if_chain! {
            if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind;
            if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
                = higher::range(index_expr);
            if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind;
            if let ast::LitKind::Int(start_idx, _) = start_lit.node;
            then {
                let mut applicability = Applicability::MachineApplicable;
                span_lint_and_sugg(
                    cx,
                    ITER_NEXT_SLICE,
                    expr.span,
                    "using `.iter().next()` on a Slice without end index",
                    "try calling",
                    format!("{}.get({})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability), start_idx),
                    applicability,
                );
            }
        }
    } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(caller_expr), sym::vec_type)
        || matches!(
            &cx.typeck_results().expr_ty(caller_expr).peel_refs().kind(),
            ty::Array(_, _)
        )
    {
        // caller is a Vec or an Array
        let mut applicability = Applicability::MachineApplicable;
        span_lint_and_sugg(
            cx,
            ITER_NEXT_SLICE,
            expr.span,
            "using `.iter().next()` on an array",
            "try calling",
            format!(
                "{}.get(0)",
                snippet_with_applicability(cx, caller_expr.span, "..", &mut applicability)
            ),
            applicability,
        );
    }
}
<commit_msg>extract a condition into a function.<commit_after>use crate::methods::utils::derefs_to_slice;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{get_parent_expr, higher};
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::symbol::sym;

use super::ITER_NEXT_SLICE;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
    let caller_expr = &iter_args[0];

    // Skip lint if the `iter().next()` expression is a for loop argument,
    // since it is already covered by `&loops::ITER_NEXT_LOOP`
    let mut parent_expr_opt = get_parent_expr(cx, expr);
    while let Some(parent_expr) = parent_expr_opt {
        if higher::for_loop(parent_expr).is_some() {
            return;
        }
        parent_expr_opt = get_parent_expr(cx, parent_expr);
    }

    if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {
        // caller is a Slice
        if_chain! {
            if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind;
            if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
                = higher::range(index_expr);
            if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind;
            if let ast::LitKind::Int(start_idx, _) = start_lit.node;
            then {
                let mut applicability = Applicability::MachineApplicable;
                span_lint_and_sugg(
                    cx,
                    ITER_NEXT_SLICE,
                    expr.span,
                    "using `.iter().next()` on a Slice without end index",
                    "try calling",
                    format!("{}.get({})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability), start_idx),
                    applicability,
                );
            }
        }
    } else if is_vec_or_array(cx, caller_expr) {
        // caller is a Vec or an Array
        let mut applicability = Applicability::MachineApplicable;
        span_lint_and_sugg(
            cx,
            ITER_NEXT_SLICE,
            expr.span,
            "using `.iter().next()` on an array",
            "try calling",
            format!(
                "{}.get(0)",
                snippet_with_applicability(cx, caller_expr.span, "..", &mut applicability)
            ),
            applicability,
        );
    }
}

fn is_vec_or_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) -> bool {
    is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::vec_type)
        || matches!(&cx.typeck_results().expr_ty(expr).peel_refs().kind(), ty::Array(_, _))
}
<|endoftext|>


<commit_before>//! It's a tree!

use std::ptr;

use rustwlc::WlcView;

use super::container::*;

#[derive(Debug, PartialEq, Eq)]
pub struct Node {
    // We need a mut pointer so we can modify the parent
    parent: *mut Node,
    val: Container,
    children: Vec<Node>
}

impl Node {
    /// Create a new node with the existing value.
    /// For root-style constructors.
    pub fn new(val: Container) -> Node {
        Node {
            parent: ptr::null_mut(),
            val: val,
            children: Vec::new()
        }
    }

    /// Add a new child node to this node, using a value
    pub fn new_child(&mut self, val: Container) -> Result<&mut Node, String> {
        if ! self.val.get_type().can_have_child(val.get_type()) {
            return Err(format!("{:?}({:?}) cannot be a child of {:?}({:?})",
                               val, val.get_type(),
                               self.val, self.val.get_type()));
        }
        let self_mut = self as *mut Node;
        self.children.push(Node {
            parent: self_mut,
            val: val,
            children: Vec::new()
        });
        let last_ix = self.children.len() -1;
        Ok(&mut self.children[last_ix])
    }

    /// Adds an already existing Node to the tree
    pub fn add_child(&mut self, mut node: Node) -> Result<&mut Node, String> {
        if ! self.val.get_type().can_have_child(node.get_val().get_type()) {
            return Err(format!("{:?}({:?}) cannot be a child of {:?}({:?})",
                               node.get_val(), node.get_val().get_type(),
                               self.val, self.val.get_type()));
        }
        node.parent = self as *mut Node;
        self.children.push(node);
        let last_ix = self.children.len() - 1;
        Ok(&mut self.children[last_ix])
    }

    /// Whether this node has a (currently-reachable) parent
    #[allow(dead_code)]
    pub fn has_parent(&self) -> bool {
        !self.parent.is_null()
    }

    /// Gets the type of container this node holds
    pub fn get_container_type(&self) -> ContainerType {
        self.val.get_type()
    }

    /// Tries to get an ancestor of the requested type
    pub fn get_ancestor_of_type(&self, container_type: ContainerType)
                                -> Option<&Node> {
        let mut maybe_parent = self.get_parent();
        loop {
            if let Some(parent) = maybe_parent {
                if parent.get_container_type() == container_type {
                    return Some(parent);
                }
                maybe_parent = parent.get_parent();
            }
            else {
                return None;
            }
        }
    }

    /// Tries to get a descendant of the requested type
    pub fn get_descendant_of_type(&self, container_type: ContainerType)
                                 -> Option<&Node> {
        let current_node = self;
        loop {
            if current_node.get_children().len() > 0 {
                for child in current_node.get_children() {
                    if let Some(descendant) = child.get_descendant_of_type(container_type) {
                        return Some(descendant)
                    }
                }
            } else if current_node.get_container_type() == container_type {
                return Some(current_node)
            } else {
                return None
            }
        }
    }

    /// Gets a node by handle
    pub fn find_view_by_handle(&self, view_handle: &WlcView) -> Option<&Node>{
        match self.get_val() {
            &Container::View { ref handle, .. } => {
                if view_handle == handle {
                    Some(self)
                } else {
                    None
                }
            },
            _ => {
                for child in self.get_children() {
                    if let Some(view) = child.find_view_by_handle(view_handle) {
                        return Some(view);
                    }
                }
                return None;
            }
        }
    }

    /// Gets the parent of this node (if it exists)
    pub fn get_parent(&self) -> Option<&mut Node> {
        if self.parent.is_null() {
            return None;
        }
        unsafe {
            return Some(&mut *self.parent);
        }
    }

    /// Borrow the children of this node.
    pub fn get_children(&self) -> &[Node] {
        &self.children
    }

    /// Mutably borrow the children of this mutable node
    pub fn get_children_mut(&mut self) -> &mut[Node] {
        &mut self.children
    }

    /// Remove a child at the given index
    #[allow(dead_code)]
    pub fn remove_child_at(&mut self, index: usize) -> Option<Node> {
        if index > self.children.len() - 1 {
            return None;
        }
        let mut child = self.children.remove(index);
        child.parent = ptr::null_mut();
        return Some(child);
    }

    /// Moves another node to be a sibling of this node.
    #[allow(dead_code)]
    pub fn add_sibling(&self, node: Node) -> Result<(), ()> {
        if let Some(parent) = self.get_parent() {
            node.move_to(parent);
            Ok(())
        }
        else {
            Err(())
        }
    }

    /// Whether this node is a parent of another node
    #[allow(dead_code)]
    pub fn is_parent_of(&self, other: &Node) -> bool {
        // Fun fact, other.parent == self as *const Node won't compile
        self as *const Node == other.parent
    }

    /// Remove a node from its parent.
    /// This method will mutate the parent if it exists.
    pub fn remove_from_parent(&mut self) -> Option<Node> {
        let mut result: Option<Node> = None;
        if let Some(mut parent) = self.get_parent() {
            if let Some(index) = parent.children.iter().position(|c| c == self) {
                result = Some(parent.children.remove(index));
            }
        }
        self.parent = ptr::null_mut();
        result
    }

    /// Removes a child from self
    #[allow(dead_code)]
    pub fn remove_child(&mut self, other: &Node) -> Option<Node> {
        if let Some(index) = self.children.iter().position(|c| c == other) {
            let mut child = self.children.remove(index);
            child.parent = ptr::null_mut();
            Some(child)
        }
        else {
            None
        }
    }

    /// Removes this node from its current parent and adds it to the given node
    /// as a child
    pub fn move_to(mut self, new_parent: &mut Node) {
        self.remove_from_parent();
        self.parent = new_parent as *mut Node;
        new_parent.children.push(self);
    }

    /// Gets the container that this node has
    pub fn get_val(&self) -> &Container {
        &self.val
    }

    /// Sets the visibility of the container and its children
    pub fn set_visibility(&mut self, visibility: bool) {
        self.val.set_visibility(visibility);
        for child in self.get_children_mut() {
            child.set_visibility(visibility);
        }
    }

    /// Attempts to get the Node as a mutable reference by going through it's
    /// child to get a mutable reference to it.
    ///
    /// # Unsafety
    /// The borrow checker can not properly infer that you are taking the Node
    /// as both mutable an immutable, so it is possible to invalidate the
    /// reference that you are using to call this method.
    pub unsafe fn as_mut<'a>(&'a self) -> &'a mut Node {
        let maybe_parent = self.get_parent();
        if maybe_parent.is_some() {
            let parent: &'a mut Node = self.get_parent().unwrap();
                for child in parent.get_children_mut() {
                    if *child == *self {
                        return child;
                    }
                };
        }
        // Error, give reason why
        if self.get_val().get_type() == ContainerType::Root {
            panic!("Tried to take as_mut of root")
        } else {
            panic!("Tried to take as_mut of a node not in the tree")
        }
    }
}

impl Drop for Node {
    fn drop(&mut self) {
        // We own the view, so we close it if we lose the Node
        if self.get_container_type() == ContainerType::View {
            if let Some(handle) = self.get_val().get_handle() {
                match handle {
                    Handle::View(view) => view.close(),
                    _ => {},
                }
            }
        }
    }
}

unsafe impl Sync for Node {}
unsafe impl Send for Node {}

#[cfg(test)]
mod tests {
    use rustwlc::*;
    const FAKE_GEOMETRY: Geometry = Geometry {
        size: Size { w: 0, h:0 },
        origin: Point { x: 0, y: 0}
    };
    use super::Node;
    use super::super::container::*;

    /// Nodes can have children added to them
    #[test]
    fn new_child() {
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap(); // This is okay
        {
            let mut third_child = root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            third_child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            //root.new_child(Root); // Have to wait for 3rd child to drop
        }
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap(); // Now this works
        assert_eq!(root.children.len(), 4);
    }

    #[test]
    fn has_get_parent() {
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        assert!(!root.has_parent(), "Root has a parent");
        assert_eq!(root.get_parent(), None);

        let child = root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        assert!(child.has_parent(), "Child does not have parent");
        assert!(child.get_parent().is_some(), "Child does not have parent");
        let parent = child.get_parent().expect("Asserted child has parent");
        assert_eq!(parent.get_container_type(), ContainerType::Container);
    }

    #[test]
    fn get_container_type() {
        use rustwlc::*;
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        assert_eq!(root.get_container_type(), ContainerType::Container);
        {
            let wksp = root.new_child(
                Container::new_view(WlcView::root())).unwrap();
            assert_eq!(wksp.get_container_type(), ContainerType::View);
        }
        {
            let container = root.new_child(Container::Container {
                layout: Layout::Horizontal, visible: false,
                floating: false, focused: false, geometry: Geometry {
                    size: Size { w: 0, h: 0},
                    origin: Point {x: 0, y: 0}
                }
            }).unwrap();
            assert_eq!(container.get_container_type(), ContainerType::Container);
        }
    }

    #[test]
    fn get_children() {
        // Create a root with 3 children. The 3rd child has 2 children.
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        {
            let third_child = root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            third_child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            third_child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        }
        let root_children = root.get_children();
        assert!(!root_children.is_empty(), "Root has children");
        assert_eq!(root_children.len(), 3);
        assert!(root_children.last().is_some(), "Root has final child");
        let third_child = root_children.last().expect("Asserted unwrap!");
        assert_eq!(third_child.get_children().len(), 2);
        let third_child_second_child = third_child.get_children().last()
            .expect("Asserted unwrap!");
        assert!(third_child_second_child.get_children().is_empty(),
                "Grandchild doesn't have children");
    }

    #[test]
    fn get_children_mut() {
        // Start out with one child, use get_mut_children to add grandchild.
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();

        assert!(root.get_children().last().expect("Root has child")
                .get_children().is_empty(), "Root has no grandchildren");

        {
            let mut children = root.get_children_mut();
            assert_eq!(children.len(), 1);

            let mut child = &mut children[0];
            child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        }

        assert_eq!(root.get_children().last().expect("Asserted unwrap!")
                .get_children().len(), 1);
    }

    #[test]
    fn remove_child_at() {
        use rustwlc::handle::*;
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        root.new_child(Container::new_view(WlcView::root())).unwrap();
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();

        let worksp = root.remove_child_at(1).expect("Index should be valid");
        assert_eq!(worksp.get_container_type(), ContainerType::View);
        assert_eq!(root.get_children().len(), 2)
    }
}
<commit_msg>Fixed memory issue. Choo choo, all aboard the unsaftey train<commit_after>//! It's a tree!

use std::ptr;

use rustwlc::WlcView;

use super::container::*;

#[derive(Debug, PartialEq, Eq)]
pub struct Node {
    // We need a mut pointer so we can modify the parent
    parent: *mut Node,
    val: Container,
    children: Vec<Node>
}

impl Node {
    /// Create a new node with the existing value.
    /// For root-style constructors.
    pub fn new(val: Container) -> Node {
        Node {
            parent: ptr::null_mut(),
            val: val,
            children: Vec::new()
        }
    }

    /// Add a new child node to this node, using a value
    pub fn new_child(&mut self, val: Container) -> Result<&mut Node, String> {
        if ! self.val.get_type().can_have_child(val.get_type()) {
            return Err(format!("{:?}({:?}) cannot be a child of {:?}({:?})",
                               val, val.get_type(),
                               self.val, self.val.get_type()));
        }
        let self_mut = self as *mut Node;
        self.children.push(Node {
            parent: self_mut,
            val: val,
            children: Vec::new()
        });
        let last_ix = self.children.len() -1;
        Ok(&mut self.children[last_ix])
    }

    /// Adds an already existing Node to the tree
    pub fn add_child(&mut self, mut node: Node) -> Result<&mut Node, String> {
        if ! self.val.get_type().can_have_child(node.get_val().get_type()) {
            return Err(format!("{:?}({:?}) cannot be a child of {:?}({:?})",
                               node.get_val(), node.get_val().get_type(),
                               self.val, self.val.get_type()));
        }
        node.parent = self as *mut Node;
        self.children.push(node);
        let last_ix = self.children.len() - 1;
        Ok(&mut self.children[last_ix])
    }

    /// Whether this node has a (currently-reachable) parent
    #[allow(dead_code)]
    pub fn has_parent(&self) -> bool {
        !self.parent.is_null()
    }

    /// Gets the type of container this node holds
    pub fn get_container_type(&self) -> ContainerType {
        self.val.get_type()
    }

    /// Tries to get an ancestor of the requested type
    pub fn get_ancestor_of_type(&self, container_type: ContainerType)
                                -> Option<&Node> {
        let mut maybe_parent = self.get_parent();
        loop {
            if let Some(parent) = maybe_parent {
                if parent.get_container_type() == container_type {
                    return Some(parent);
                }
                maybe_parent = parent.get_parent();
            }
            else {
                return None;
            }
        }
    }

    /// Tries to get a descendant of the requested type
    pub fn get_descendant_of_type(&self, container_type: ContainerType)
                                 -> Option<&Node> {
        let current_node = self;
        loop {
            if current_node.get_children().len() > 0 {
                for child in current_node.get_children() {
                    if let Some(descendant) = child.get_descendant_of_type(container_type) {
                        return Some(descendant)
                    }
                }
            } else if current_node.get_container_type() == container_type {
                return Some(current_node)
            } else {
                return None
            }
        }
    }

    /// Gets a node by handle
    pub fn find_view_by_handle(&self, view_handle: &WlcView) -> Option<&Node>{
        match self.get_val() {
            &Container::View { ref handle, .. } => {
                if view_handle == handle {
                    Some(self)
                } else {
                    None
                }
            },
            _ => {
                for child in self.get_children() {
                    if let Some(view) = child.find_view_by_handle(view_handle) {
                        return Some(view);
                    }
                }
                return None;
            }
        }
    }

    /// Gets the parent of this node (if it exists)
    pub fn get_parent(&self) -> Option<&mut Node> {
        if self.parent.is_null() {
            return None;
        }
        unsafe {
            return Some(&mut *self.parent);
        }
    }

    /// Borrow the children of this node.
    pub fn get_children(&self) -> &[Node] {
        &self.children
    }

    /// Mutably borrow the children of this mutable node
    pub fn get_children_mut(&mut self) -> &mut[Node] {
        &mut self.children
    }

    /// Remove a child at the given index
    #[allow(dead_code)]
    pub fn remove_child_at(&mut self, index: usize) -> Option<Node> {
        if index > self.children.len() - 1 {
            return None;
        }
        let mut child = self.children.remove(index);
        child.parent = ptr::null_mut();
        return Some(child);
    }

    /// Moves another node to be a sibling of this node.
    #[allow(dead_code)]
    pub fn add_sibling(&self, node: Node) -> Result<(), ()> {
        if let Some(parent) = self.get_parent() {
            node.move_to(parent);
            Ok(())
        }
        else {
            Err(())
        }
    }

    /// Whether this node is a parent of another node
    #[allow(dead_code)]
    pub fn is_parent_of(&self, other: &Node) -> bool {
        // Fun fact, other.parent == self as *const Node won't compile
        self as *const Node == other.parent
    }

    /// Remove a node from its parent.
    /// This method will mutate the parent if it exists.
    pub fn remove_from_parent(&mut self) -> Option<Node> {
        if let Some(mut parent) = self.get_parent() {
            if let Some(index) = parent.children.iter().position(|c| c == self) {
                // MOVES SELF OUT
                // DO NOT USE SELF AFTER THIS, IS UNDEFINED BEHAVIOR
                let mut node = parent.children.remove(index);
                node.parent = ptr::null_mut();
                return Some(node);
            }
        }
        return None;
    }

    /// Removes a child from self
    #[allow(dead_code)]
    pub fn remove_child(&mut self, other: &Node) -> Option<Node> {
        if let Some(index) = self.children.iter().position(|c| c == other) {
            let mut child = self.children.remove(index);
            child.parent = ptr::null_mut();
            Some(child)
        }
        else {
            None
        }
    }

    /// Removes this node from its current parent and adds it to the given node
    /// as a child
    pub fn move_to(mut self, new_parent: &mut Node) {
        self.remove_from_parent();
        self.parent = new_parent as *mut Node;
        new_parent.children.push(self);
    }

    /// Gets the container that this node has
    pub fn get_val(&self) -> &Container {
        &self.val
    }

    /// Sets the visibility of the container and its children
    pub fn set_visibility(&mut self, visibility: bool) {
        self.val.set_visibility(visibility);
        for child in self.get_children_mut() {
            child.set_visibility(visibility);
        }
    }

    /// Attempts to get the Node as a mutable reference by going through it's
    /// child to get a mutable reference to it.
    ///
    /// # Unsafety
    /// The borrow checker can not properly infer that you are taking the Node
    /// as both mutable an immutable, so it is possible to invalidate the
    /// reference that you are using to call this method.
    pub unsafe fn as_mut<'a>(&'a self) -> &'a mut Node {
        let maybe_parent = self.get_parent();
        if maybe_parent.is_some() {
            let parent: &'a mut Node = self.get_parent().unwrap();
                for child in parent.get_children_mut() {
                    if *child == *self {
                        return child;
                    }
                };
        }
        // Error, give reason why
        if self.get_val().get_type() == ContainerType::Root {
            panic!("Tried to take as_mut of root")
        } else {
            panic!("Tried to take as_mut of a node not in the tree")
        }
    }
}

impl Drop for Node {
    fn drop(&mut self) {
        // We own the view, so we close it if we lose the Node
        if self.get_container_type() == ContainerType::View {
            if let Some(handle) = self.get_val().get_handle() {
                match handle {
                    Handle::View(view) => view.close(),
                    _ => {},
                }
            }
        }
    }
}

unsafe impl Sync for Node {}
unsafe impl Send for Node {}

#[cfg(test)]
mod tests {
    use rustwlc::*;
    const FAKE_GEOMETRY: Geometry = Geometry {
        size: Size { w: 0, h:0 },
        origin: Point { x: 0, y: 0}
    };
    use super::Node;
    use super::super::container::*;

    /// Nodes can have children added to them
    #[test]
    fn new_child() {
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap(); // This is okay
        {
            let mut third_child = root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            third_child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            //root.new_child(Root); // Have to wait for 3rd child to drop
        }
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap(); // Now this works
        assert_eq!(root.children.len(), 4);
    }

    #[test]
    fn has_get_parent() {
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        assert!(!root.has_parent(), "Root has a parent");
        assert_eq!(root.get_parent(), None);

        let child = root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        assert!(child.has_parent(), "Child does not have parent");
        assert!(child.get_parent().is_some(), "Child does not have parent");
        let parent = child.get_parent().expect("Asserted child has parent");
        assert_eq!(parent.get_container_type(), ContainerType::Container);
    }

    #[test]
    fn get_container_type() {
        use rustwlc::*;
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        assert_eq!(root.get_container_type(), ContainerType::Container);
        {
            let wksp = root.new_child(
                Container::new_view(WlcView::root())).unwrap();
            assert_eq!(wksp.get_container_type(), ContainerType::View);
        }
        {
            let container = root.new_child(Container::Container {
                layout: Layout::Horizontal, visible: false,
                floating: false, focused: false, geometry: Geometry {
                    size: Size { w: 0, h: 0},
                    origin: Point {x: 0, y: 0}
                }
            }).unwrap();
            assert_eq!(container.get_container_type(), ContainerType::Container);
        }
    }

    #[test]
    fn get_children() {
        // Create a root with 3 children. The 3rd child has 2 children.
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        {
            let third_child = root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            third_child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
            third_child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        }
        let root_children = root.get_children();
        assert!(!root_children.is_empty(), "Root has children");
        assert_eq!(root_children.len(), 3);
        assert!(root_children.last().is_some(), "Root has final child");
        let third_child = root_children.last().expect("Asserted unwrap!");
        assert_eq!(third_child.get_children().len(), 2);
        let third_child_second_child = third_child.get_children().last()
            .expect("Asserted unwrap!");
        assert!(third_child_second_child.get_children().is_empty(),
                "Grandchild doesn't have children");
    }

    #[test]
    fn get_children_mut() {
        // Start out with one child, use get_mut_children to add grandchild.
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();

        assert!(root.get_children().last().expect("Root has child")
                .get_children().is_empty(), "Root has no grandchildren");

        {
            let mut children = root.get_children_mut();
            assert_eq!(children.len(), 1);

            let mut child = &mut children[0];
            child.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        }

        assert_eq!(root.get_children().last().expect("Asserted unwrap!")
                .get_children().len(), 1);
    }

    #[test]
    fn remove_child_at() {
        use rustwlc::handle::*;
        let mut root = Node::new(Container::new_container(FAKE_GEOMETRY));
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();
        root.new_child(Container::new_view(WlcView::root())).unwrap();
        root.new_child(Container::new_container(FAKE_GEOMETRY)).unwrap();

        let worksp = root.remove_child_at(1).expect("Index should be valid");
        assert_eq!(worksp.get_container_type(), ContainerType::View);
        assert_eq!(root.get_children().len(), 2)
    }
}
<|endoftext|>


<commit_before>//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
//! and the `AsyncRead` and `AsyncWrite` traits.

#![feature(pin, arbitrary_self_types)]

#![no_std]
#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/futures/0.1")]

#[cfg(test)]
extern crate futures_channel;
#[macro_use]
extern crate futures_core;
#[cfg(test)]
extern crate futures_executor;

extern crate futures_io;
extern crate futures_sink;

extern crate either;

#[cfg(feature = "std")]
use futures_core::{Future, Poll, task};

macro_rules! if_std {
    ($($i:item)*) => ($(
        #[cfg(feature = "std")]
        $i
    )*)
}

#[cfg(feature = "std")]
//#[macro_use]
extern crate std;

macro_rules! delegate_sink {
    ($field:ident) => {
        fn poll_ready(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
            self.$field().poll_ready(cx)
        }

        fn start_send(mut self: PinMut<Self>, item: Self::SinkItem) -> Result<(), Self::SinkError> {
            self.$field().start_send(item)
        }

        fn poll_flush(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
            self.$field().poll_flush(cx)
        }

        fn poll_close(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
            self.$field().poll_close(cx)
        }

    }
}

#[cfg(all(feature = "std", any(test, feature = "bench")))]
pub mod lock;
#[cfg(all(feature = "std", not(any(test, feature = "bench"))))]
mod lock;

pub mod future;
pub use future::FutureExt;

pub mod try_future;
pub use try_future::TryFutureExt;

#[cfg(feature = "std")]
pub mod io;
#[cfg(feature = "std")]
pub use io::{AsyncReadExt, AsyncWriteExt};

pub mod stream;
pub use stream::StreamExt;

pub mod sink;
pub use sink::SinkExt;

pub mod prelude {
    //! Prelude containing the extension traits, which add functionality to
    //! existing asynchronous types.
    // pub use {FutureExt, StreamExt, SinkExt};
    // #[cfg(feature = "std")]
    // pub use {AsyncReadExt, AsyncWriteExt};
}
<commit_msg>stdify futures-util<commit_after>//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
//! and the `AsyncRead` and `AsyncWrite` traits.

#![feature(pin, arbitrary_self_types, futures_api)]

#![no_std]
#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/futures/0.1")]

#[cfg(test)]
extern crate futures_channel;
#[macro_use]
extern crate futures_core;
#[cfg(test)]
extern crate futures_executor;

extern crate futures_io;
extern crate futures_sink;

extern crate either;

#[cfg(feature = "std")]
use futures_core::{Future, Poll, task};

macro_rules! if_std {
    ($($i:item)*) => ($(
        #[cfg(feature = "std")]
        $i
    )*)
}

#[cfg(feature = "std")]
//#[macro_use]
extern crate std;

macro_rules! delegate_sink {
    ($field:ident) => {
        fn poll_ready(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
            self.$field().poll_ready(cx)
        }

        fn start_send(mut self: PinMut<Self>, item: Self::SinkItem) -> Result<(), Self::SinkError> {
            self.$field().start_send(item)
        }

        fn poll_flush(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
            self.$field().poll_flush(cx)
        }

        fn poll_close(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
            self.$field().poll_close(cx)
        }

    }
}

#[cfg(all(feature = "std", any(test, feature = "bench")))]
pub mod lock;
#[cfg(all(feature = "std", not(any(test, feature = "bench"))))]
mod lock;

pub mod future;
pub use future::FutureExt;

pub mod try_future;
pub use try_future::TryFutureExt;

#[cfg(feature = "std")]
pub mod io;
#[cfg(feature = "std")]
pub use io::{AsyncReadExt, AsyncWriteExt};

pub mod stream;
pub use stream::StreamExt;

pub mod sink;
pub use sink::SinkExt;

pub mod prelude {
    //! Prelude containing the extension traits, which add functionality to
    //! existing asynchronous types.
    // pub use {FutureExt, StreamExt, SinkExt};
    // #[cfg(feature = "std")]
    // pub use {AsyncReadExt, AsyncWriteExt};
}
<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(never_type)]

fn foo(x: usize, y: !, z: usize) { }

fn call_foo_a() {
    foo(return, 22, 44);
    //~^ ERROR mismatched types
}

fn call_foo_b() {
    // Divergence happens in the argument itself, definitely ok.
    foo(22, return, 44);
}

fn call_foo_c() {
    // This test fails because the divergence happens **after** the
    // coercion to `!`:
    foo(22, 44, return); //~ ERROR mismatched types
}

fn call_foo_d() {
    // This test passes because `a` has type `!`:
    let a: ! = return;
    let b = 22;
    let c = 44;
    foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
    //~^ ERROR mismatched types
}

fn call_foo_e() {
    // This test probably could pass but we don't *know* that `a`
    // has type `!` so we don't let it work.
    let a = return;
    let b = 22;
    let c = 44;
    foo(a, b, c); //~ ERROR mismatched types
}

fn call_foo_f() {
    // This fn fails because `a` has type `usize`, and hence a
    // reference to is it **not** considered to diverge.
    let a: usize = return;
    let b = 22;
    let c = 44;
    foo(a, b, c); //~ ERROR mismatched types
}

fn array_a() {
    // Accepted: return is coerced to `!` just fine, and then `22` can be
    // because we already diverged.
    let x: [!; 2] = [return, 22];
}

fn array_b() {
    // Error: divergence has not yet occurred.
    let x: [!; 2] = [22, return]; //~ ERROR mismatched types
}

fn tuple_a() {
    // No divergence at all.
    let x: (usize, !, usize) = (22, 44, 66); //~ ERROR mismatched types
}

fn tuple_b() {
    // Divergence happens before coercion: OK
    let x: (usize, !, usize) = (return, 44, 66);
    //~^ ERROR mismatched types
}

fn tuple_c() {
    // Divergence happens before coercion: OK
    let x: (usize, !, usize) = (22, return, 66);
}

fn tuple_d() {
    // Error: divergence happens too late
    let x: (usize, !, usize) = (22, 44, return); //~ ERROR mismatched types
}

fn main() { }
<commit_msg>Fix coerce-to-bang test<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(never_type)]

fn foo(x: usize, y: !, z: usize) { }

fn call_foo_a() {
    foo(return, 22, 44);
    //~^ ERROR mismatched types
}

fn call_foo_b() {
    // Divergence happens in the argument itself, definitely ok.
    foo(22, return, 44);
}

fn call_foo_c() {
    // This test fails because the divergence happens **after** the
    // coercion to `!`:
    foo(22, 44, return); //~ ERROR mismatched types
}

fn call_foo_d() {
    // This test passes because `a` has type `!`:
    let a: ! = return;
    let b = 22;
    let c = 44;
    foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
    //~^ ERROR mismatched types
}

fn call_foo_e() {
    // This test probably could pass but we don't *know* that `a`
    // has type `!` so we don't let it work.
    let a = return;
    let b = 22;
    let c = 44;
    foo(a, b, c); //~ ERROR mismatched types
}

fn call_foo_f() {
    // This fn fails because `a` has type `usize`, and hence a
    // reference to is it **not** considered to diverge.
    let a: usize = return;
    let b = 22;
    let c = 44;
    foo(a, b, c); //~ ERROR mismatched types
}

fn array_a() {
    // Accepted: return is coerced to `!` just fine, but `22` cannot be.
    let x: [!; 2] = [return, 22]; //~ ERROR mismatched types
}

fn array_b() {
    // Error: divergence has not yet occurred.
    let x: [!; 2] = [22, return]; //~ ERROR mismatched types
}

fn tuple_a() {
    // No divergence at all.
    let x: (usize, !, usize) = (22, 44, 66); //~ ERROR mismatched types
}

fn tuple_b() {
    // Divergence happens before coercion: OK
    let x: (usize, !, usize) = (return, 44, 66);
    //~^ ERROR mismatched types
}

fn tuple_c() {
    // Divergence happens before coercion: OK
    let x: (usize, !, usize) = (22, return, 66);
}

fn tuple_d() {
    // Error: divergence happens too late
    let x: (usize, !, usize) = (22, 44, return); //~ ERROR mismatched types
}

fn main() { }
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(const_fn)]

const X : usize = 2;

const fn f(x: usize) -> usize {
    let mut sum = 0;
    for i in 0..x {
        //~^ ERROR E0015
        //~| ERROR E0019
        //~| ERROR E0080
        sum += i;
    }
    sum
}

#[allow(unused_variables)]
fn main() {
    let a : [i32; f(X)];
}
<commit_msg>Fix a compile-fail test<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(const_fn, const_let)]

const X : usize = 2;

const fn f(x: usize) -> usize {
    let mut sum = 0;
    for i in 0..x {
        //~^ ERROR E0015
        //~| ERROR E0019
        //~| ERROR E0080
        sum += i;
    }
    sum
}

#[allow(unused_variables)]
fn main() {
    let a : [i32; f(X)];
}
<|endoftext|>


<commit_before><commit_msg>Remove code duplication with sink responses.<commit_after><|endoftext|>


<commit_before>// "Tifflin" Kernel
// - By John Hodge (thePowersGang)
//
// Modules/fs_fat/dir.rs
use kernel::prelude::*;
use kernel::lib::mem::aref::ArefBorrow;
use kernel::vfs::node;
use kernel::lib::byte_str::{ByteStr,ByteString};
use super::on_disk;
use super::file::FileNode;
use super::ClusterList;

pub type FilesystemInner = super::FilesystemInner;

pub struct DirNode
{
	fs: ArefBorrow<FilesystemInner>,
	start_cluster: u32,
	// - Uses the cluster chain
}

impl DirNode {
	pub fn new(fs: ArefBorrow<FilesystemInner>, start_cluster: u32) -> DirNode {
		DirNode {
			fs: fs,
			start_cluster: start_cluster,
		}
	}
	pub fn new_boxed(fs: ArefBorrow<FilesystemInner>, start_cluster: u32) -> Box<DirNode> {
		Box::new(Self::new(fs, start_cluster))
	}
}

impl node::NodeBase for DirNode {
	fn get_id(&self) -> node::InodeId {
		todo!("")
	}
}

impl DirNode {
	fn is_fixed_root(&self) -> bool {
		!is!(self.fs.ty, super::Size::Fat32) && self.start_cluster == self.fs.root_first_cluster
	}
	fn clusters(&self) -> ClusterList {
		if self.is_fixed_root() {
			let root_cluster_count = (self.fs.root_sector_count as usize + self.fs.spc-1) / self.fs.spc;
			ClusterList::Range(self.fs.root_first_cluster .. self.fs.root_first_cluster + root_cluster_count as u32)
		}
		else {
			ClusterList::Chained(self.fs.reborrow(), self.start_cluster)
		}
	}

	/// Locate a node in this directory by its first data cluster
	pub fn find_node(&self, ent_cluster: u32) -> Option<node::Node>
	{
		match self.find_ent_by_cluster(ent_cluster)
		{
		None => None,
		Some(e) =>
			if e.attributes & on_disk::ATTR_DIRECTORY != 0 {
				Some(node::Node::Dir(DirNode::new_boxed(self.fs.reborrow(), ent_cluster)))
			}
			else if e.attributes & on_disk::ATTR_VOLUMEID != 0 {
				None
			}
			else {
				Some(node::Node::File(FileNode::new_boxed(
					self.fs.reborrow(), self.start_cluster, ent_cluster, e.size
					)))
			},
		}
	}

	fn find_ent_by_cluster(&self, ent_cluster: u32) -> Option<DirEntShort> {
		for c in self.clusters()
		{
			let cluster = match self.fs.load_cluster(c) {
				Ok(v) => v,
				Err(_) => return None,
				};
			for ent in DirEnts::new(&cluster) {
				if let DirEnt::Short(e) = ent {
					if e.cluster == ent_cluster {
						return Some(e);
					}
				}
			}
		}
		None
	}
}

/// Iterator over directory entries
struct DirEnts<'a>
{
	cluster: &'a [u8],
	ofs: usize,
}

/// Directory entry returned by the DirEnts iterator
#[derive(Debug)]
enum DirEnt {
	End,
	Empty,
	Short(DirEntShort),
	Long(DirEntLong),
}
#[derive(Debug)]
struct DirEntShort {
	/// NUL-padded string with extention joined
	name: [u8; 11+1],
	cluster: u32,
	size: u32,
	attributes: u8,
	//creation_time: ::kernel::time::Timestamp,
	//modified_time: ::kernel::time::Timestamp,
	//accessed_time: ::kernel::time::Timestamp,
}
#[derive(Debug)]
struct DirEntLong {
	id: u8,
	_type: u8,
	chars: [u16; 13],
}
impl<'a> DirEnts<'a>
{
	fn new(data: &[u8]) -> DirEnts {
		assert_eq!(data.len() % 32, 0);
		DirEnts {
			cluster: data,
			ofs: 0,
		}
	}
}
impl<'a> ::core::iter::Iterator for DirEnts<'a> {
	type Item = DirEnt;
	fn next(&mut self) -> Option<DirEnt> {
		if self.ofs >= self.cluster.len() / 32 {
			None
		}
		else {
			let slice = &self.cluster[self.ofs*32..];
			self.ofs += 1;
			// Decode the legacy format entry
			let ent = on_disk::DirEnt::read(&mut &slice[..]);
			if ent.name[0] == 0 {
				Some(DirEnt::End)
			}
			else if ent.name[0] == b'\xE5' {
				Some(DirEnt::Empty)
			}
			else if ent.attribs == on_disk::ATTR_LFN {
				// Long filename entry
				let lfn = on_disk::DirEntLong::read(&mut &slice[..]);
				let outname = {
					let mut outname = [0u16; 13];
					outname[0..5].clone_from_slice(&lfn.name1);
					outname[5..11].clone_from_slice(&lfn.name2);
					outname[11..13].clone_from_slice(&lfn.name3);
					outname
					};
				Some(DirEnt::Long( DirEntLong{
					id: lfn.id,
					_type: lfn.ty,
					chars: outname,
					} ))
			}
			else {
				// Short entry
				// 1. Decode name into a NUL-padded string
				let (outname, _) = {
					let (mut outname, mut oidx) =  ([0u8; 8+1+3], 0);
					for iidx in (0 .. 8) {
						if ent.name[iidx] != b' ' {
							outname[oidx] = ent.name[iidx];
							oidx += 1;
						}
					}
					outname[oidx] = b'.';
					oidx += 1;
					for iidx in (8 .. 11) {
						if ent.name[iidx] != b' ' {
							outname[oidx] = ent.name[iidx];
							oidx += 1;
						}
					}
					if outname[oidx-1] == b'.' {
						outname[oidx-1] = 0;
						oidx -= 1;
					}
					(outname, oidx)
					};
				// 2. Cluster, Size, Attribs
				Some( DirEnt::Short(DirEntShort{
					name: outname,
					cluster: (ent.cluster as u32) | (ent.cluster_hi as u32) << 16,
					size: ent.size,
					attributes: ent.attribs,
					}) )
			}
		}
	}
}
impl DirEntShort {
	fn name(&self) -> &ByteStr {
		ByteStr::new( (&self.name).split(|&e|e==0).next().unwrap() )
	}
}

impl node::Dir for DirNode {
	fn lookup(&self, name: &ByteStr) -> node::Result<node::InodeId> {
		// For each cluster in the directory, iterate
		for c in self.clusters()
		{
			let cluster = try!(self.fs.load_cluster(c));
			for ent in DirEnts::new(&cluster) {
				log_debug!("ent = {:?}", ent);
				match ent {
				DirEnt::End => return Err(node::IoError::NotFound),
				DirEnt::Short(e) =>
					if e.name() == name {
						return Ok( super::InodeRef::new(e.cluster, self.start_cluster).to_id() );
					},
				DirEnt::Long(_) => log_log!("TODO: LFN"),
				DirEnt::Empty => {},
				}
			}
		}
		Err(node::IoError::NotFound)
	}
	fn read(&self, ofs: usize, items: &mut [(node::InodeId,ByteString)]) -> node::Result<(usize,usize)> {

		let ents_per_cluster = self.fs.cluster_size / 32;
		let cluster_idx = ofs / ents_per_cluster;
		let c_ofs = ofs % ents_per_cluster;
		let mut count = 0;
		// next_ofs is the return value, and is updated when a short entry is seen.
		let mut next_ofs = ofs+1;
		let mut cur_ofs = ofs;
		for c in self.clusters().skip(cluster_idx)
		{
			let cluster = try!(self.fs.load_cluster(c));
			for ent in DirEnts::new(&cluster).skip(c_ofs) {
				cur_ofs += 1;
				match ent {
				DirEnt::End => {
					// On next call, we want to hit this first shot
					next_ofs = cur_ofs-1;
					break;
					},
				DirEnt::Short(e) => {
					let i = super::InodeRef::new(e.cluster, self.start_cluster).to_id();
					items[count] = (i, ByteString::from(e.name()));
					count += 1;
					// Update return offset to be the next entry
					next_ofs = cur_ofs;
					if count == items.len() {
						break;
					}
					},
				DirEnt::Long(_) => log_log!("TODO: LFN"),
				DirEnt::Empty => {},
				}
			}
		}

		Ok( (next_ofs, count) )
	}
	fn create(&self, name: &ByteStr, nodetype: node::NodeType) -> node::Result<node::InodeId> {
		todo!("DirNode::create('{:?}', {:?})", name, nodetype);
	}
	fn link(&self, name: &ByteStr, inode: node::InodeId) -> node::Result<()> {
		todo!("DirNode::link('{:?}', {:#x})", name, inode);
	}
	fn unlink(&self, name: &ByteStr) -> node::Result<()> {
		todo!("DirNode::unlink('{:?}')", name);
	}
}

<commit_msg>Modules/FAT - Fix not terminating readdir on end marker<commit_after>// "Tifflin" Kernel
// - By John Hodge (thePowersGang)
//
// Modules/fs_fat/dir.rs
use kernel::prelude::*;
use kernel::lib::mem::aref::ArefBorrow;
use kernel::vfs::node;
use kernel::lib::byte_str::{ByteStr,ByteString};
use super::on_disk;
use super::file::FileNode;
use super::ClusterList;

pub type FilesystemInner = super::FilesystemInner;

pub struct DirNode
{
	fs: ArefBorrow<FilesystemInner>,
	start_cluster: u32,
	// - Uses the cluster chain
}

impl DirNode {
	pub fn new(fs: ArefBorrow<FilesystemInner>, start_cluster: u32) -> DirNode {
		DirNode {
			fs: fs,
			start_cluster: start_cluster,
		}
	}
	pub fn new_boxed(fs: ArefBorrow<FilesystemInner>, start_cluster: u32) -> Box<DirNode> {
		Box::new(Self::new(fs, start_cluster))
	}
}

impl node::NodeBase for DirNode {
	fn get_id(&self) -> node::InodeId {
		todo!("")
	}
}

impl DirNode {
	fn is_fixed_root(&self) -> bool {
		!is!(self.fs.ty, super::Size::Fat32) && self.start_cluster == self.fs.root_first_cluster
	}
	fn clusters(&self) -> ClusterList {
		if self.is_fixed_root() {
			let root_cluster_count = (self.fs.root_sector_count as usize + self.fs.spc-1) / self.fs.spc;
			ClusterList::Range(self.fs.root_first_cluster .. self.fs.root_first_cluster + root_cluster_count as u32)
		}
		else {
			ClusterList::Chained(self.fs.reborrow(), self.start_cluster)
		}
	}

	/// Locate a node in this directory by its first data cluster
	pub fn find_node(&self, ent_cluster: u32) -> Option<node::Node>
	{
		match self.find_ent_by_cluster(ent_cluster)
		{
		None => None,
		Some(e) =>
			if e.attributes & on_disk::ATTR_DIRECTORY != 0 {
				Some(node::Node::Dir(DirNode::new_boxed(self.fs.reborrow(), ent_cluster)))
			}
			else if e.attributes & on_disk::ATTR_VOLUMEID != 0 {
				None
			}
			else {
				Some(node::Node::File(FileNode::new_boxed(
					self.fs.reborrow(), self.start_cluster, ent_cluster, e.size
					)))
			},
		}
	}

	fn find_ent_by_cluster(&self, ent_cluster: u32) -> Option<DirEntShort> {
		for c in self.clusters()
		{
			let cluster = match self.fs.load_cluster(c) {
				Ok(v) => v,
				Err(_) => return None,
				};
			for ent in DirEnts::new(&cluster) {
				if let DirEnt::Short(e) = ent {
					if e.cluster == ent_cluster {
						return Some(e);
					}
				}
			}
		}
		None
	}
}

/// Iterator over directory entries
struct DirEnts<'a>
{
	cluster: &'a [u8],
	ofs: usize,
}

/// Directory entry returned by the DirEnts iterator
#[derive(Debug)]
enum DirEnt {
	End,
	Empty,
	Short(DirEntShort),
	Long(DirEntLong),
}
#[derive(Debug)]
struct DirEntShort {
	/// NUL-padded string with extention joined
	name: [u8; 11+1],
	cluster: u32,
	size: u32,
	attributes: u8,
	//creation_time: ::kernel::time::Timestamp,
	//modified_time: ::kernel::time::Timestamp,
	//accessed_time: ::kernel::time::Timestamp,
}
#[derive(Debug)]
struct DirEntLong {
	id: u8,
	_type: u8,
	chars: [u16; 13],
}
impl<'a> DirEnts<'a>
{
	fn new(data: &[u8]) -> DirEnts {
		assert_eq!(data.len() % 32, 0);
		DirEnts {
			cluster: data,
			ofs: 0,
		}
	}
}
impl<'a> ::core::iter::Iterator for DirEnts<'a> {
	type Item = DirEnt;
	fn next(&mut self) -> Option<DirEnt> {
		if self.ofs >= self.cluster.len() / 32 {
			None
		}
		else {
			let slice = &self.cluster[self.ofs*32..];
			self.ofs += 1;
			// Decode the legacy format entry
			let ent = on_disk::DirEnt::read(&mut &slice[..]);
			if ent.name[0] == 0 {
				Some(DirEnt::End)
			}
			else if ent.name[0] == b'\xE5' {
				Some(DirEnt::Empty)
			}
			else if ent.attribs == on_disk::ATTR_LFN {
				// Long filename entry
				let lfn = on_disk::DirEntLong::read(&mut &slice[..]);
				let outname = {
					let mut outname = [0u16; 13];
					outname[0..5].clone_from_slice(&lfn.name1);
					outname[5..11].clone_from_slice(&lfn.name2);
					outname[11..13].clone_from_slice(&lfn.name3);
					outname
					};
				Some(DirEnt::Long( DirEntLong{
					id: lfn.id,
					_type: lfn.ty,
					chars: outname,
					} ))
			}
			else {
				// Short entry
				// 1. Decode name into a NUL-padded string
				let (outname, _) = {
					let (mut outname, mut oidx) =  ([0u8; 8+1+3], 0);
					for iidx in (0 .. 8) {
						if ent.name[iidx] != b' ' {
							outname[oidx] = ent.name[iidx];
							oidx += 1;
						}
					}
					outname[oidx] = b'.';
					oidx += 1;
					for iidx in (8 .. 11) {
						if ent.name[iidx] != b' ' {
							outname[oidx] = ent.name[iidx];
							oidx += 1;
						}
					}
					if outname[oidx-1] == b'.' {
						outname[oidx-1] = 0;
						oidx -= 1;
					}
					(outname, oidx)
					};
				// 2. Cluster, Size, Attribs
				Some( DirEnt::Short(DirEntShort{
					name: outname,
					cluster: (ent.cluster as u32) | (ent.cluster_hi as u32) << 16,
					size: ent.size,
					attributes: ent.attribs,
					}) )
			}
		}
	}
}
impl DirEntShort {
	fn name(&self) -> &ByteStr {
		ByteStr::new( (&self.name).split(|&e|e==0).next().unwrap() )
	}
}

impl node::Dir for DirNode {
	fn lookup(&self, name: &ByteStr) -> node::Result<node::InodeId> {
		// For each cluster in the directory, iterate
		for c in self.clusters()
		{
			let cluster = try!(self.fs.load_cluster(c));
			for ent in DirEnts::new(&cluster) {
				log_debug!("ent = {:?}", ent);
				match ent {
				DirEnt::End => return Err(node::IoError::NotFound),
				DirEnt::Short(e) =>
					if e.name() == name {
						return Ok( super::InodeRef::new(e.cluster, self.start_cluster).to_id() );
					},
				DirEnt::Long(_) => log_log!("TODO: LFN"),
				DirEnt::Empty => {},
				}
			}
		}
		Err(node::IoError::NotFound)
	}
	fn read(&self, ofs: usize, items: &mut [(node::InodeId,ByteString)]) -> node::Result<(usize,usize)> {

		let ents_per_cluster = self.fs.cluster_size / 32;
		let cluster_idx = ofs / ents_per_cluster;
		let c_ofs = ofs % ents_per_cluster;
		let mut count = 0;
		// next_ofs is the return value, and is updated when a short entry is seen.
		let mut next_ofs = ofs+1;
		let mut cur_ofs = ofs;
		'outer: for c in self.clusters().skip(cluster_idx)
		{
			let cluster = try!(self.fs.load_cluster(c));
			for ent in DirEnts::new(&cluster).skip(c_ofs) {
				cur_ofs += 1;
				match ent {
				DirEnt::End => {
					// On next call, we want to hit this first shot
					next_ofs = cur_ofs-1;
					break 'outer;
					},
				DirEnt::Short(e) => {
					let i = super::InodeRef::new(e.cluster, self.start_cluster).to_id();
					items[count] = (i, ByteString::from(e.name()));
					count += 1;
					// Update return offset to be the next entry
					next_ofs = cur_ofs;
					if count == items.len() {
						break 'outer;
					}
					},
				DirEnt::Long(_) => log_log!("TODO: LFN"),
				DirEnt::Empty => {},
				}
			}
		}

		Ok( (next_ofs, count) )
	}
	fn create(&self, name: &ByteStr, nodetype: node::NodeType) -> node::Result<node::InodeId> {
		todo!("DirNode::create('{:?}', {:?})", name, nodetype);
	}
	fn link(&self, name: &ByteStr, inode: node::InodeId) -> node::Result<()> {
		todo!("DirNode::link('{:?}', {:#x})", name, inode);
	}
	fn unlink(&self, name: &ByteStr) -> node::Result<()> {
		todo!("DirNode::unlink('{:?}')", name);
	}
}

<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2014 Kashyap
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use super::x86asm::outb;
use super::x86asm::inb;

use core::str::StrPrelude;

const COM1 : u16 = 0x3f8;
static mut uartInitialized : bool = false;

pub fn early_init () {
	outb(COM1+2 , 0);
	outb(COM1+3, 0x80);    // Unlock divisor
	outb(COM1+0, 12);
	outb(COM1+1, 0);
	outb(COM1+3, 0x03);    // Lock divisor, 8 data bits.
	outb(COM1+4, 0);
	outb(COM1+1, 0x01);    // Enable receive interrupts.

	if inb(COM1+5) == 0xff {
		return;
	}

	unsafe {
		uartInitialized = true;
	}

	outb(COM1, 65);
	uart_putc("123456");
}

fn uart_putc(text: &str) {
	for b in text.bytes() {
		outb(COM1, 67);
	}
}
<commit_msg>use the byte<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2014 Kashyap
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use super::x86asm::outb;
use super::x86asm::inb;

use core::str::StrPrelude;

const COM1 : u16 = 0x3f8;
static mut uartInitialized : bool = false;

pub fn early_init () {
	outb(COM1+2 , 0);
	outb(COM1+3, 0x80);    // Unlock divisor
	outb(COM1+0, 12);
	outb(COM1+1, 0);
	outb(COM1+3, 0x03);    // Lock divisor, 8 data bits.
	outb(COM1+4, 0);
	outb(COM1+1, 0x01);    // Enable receive interrupts.

	if inb(COM1+5) == 0xff {
		return;
	}

	unsafe {
		uartInitialized = true;
	}

	outb(COM1, 65);
	uart_putc("123456");
}

fn uart_putc(text: &str) {
	for b in text.bytes() {
		outb(COM1, b);
	}
}
<|endoftext|>


<commit_before>#![feature(btree_range, collections_bound)]
extern crate capnp;

#[macro_use]
extern crate rustfbp;
mod contract_capnp {
    include!("list_triple.rs");
    include!("quadruple.rs");
}
use contract_capnp::list_triple;
use contract_capnp::quadruple;
use std::collections::BTreeSet;
use std::collections::Bound::{Included, Unbounded, Excluded};
use std::str::FromStr;

fn process_data(ip: rustfbp::ports::IP) -> Result<(u32,u32,u32,u32)>
{
    let data_reader = try!(ip.get_reader());
    let data_reader: list_triple::Reader = try!(data_reader.get_root());
    let data = try!(data_reader.get_triples());
    let first = try!(data.get(0).get_second());
    let stats_length = data.len();
    let mut total :u32 = 0;
    let mut stats = BTreeSet::new();
    for i in 0..data.len() {
        let second = try!(data.get(i).get_second());
        let third = try!(data.get(i).get_third());
        let second = u32::from_str(second).unwrap();
        stats.insert(second);
        total += second;
    }
    let min =  stats.iter().next().unwrap();
    let max =  stats.iter().last().unwrap();
    let average :u32 = total / stats.len() as u32;
    let mid_top = stats.range(Included(&average), Unbounded).next();
    let mid_bottom = stats.range(Unbounded,Included(&average)).last();
    let median :u32 = (mid_top.unwrap() + mid_bottom.unwrap()) / 2;
    Ok((min.clone(),max.clone(),average.clone(),median.clone()))
}

component! {
    example_wrangle_stats,
    inputs(raw: list_triple, anonymous: list_triple),
    inputs_array(),
    outputs(raw: quadruple, anonymous: quadruple),
    outputs_array(),
    option(),
    acc(),
    fn run(&mut self) -> Result<()> {
        let (min, max, average, median): (u32, u32, u32, u32) = try!(process_data(try!(self.ports.recv("raw"))));
        let mut raw_ip = capnp::message::Builder::new_default();
        {
            let mut quad = raw_ip.init_root::<quadruple::Builder>();
            quad.set_first(min);
            quad.set_second(max);
            quad.set_third(average);
            quad.set_fourth(median);
        }
        let mut send_ip = IP::new();
        try!(send_ip.write_builder(&raw_ip));
        try!(self.ports.send("raw", send_ip));

        let (min, max, average, median): (u32, u32, u32, u32) = try!(process_data(try!(self.ports.recv("anonymous"))));
        let mut anonymous_ip = capnp::message::Builder::new_default();
        {
            let mut quad = anonymous_ip.init_root::<quadruple::Builder>();
            quad.set_first(min);
            quad.set_second(max);
            quad.set_third(average);
            quad.set_fourth(median);
        }
        let mut send_ip = IP::new();
        try!(send_ip.write_builder(&anonymous_ip));
        try!(self.ports.send("anonymous", send_ip));
        Ok(())
    }
}

<commit_msg>Problem: wrong code for median<commit_after>#![feature(btree_range, collections_bound)]
extern crate capnp;

#[macro_use]
extern crate rustfbp;
mod contract_capnp {
    include!("list_triple.rs");
    include!("quadruple.rs");
}
use contract_capnp::list_triple;
use contract_capnp::quadruple;
use std::collections::BTreeSet;
use std::collections::Bound::{Included, Unbounded, Excluded};
use std::str::FromStr;

fn process_data(ip: rustfbp::ports::IP) -> Result<(u32,u32,u32,u32)>
{
    let data_reader = try!(ip.get_reader());
    let data_reader: list_triple::Reader = try!(data_reader.get_root());
    let data = try!(data_reader.get_triples());
    let first = try!(data.get(0).get_second());
    let stats_length = data.len();
    let mut total :u32 = 0;
    let mut stats = BTreeSet::new();
    for i in 0..data.len() {
        let second = try!(data.get(i).get_second());
        let third = try!(data.get(i).get_third());
        let second = u32::from_str(second).unwrap();
        stats.insert(second);
        total += second;
    }
    let min =  stats.iter().next().unwrap();
    let max =  stats.iter().last().unwrap();
    let average :u32 = total / stats.len() as u32;
    let median :u32 = stats.iter().nth(&stats.len()/2).unwrap().clone();
    Ok((min.clone(),max.clone(),average.clone(),median.clone()))
}

component! {
    example_wrangle_stats,
    inputs(raw: list_triple, anonymous: list_triple),
    inputs_array(),
    outputs(raw: quadruple, anonymous: quadruple),
    outputs_array(),
    option(),
    acc(),
    fn run(&mut self) -> Result<()> {
        let (min, max, average, median): (u32, u32, u32, u32) = try!(process_data(try!(self.ports.recv("raw"))));
        let mut raw_ip = capnp::message::Builder::new_default();
        {
            let mut quad = raw_ip.init_root::<quadruple::Builder>();
            quad.set_first(min);
            quad.set_second(max);
            quad.set_third(average);
            quad.set_fourth(median);
        }
        let mut send_ip = IP::new();
        try!(send_ip.write_builder(&raw_ip));
        try!(self.ports.send("raw", send_ip));

        let (min, max, average, median): (u32, u32, u32, u32) = try!(process_data(try!(self.ports.recv("anonymous"))));
        let mut anonymous_ip = capnp::message::Builder::new_default();
        {
            let mut quad = anonymous_ip.init_root::<quadruple::Builder>();
            quad.set_first(min);
            quad.set_second(max);
            quad.set_third(average);
            quad.set_fourth(median);
        }
        let mut send_ip = IP::new();
        try!(send_ip.write_builder(&anonymous_ip));
        try!(self.ports.send("anonymous", send_ip));
        Ok(())
    }
}

<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::answer::DnsAnswer;
pub use self::query::DnsQuery;

use slice;
use u16;
use string::String;
use vec::Vec;

mod answer;
mod query;

#[unstable(feature = "n16", issue="0")]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(packed)]
pub struct n16 {
    inner: u16
}

impl n16 {
    #[unstable(feature = "n16", issue="0")]
    pub fn as_bytes(&self) -> &[u8] {
        unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) }
    }

    #[unstable(feature = "n16", issue="0")]
    pub fn from_bytes(bytes: &[u8]) -> Self {
        n16 {
            inner: unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len()/2)[0] }
        }
    }
}

#[unstable(feature = "n16", issue="0")]
impl From<u16> for n16 {
    fn from(value: u16) -> Self {
        n16 {
            inner: value.to_be()
        }
    }
}

#[unstable(feature = "n16", issue="0")]
impl From<n16> for u16 {
    fn from(value: n16) -> Self {
        u16::from_be(value.inner)
    }
}

#[derive(Clone, Debug)]
pub struct Dns {
    pub transaction_id: u16,
    pub flags: u16,
    pub queries: Vec<DnsQuery>,
    pub answers: Vec<DnsAnswer>
}

impl Dns {
    pub fn compile(&self) -> Vec<u8> {
        let mut data = Vec::new();

        macro_rules! push_u8 {
            ($value:expr) => {
                data.push($value);
            };
        };

        macro_rules! push_n16 {
            ($value:expr) => {
                data.extend_from_slice(n16::from($value).as_bytes());
            };
        };

        push_n16!(self.transaction_id);
        push_n16!(self.flags);
        push_n16!(self.queries.len() as u16);
        push_n16!(self.answers.len() as u16);
        push_n16!(0);
        push_n16!(0);

        for query in self.queries.iter() {
            for part in query.name.split('.') {
                push_u8!(part.len() as u8);
                data.extend_from_slice(part.as_bytes());
            }
            push_u8!(0);
            push_n16!(query.q_type);
            push_n16!(query.q_class);
        }

        data
    }

    pub fn parse(data: &[u8]) -> Result<Self, String> {
        let mut i = 0;

        macro_rules! pop_u8 {
            () => {
                {
                    i += 1;
                    if i > data.len() {
                        return Err(format!("{}: {}: pop_u8", file!(), line!()));
                    }
                    data[i - 1]
                }
            };
        };

        macro_rules! pop_n16 {
            () => {
                {
                    i += 2;
                    if i > data.len() {
                        return Err(format!("{}: {}: pop_n16", file!(), line!()));
                    }
                    u16::from(n16::from_bytes(&data[i - 2 .. i]))
                }
            };
        };

        macro_rules! pop_data {
            () => {
                {
                    let mut data = Vec::new();

                    let data_len = pop_n16!();
                    for _data_i in 0..data_len {
                        data.push(pop_u8!());
                    }

                    data
                }
            };
        };

        macro_rules! pop_name {
            () => {
                {
                    let mut name = String::new();

                    loop {
                        let name_len = pop_u8!();
                        if name_len == 0 {
                            break;
                        }
                        if ! name.is_empty() {
                            name.push('.');
                        }
                        for _name_i in 0..name_len {
                            name.push(pop_u8!() as char);
                        }
                    }

                    name
                }
            };
        };

        let transaction_id = pop_n16!();
        let flags = pop_n16!();
        let queries_len = pop_n16!();
        let answers_len = pop_n16!();
        pop_n16!();
        pop_n16!();

        let mut queries = Vec::new();
        for _query_i in 0..queries_len {
            queries.push(DnsQuery {
                name: pop_name!(),
                q_type: pop_n16!(),
                q_class: pop_n16!()
            });
        }

        let mut answers = Vec::new();
        for _answer_i in 0..answers_len {
            let name_ind = 0b11000000;
            let name_test = pop_u8!();
            i -= 1;

            answers.push(DnsAnswer {
                name: if name_test & name_ind == name_ind {
                    let name_off = pop_n16!() - ((name_ind as u16) << 8);
                    let old_i = i;
                    i = name_off as usize;
                    let name = pop_name!();
                    i = old_i;
                    name
                } else {
                    pop_name!()
                },
                a_type: pop_n16!(),
                a_class: pop_n16!(),
                ttl_a: pop_n16!(),
                ttl_b: pop_n16!(),
                data: pop_data!()
            });
        }

        Ok(Dns {
            transaction_id: transaction_id,
            flags: flags,
            queries: queries,
            answers: answers,
        })
    }
}
<commit_msg>Rollup merge of #43821 - NilSet:redox-dns, r=alexcrichton<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::answer::DnsAnswer;
pub use self::query::DnsQuery;

use slice;
use u16;
use string::String;
use vec::Vec;

mod answer;
mod query;

#[unstable(feature = "n16", issue="0")]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(packed)]
pub struct n16 {
    inner: u16
}

impl n16 {
    #[unstable(feature = "n16", issue="0")]
    pub fn as_bytes(&self) -> &[u8] {
        unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) }
    }

    #[unstable(feature = "n16", issue="0")]
    pub fn from_bytes(bytes: &[u8]) -> Self {
        n16 {
            inner: unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len()/2)[0] }
        }
    }
}

#[unstable(feature = "n16", issue="0")]
impl From<u16> for n16 {
    fn from(value: u16) -> Self {
        n16 {
            inner: value.to_be()
        }
    }
}

#[unstable(feature = "n16", issue="0")]
impl From<n16> for u16 {
    fn from(value: n16) -> Self {
        u16::from_be(value.inner)
    }
}

#[derive(Clone, Debug)]
pub struct Dns {
    pub transaction_id: u16,
    pub flags: u16,
    pub queries: Vec<DnsQuery>,
    pub answers: Vec<DnsAnswer>
}

impl Dns {
    pub fn compile(&self) -> Vec<u8> {
        let mut data = Vec::new();

        macro_rules! push_u8 {
            ($value:expr) => {
                data.push($value);
            };
        };

        macro_rules! push_n16 {
            ($value:expr) => {
                data.extend_from_slice(n16::from($value).as_bytes());
            };
        };

        push_n16!(self.transaction_id);
        push_n16!(self.flags);
        push_n16!(self.queries.len() as u16);
        push_n16!(self.answers.len() as u16);
        push_n16!(0);
        push_n16!(0);

        for query in self.queries.iter() {
            for part in query.name.split('.') {
                push_u8!(part.len() as u8);
                data.extend_from_slice(part.as_bytes());
            }
            push_u8!(0);
            push_n16!(query.q_type);
            push_n16!(query.q_class);
        }

        data
    }

    pub fn parse(data: &[u8]) -> Result<Self, String> {
        let name_ind = 0b11000000;
        let mut i = 0;

        macro_rules! pop_u8 {
            () => {
                {
                    i += 1;
                    if i > data.len() {
                        return Err(format!("{}: {}: pop_u8", file!(), line!()));
                    }
                    data[i - 1]
                }
            };
        };

        macro_rules! pop_n16 {
            () => {
                {
                    i += 2;
                    if i > data.len() {
                        return Err(format!("{}: {}: pop_n16", file!(), line!()));
                    }
                    u16::from(n16::from_bytes(&data[i - 2 .. i]))
                }
            };
        };

        macro_rules! pop_data {
            () => {
                {
                    let mut data = Vec::new();

                    let data_len = pop_n16!();
                    for _data_i in 0..data_len {
                        data.push(pop_u8!());
                    }

                    data
                }
            };
        };

        macro_rules! pop_name {
            () => {
                {
                    let mut name = String::new();
                    let old_i = i;

                    loop {
                        let name_len = pop_u8!();
                        if name_len & name_ind == name_ind {
                            i -= 1;
                            i = (pop_n16!() - ((name_ind as u16) << 8)) as usize;
                            continue;
                        }
                        if name_len == 0 {
                            break;
                        }
                        if ! name.is_empty() {
                            name.push('.');
                        }
                        for _name_i in 0..name_len {
                            name.push(pop_u8!() as char);
                        }
                    }

                    if i <= old_i {
                        i = old_i + 2;
                    }

                    name
                }
            };
        };

        let transaction_id = pop_n16!();
        let flags = pop_n16!();
        let queries_len = pop_n16!();
        let answers_len = pop_n16!();
        pop_n16!();
        pop_n16!();

        let mut queries = Vec::new();
        for _query_i in 0..queries_len {
            queries.push(DnsQuery {
                name: pop_name!(),
                q_type: pop_n16!(),
                q_class: pop_n16!()
            });
        }

        let mut answers = Vec::new();
        for _answer_i in 0..answers_len {
            answers.push(DnsAnswer {
                name: pop_name!(),
                a_type: pop_n16!(),
                a_class: pop_n16!(),
                ttl_a: pop_n16!(),
                ttl_b: pop_n16!(),
                data: pop_data!()
            });
        }

        Ok(Dns {
            transaction_id: transaction_id,
            flags: flags,
            queries: queries,
            answers: answers,
        })
    }
}
<|endoftext|>


<commit_before>use ws;
use time;
use std::fmt;
use uuid::Uuid;
use std::sync::{Arc,Mutex};
use std::collections::{HashMap,HashSet};

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Item {
    Potatoes,
    Berries,
    TreeSap,
}

trait ParseFrom<T, Out = Self> {
    fn parse (from: T) -> Result<Out, String>;
}

impl ParseFrom<i32> for Item {
    fn parse (i: i32) -> Result<Self, String> {
        match i {
            0 => Ok(Item::Potatoes),
            1 => Ok(Item::Berries),
            2 => Ok(Item::TreeSap),
            _ => Err(format!("Item.parse<i32> failure: unrecognized Item {}", i)),
        }
    }
}

#[derive(Debug)]
#[allow(non_camel_case_types)]
pub enum Action {
    addItemToInventory(Item),
}

#[derive(Debug, Clone)]
pub struct PlayerState {
    inventory: HashSet<Item>,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Player {
    AnonymousPlayer {
        state : PlayerState,
    },
    RegisteredPlayer {
        id    : i32,
        name  : String,
        state : PlayerState,
    }
}

#[allow(non_snake_case)]
mod AnonymousPlayer {
    use super::*;
    pub fn new () -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potatoes);

        Player::AnonymousPlayer {
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[allow(non_snake_case,dead_code)]
mod RegisteredPlayer {
    use super::*;
    pub fn new (id: i32, name: String) -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potatoes);

        Player::RegisteredPlayer {
            id: id,
            name: name,
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[derive(Debug, Clone)]
pub struct Connection {
    uuid   : Uuid,
    player : Player,
}

impl Connection {
    fn new(u: Uuid, p: Player) -> Connection {
        Connection {
            uuid  : u,
            player: p
        }
    }
}

impl fmt::Display for Connection {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "conn{{{}}}", self.uuid)
    }
}

fn parse_cookies (req: &ws::Request) -> HashMap<String, String> {
    req.header("cookie")
        .and_then(|cookies_bytes| String::from_utf8(cookies_bytes.to_vec()).ok())
        .unwrap_or(String::from(""))
        .rsplit(";")
        .filter_map(|cookie_string| {
            let mut cookie_pair = cookie_string.split("=");
            match (cookie_pair.next(), cookie_pair.next()) {
                (Some(name), Some(value)) => {
                    Some((String::from(name.trim()), String::from(value.trim())))
                },
                _ => None
            }
        })
        .collect()
}

fn put_cookie (name: String, value: String, resp: &mut ws::Response) {
    let headers = resp.headers_mut();
    let cookie_bytes = format!("{}={}", name, value).as_bytes().to_vec();
    headers.push((String::from("Set-Cookie"), cookie_bytes));
}

fn authorize_ticket_dumb (ticket: Uuid, msg_type: Vec<String>, conn_map: ConnectionMap) -> Result<Vec<String>, String> {
   if conn_map.lock().unwrap().contains_key(&ticket) {
        Ok(msg_type)
   } else {
        Err(String::from("authorize_ticket_dumb authorization failed"))
   }
}

type ConnectionMap = Arc<Mutex<HashMap<Uuid, Connection>>>;

struct WSServer {
    out: ws::Sender,
    connections: ConnectionMap,
}

fn parse_message (msg: ws::Message) -> Result<(Uuid, Vec<String>), String> {
    fn parse_error_msg (reason: &str) -> String {
        format!("parse_message failure: {}", reason)
    }

    msg.into_text()
        .or(Err(parse_error_msg("cannot get text from Message; is it a binary Message?")))
        // NOTE(jordan): feels... wrong. But I hate the nesting! There's no unwrap_or_err()...
        .and_then(|msg| msg                  // Result<String, Err> -> String, or propagate Err
        .split(":")                          // String -> Split<'_, &str>
        .map(|p| p.to_string())              // Split<'_, &str> -> &[String]
        .collect::<Vec<String>>()            // &[String] -> Vec<String>
        .split_first()                       // Vec<String> -> Option<(String, Vec<String>)>
        .ok_or(parse_error_msg("no ticket")) // Option -> Result<(String, &[String]), String>
        .and_then(|(uuid_string, rest)| {    // Result<(String, &[String]), String>
            Uuid::parse_str(uuid_string)     //   |-> Result<(Uuid, Vec<String>), String>
                .or(Err(parse_error_msg("ticket is invalid uuidv4")))
                .map(|uuid| (uuid, Vec::from(rest)))
        }))
}

impl ws::Handler for WSServer {
    fn on_request(&mut self, req: &ws::Request) -> ws::Result<ws::Response> {
        let mut resp = ws::Response::from_request(req).unwrap();

        let mut conn_map = self.connections.lock().unwrap();

        println!("ws:req[{}]", time::precise_time_ns());

        let cookies : HashMap<String, String> = parse_cookies(req);

        let mut cookie_existed = true;
        let ticket = cookies.get("bzwf_anon_wstx")
            .and_then(|uuid_string| Uuid::parse_str(uuid_string.as_str()).ok())
            .unwrap_or_else(|| {
                println!("ws:req[{}]: no bzwf_anon_wstx cookie found", time::precise_time_ns());
                cookie_existed = false;
                Uuid::new_v4()
            });

        let users_count = conn_map.len();

        if conn_map.contains_key(&ticket) {
            println!("ws:req[{}]: reconnect: uuid {}", time::precise_time_ns(), ticket);
            println!("{} connected users", users_count);
        } else {
            println!("ws:req[{}]: new connection with uuid {}", time::precise_time_ns(), ticket);

            let cookie_op_str = if cookie_existed {
                "replacing persistence cookie"
            } else {
                "creating persistence cookie"
            };

            println!("ws:req[{}]: {}: bzwf_anon_wstx={}", time::precise_time_ns(), cookie_op_str, ticket);
            println!("{} connected users", users_count + 1);
            put_cookie(String::from("bzwf_anon_wstx"), ticket.to_string(), &mut resp);
            conn_map.insert(ticket, Connection::new(ticket, AnonymousPlayer::new()));
        }

        Ok(resp)
    }

    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        println!("ws:rcv[{}]: user with uuid {} sent ws msg {}",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]",
                 msg);

        parse_message(msg)
            .and_then(|(msg_ticket, msg_contents)| {
                println!("authorizing ticket {}", msg_ticket);
                authorize_ticket_dumb(msg_ticket, msg_contents, self.connections.clone())
            })
            .and_then(|msg_contents| {
                // FIXME possible out of bounds error
                let ref msg_type  = msg_contents[0];
                let ref msg_param = msg_contents[1];

                println!("trying to read message contents of {}({})", msg_type, msg_param);

                match (msg_type.as_str(), msg_param) {
                    ("addItemToInventory", item) => {
                        if let Ok(item_num) = item.parse::<i32>() {
                            Item::parse(item_num)
                                .map(|item| Action::addItemToInventory(item))
                        } else {
                            Err(String::from("parse_message failure: addItemToInventory: invalid item code"))
                        }
                    },
                    _ => Err(String::from("parse_message failure: unrecognized message type"))
                }
            })
            .map(|action| {
                self.out.send(format!("gotcha, you want to {:?}", action))
            })
            .unwrap_or_else(|err| {
                println!("{}", err);
                self.out.send("got your message, but not sure what it meant")
            });

        Ok(())
    }

    fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
        // TODO
        println!("ws:opn[{}]: user with uuid {} opened ws cxn",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]");
        Ok(())
    }

    fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
        println!("ws:cls[{}]: user with uuid {} closed ws cxn\n\tCode [{:?}] reason: {}",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]",
                 code,
                 reason);
        // TODO
    }

    fn on_error(&mut self, err: ws::Error) {
        println!("ws:err[{}]: user with uuid {} got error {}",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]",
                 err);
        // TODO
    }
}

pub fn server (domain: String, port: i32) -> () {
    let connections : ConnectionMap = Arc::new(Mutex::new(HashMap::new()));
    let addr = format!("{}:{}", domain, port);
    println!("WebSockets server listening on {}", addr);
    ws::listen(addr, |out| WSServer {
        out: out,
        connections: connections.clone(),
    }).unwrap();
}
<commit_msg>Refactor/Minor: silly jordan, just unwrap_or_else and return the err<commit_after>use ws;
use time;
use std::fmt;
use uuid::Uuid;
use std::sync::{Arc,Mutex};
use std::collections::{HashMap,HashSet};

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Item {
    Potatoes,
    Berries,
    TreeSap,
}

trait ParseFrom<T, Out = Self> {
    fn parse (from: T) -> Result<Out, String>;
}

impl ParseFrom<i32> for Item {
    fn parse (i: i32) -> Result<Self, String> {
        match i {
            0 => Ok(Item::Potatoes),
            1 => Ok(Item::Berries),
            2 => Ok(Item::TreeSap),
            _ => Err(format!("Item.parse<i32> failure: unrecognized Item {}", i)),
        }
    }
}

#[derive(Debug)]
#[allow(non_camel_case_types)]
pub enum Action {
    addItemToInventory(Item),
}

#[derive(Debug, Clone)]
pub struct PlayerState {
    inventory: HashSet<Item>,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Player {
    AnonymousPlayer {
        state : PlayerState,
    },
    RegisteredPlayer {
        id    : i32,
        name  : String,
        state : PlayerState,
    }
}

#[allow(non_snake_case)]
mod AnonymousPlayer {
    use super::*;
    pub fn new () -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potatoes);

        Player::AnonymousPlayer {
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[allow(non_snake_case,dead_code)]
mod RegisteredPlayer {
    use super::*;
    pub fn new (id: i32, name: String) -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potatoes);

        Player::RegisteredPlayer {
            id: id,
            name: name,
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[derive(Debug, Clone)]
pub struct Connection {
    uuid   : Uuid,
    player : Player,
}

impl Connection {
    fn new(u: Uuid, p: Player) -> Connection {
        Connection {
            uuid  : u,
            player: p
        }
    }
}

impl fmt::Display for Connection {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "conn{{{}}}", self.uuid)
    }
}

fn parse_cookies (req: &ws::Request) -> HashMap<String, String> {
    req.header("cookie")
        .and_then(|cookies_bytes| String::from_utf8(cookies_bytes.to_vec()).ok())
        .unwrap_or(String::from(""))
        .rsplit(";")
        .filter_map(|cookie_string| {
            let mut cookie_pair = cookie_string.split("=");
            match (cookie_pair.next(), cookie_pair.next()) {
                (Some(name), Some(value)) => {
                    Some((String::from(name.trim()), String::from(value.trim())))
                },
                _ => None
            }
        })
        .collect()
}

fn put_cookie (name: String, value: String, resp: &mut ws::Response) {
    let headers = resp.headers_mut();
    let cookie_bytes = format!("{}={}", name, value).as_bytes().to_vec();
    headers.push((String::from("Set-Cookie"), cookie_bytes));
}

fn authorize_ticket_dumb (ticket: Uuid, msg_type: Vec<String>, conn_map: ConnectionMap) -> Result<Vec<String>, String> {
   if conn_map.lock().unwrap().contains_key(&ticket) {
        Ok(msg_type)
   } else {
        Err(String::from("authorize_ticket_dumb authorization failed"))
   }
}

type ConnectionMap = Arc<Mutex<HashMap<Uuid, Connection>>>;

struct WSServer {
    out: ws::Sender,
    connections: ConnectionMap,
}

fn parse_message (msg: ws::Message) -> Result<(Uuid, Vec<String>), String> {
    fn parse_error_msg (reason: &str) -> String {
        format!("parse_message failure: {}", reason)
    }

    msg.into_text()
        .or(Err(parse_error_msg("cannot get text from Message; is it a binary Message?")))
        // NOTE(jordan): feels... wrong. But I hate the nesting! There's no unwrap_or_err()...
        .unwrap_or_else(|err| err)           // Result<String, Err> -> String, or propagate Err
        .split(":")                          // String -> Split<'_, &str>
        .map(|p| p.to_string())              // Split<'_, &str> -> &[String]
        .collect::<Vec<String>>()            // &[String] -> Vec<String>
        .split_first()                       // Vec<String> -> Option<(String, Vec<String>)>
        .ok_or(parse_error_msg("no ticket")) // Option -> Result<(String, &[String]), String>
        .and_then(|(uuid_string, rest)| {    // Result<(String, &[String]), String>
            Uuid::parse_str(uuid_string)     //   |-> Result<(Uuid, Vec<String>), String>
                .or(Err(parse_error_msg("ticket is invalid uuidv4")))
                .map(|uuid| (uuid, Vec::from(rest)))
        })
}

impl ws::Handler for WSServer {
    fn on_request(&mut self, req: &ws::Request) -> ws::Result<ws::Response> {
        let mut resp = ws::Response::from_request(req).unwrap();

        let mut conn_map = self.connections.lock().unwrap();

        println!("ws:req[{}]", time::precise_time_ns());

        let cookies : HashMap<String, String> = parse_cookies(req);

        let mut cookie_existed = true;
        let ticket = cookies.get("bzwf_anon_wstx")
            .and_then(|uuid_string| Uuid::parse_str(uuid_string.as_str()).ok())
            .unwrap_or_else(|| {
                println!("ws:req[{}]: no bzwf_anon_wstx cookie found", time::precise_time_ns());
                cookie_existed = false;
                Uuid::new_v4()
            });

        let users_count = conn_map.len();

        if conn_map.contains_key(&ticket) {
            println!("ws:req[{}]: reconnect: uuid {}", time::precise_time_ns(), ticket);
            println!("{} connected users", users_count);
        } else {
            println!("ws:req[{}]: new connection with uuid {}", time::precise_time_ns(), ticket);

            let cookie_op_str = if cookie_existed {
                "replacing persistence cookie"
            } else {
                "creating persistence cookie"
            };

            println!("ws:req[{}]: {}: bzwf_anon_wstx={}", time::precise_time_ns(), cookie_op_str, ticket);
            println!("{} connected users", users_count + 1);
            put_cookie(String::from("bzwf_anon_wstx"), ticket.to_string(), &mut resp);
            conn_map.insert(ticket, Connection::new(ticket, AnonymousPlayer::new()));
        }

        Ok(resp)
    }

    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        println!("ws:rcv[{}]: user with uuid {} sent ws msg {}",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]",
                 msg);

        parse_message(msg)
            .and_then(|(msg_ticket, msg_contents)| {
                println!("authorizing ticket {}", msg_ticket);
                authorize_ticket_dumb(msg_ticket, msg_contents, self.connections.clone())
            })
            .and_then(|msg_contents| {
                // FIXME possible out of bounds error
                let ref msg_type  = msg_contents[0];
                let ref msg_param = msg_contents[1];

                println!("trying to read message contents of {}({})", msg_type, msg_param);

                match (msg_type.as_str(), msg_param) {
                    ("addItemToInventory", item) => {
                        if let Ok(item_num) = item.parse::<i32>() {
                            Item::parse(item_num)
                                .map(|item| Action::addItemToInventory(item))
                        } else {
                            Err(String::from("parse_message failure: addItemToInventory: invalid item code"))
                        }
                    },
                    _ => Err(String::from("parse_message failure: unrecognized message type"))
                }
            })
            .map(|action| {
                self.out.send(format!("gotcha, you want to {:?}", action))
            })
            .unwrap_or_else(|err| {
                println!("{}", err);
                self.out.send("got your message, but not sure what it meant")
            });

        Ok(())
    }

    fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
        // TODO
        println!("ws:opn[{}]: user with uuid {} opened ws cxn",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]");
        Ok(())
    }

    fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
        println!("ws:cls[{}]: user with uuid {} closed ws cxn\n\tCode [{:?}] reason: {}",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]",
                 code,
                 reason);
        // TODO
    }

    fn on_error(&mut self, err: ws::Error) {
        println!("ws:err[{}]: user with uuid {} got error {}",
                 time::precise_time_ns(),
                 "[[[ we don't have uuids in ws yet ]]]",
                 err);
        // TODO
    }
}

pub fn server (domain: String, port: i32) -> () {
    let connections : ConnectionMap = Arc::new(Mutex::new(HashMap::new()));
    let addr = format!("{}:{}", domain, port);
    println!("WebSockets server listening on {}", addr);
    ws::listen(addr, |out| WSServer {
        out: out,
        connections: connections.clone(),
    }).unwrap();
}
<|endoftext|>