<commit_before>
use dsp::Dsp;
use petgraph as pg;
use sound_stream::{Sample, Settings};

/// A directed, acyclic DSP graph.
#[derive(Clone, Debug)]
pub struct Graph<S, D> {
    graph: pg::Graph<Node<S, D>, ()>,
    maybe_master: Option<NodeIndex>,
    phantom_data: ::std::marker::PhantomData<S>,
}

/// A Dsp object and it's sample buffer.
#[derive(Clone, Debug)]
struct Node<S, D>(D, Option<Vec<S>>);

/// Represents a graph node index.
pub type NodeIndex = pg::graph::NodeIndex<u32>;

/// A type for representing an error on the occasion
/// that a connection would create a cyclic graph.
#[derive(Copy, Clone, Debug)]
pub struct WouldCycle;

/// An iterator over references to the inputs of a Graph node.
pub type Inputs<'a, S, D> = Neighbors<'a, S, D>;
/// An iterator over mutable references to the inputs of a Graph node.
pub type InputsMut<'a, S, D> = NeighborsMut<'a, S, D>;
/// An iterator over references to the outputs of a Graph node.
pub type Outputs<'a, S, D> = Neighbors<'a, S, D>;
/// An iterator over mutable references to the outputs of a Graph node.
pub type OutputsMut<'a, S, D> = NeighborsMut<'a, S, D>;

/// An iterator over references to the neighbors of a Graph node.
pub struct Neighbors<'a, S: 'a, D: 'a> {
    graph: &'a pg::Graph<Node<S, D>, ()>,
    neighbors: pg::graph::Neighbors<'a, (), u32>,
}

/// An iterator over mutable references to the neighbors of a Graph node.
pub struct NeighborsMut<'a, S: 'a, D: 'a> {
    graph: &'a mut pg::Graph<Node<S, D>, ()>,
    neighbors: pg::graph::Neighbors<'a, (), u32>,
}

impl<S, D> Graph<S, D> where S: Sample, D: Dsp<S> {

    /// Constructor for a new dsp Graph.
    pub fn new() -> Graph<S, D> {
        let graph = pg::Graph::new();
        Graph {
            graph: graph,
            maybe_master: None,
            phantom_data: ::std::marker::PhantomData,
        }
    }

    /// Set the master node for the Graph.
    /// Graph will check to see if a node exists for the given index before assigning.
    /// Graph's Dsp implementation will use the dsp at the master node when the audio_requested
    /// method is called.
    pub fn set_master(&mut self, maybe_index: Option<NodeIndex>) {
        let maybe_index = match maybe_index {
            Some(index) => match self.graph.node_weight(index) {
                Some(_) => Some(index),
                None => None,
            },
            None => None,
        };
        self.maybe_master = maybe_index;
    }

    /// Return the master index if there is one.
    pub fn master_index(&self) -> Option<NodeIndex> {
        self.maybe_master
    }

    /// Add a node to the dsp graph.
    pub fn add_node(&mut self, dsp: D) -> NodeIndex {
        self.graph.add_node(Node(dsp, None))
    }

    /// Remove a node from the dsp graph.
    /// Reset maybe_master to None if the index matches the current master index.
    pub fn remove_node(&mut self, idx: NodeIndex) -> Option<D> {
        if let Some(master_idx) = self.maybe_master {
            if idx == master_idx {
                self.maybe_master = None;
            }
        }
        self.graph.remove_node(idx).map(|node| {
            let Node(dsp, _) = node;
            dsp
        })
    }

    /// Adds a connection from `a` to `b`. That is, `a` is now an input to `b`.
    /// Returns an error instead if the input would create a cycle in the graph.
    pub fn add_input(&mut self, a: NodeIndex, b: NodeIndex) -> Result<(), WouldCycle> {
        let edge = self.graph.add_edge(a, b, ());
        if pg::algo::is_cyclic(&self.graph) {
            self.graph.remove_edge(edge);
            Err(WouldCycle)
        } else {
            Ok(())
        }
    }

    /// Remove the input between the nodes at the given indices if there is one.
    pub fn remove_input(&mut self, a: NodeIndex, b: NodeIndex) {
        if let Some(edge) = self.graph.find_edge(a, b) {
            self.graph.remove_edge(edge);
        } else if let Some(edge) = self.graph.find_edge(b, a) {
            self.graph.remove_edge(edge);
        }
    }

    /// Returns an iterator over references to each neighboring node in the given direction.
    fn neighbors<'a>(&'a self, idx: NodeIndex,
                     direction: pg::EdgeDirection) -> Neighbors<'a, S, D> {
        Neighbors {
            graph: &self.graph,
            neighbors: self.graph.neighbors_directed(idx, direction),
        }
    }

    /// Returns an iterator over mutable references to each neighboring node in the given direction.
    fn neighbors_mut<'a>(&'a mut self, idx: NodeIndex,
                         direction: pg::EdgeDirection) -> NeighborsMut<'a, S, D> {
        let graph = &mut self.graph as *mut pg::Graph<Node<S, D>, ()>;
        // Here we use `unsafe` to allow for aliasing references to the Graph.
        // We allow aliasing in this case because we know that it is impossible
        // for a user to use InputsMut unsafely as it's fields are private and
        // it only exposes its Iterator implementation, which we know is safe.
        // (see the Iterator implementation below the Graph implementation).
        NeighborsMut {
            graph: unsafe { ::std::mem::transmute(graph) },
            neighbors: unsafe { (*graph).neighbors_directed(idx, direction) },
        }
    }

    /// Returns an iterator over references to each input node.
    pub fn inputs<'a>(&'a self, idx: NodeIndex) -> Inputs<'a, S, D> {
        self.neighbors(idx, pg::Incoming)
    }

    /// Returns an iterator over mutable references to each input node.
    pub fn inputs_mut<'a>(&'a mut self, idx: NodeIndex) -> InputsMut<'a, S, D> {
        self.neighbors_mut(idx, pg::Incoming)
    }

    /// Returns an iterator over references to each output node.
    pub fn outputs<'a>(&'a self, idx: NodeIndex) -> Outputs<'a, S, D> {
        self.neighbors(idx, pg::Outgoing)
    }

    /// Returns an iterator over mutable references to each output node.
    pub fn outputs_mut<'a>(&'a mut self, idx: NodeIndex) -> OutputsMut<'a, S, D> {
        self.neighbors_mut(idx, pg::Outgoing)
    }

    /// Request audio from the node at the given index.
    pub fn audio_requested_from_node(&mut self,
                                     idx: NodeIndex,
                                     output: &mut[S],
                                     settings: Settings) {
        request_audio_from_graph(&mut self.graph, idx, output, settings);
        reset_graph_buffers(&mut self.graph, idx);
    }

    /// Clear all dsp nodes that have no inputs and that are not inputs to any other nodes.
    pub fn clear_disconnected(&mut self) {
        let no_incoming: Vec<_> = self.graph.without_edges(pg::Incoming).collect();
        let no_outgoing: Vec<_> = self.graph.without_edges(pg::Outgoing).collect();
        let indices_for_removal = no_incoming.into_iter()
            .filter(|incoming| no_outgoing.iter().any(|outgoing| outgoing == incoming));
        for idx in indices_for_removal {
            if let Some(master_idx) = self.maybe_master {
                if master_idx == idx {
                    self.maybe_master = None;
                }
            }
            self.graph.remove_node(idx);
        }
    }

    /// Clear all dsp nodes.
    pub fn clear(&mut self) {
        self.graph.clear();
        self.maybe_master = None;
    }

}

impl<'a, S, D> Iterator for Neighbors<'a, S, D> {
    type Item = &'a D;
    fn next(&mut self) -> Option<&'a D> {
        match self.neighbors.next() {
            Some(idx) => {
                let &Node(ref dsp, _) = &self.graph[idx];
                Some(dsp)
            },
            None => None,
        }
    }
}

impl<'a, S, D> Iterator for NeighborsMut<'a, S, D> {
    type Item = &'a mut D;
    fn next(&mut self) -> Option<&'a mut D> {
        let NeighborsMut { ref mut graph, ref mut neighbors } = *self;
        match neighbors.next() {
            Some(idx) => {
                let &mut Node(ref mut dsp, _) = &mut graph[idx];
                let dsp: &mut D = dsp;
                // Without the following unsafe block, rustc complains about
                // input_ref_mut not having a suitable life time. This is because
                // it is concerned about creating aliasing mutable references,
                // however we know that only one mutable reference will be returned
                // at a time and that they will never alias. Thus, we transmute to
                // silence the lifetime warning!
                Some(unsafe { ::std::mem::transmute(dsp) })
            },
            None => None,
        }
    }
}

impl<S, D> ::std::ops::Index<NodeIndex> for Graph<S, D> {
    type Output = D;
    fn index<'a>(&'a self, index: &NodeIndex) -> &'a D {
        let &Node(ref dsp, _) = &self.graph[*index];
        dsp
    }
}

impl<S, D> ::std::ops::IndexMut<NodeIndex> for Graph<S, D> {
    fn index_mut(&mut self, index: &NodeIndex) -> &mut D {
        let &mut Node(ref mut dsp, _) = &mut self.graph[*index];
        dsp
    }
}

impl<S, D> Dsp<S> for Graph<S, D>
    where
        S: Sample,
        D: Dsp<S>,
{
    fn audio_requested(&mut self, output: &mut [S], settings: Settings) {
        if let Some(idx) = self.maybe_master {
            self.audio_requested_from_node(idx, output, settings);
        }
    }
}

/// Request audio from the node at the given index and all incoming nodes.
/// If the node does have incoming neighbors, they will be requested and summed first.
/// This process will continue recursively until all incoming connections have been visited.
#[inline]
fn request_audio_from_graph<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                                  idx: pg::graph::NodeIndex,
                                  output: &mut [S],
                                  settings: Settings)
    where
        S: Sample,
        D: Dsp<S>,
{
    {
        let graph = graph as *mut pg::Graph<Node<S, D>, ()>;
        for neighbor_idx in unsafe { (*graph).neighbors_directed(idx, pg::Incoming) } {
            let graph: &mut pg::Graph<Node<S, D>, ()> = unsafe { ::std::mem::transmute(graph) };
            let mut working = vec![Sample::zero(); settings.buffer_size()];
            request_audio_from_graph(graph, neighbor_idx, &mut working, settings);
            let Node(ref dsp, _) = graph[neighbor_idx];
            let vol_per_channel = dsp.vol_per_channel();
            Sample::add_buffers(output, &working[..], &vol_per_channel[..]);
        }
    }
    request_audio_from_node(graph, idx, output, settings);
}

/// If the node at the given index already has a prepared buffer, clone that.
/// Otherwise, request a new buffer from the dsp object.
fn request_audio_from_node<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                                 idx: pg::graph::NodeIndex,
                                 output: &mut [S],
                                 settings: Settings)
    where
        S: Sample,
        D: Dsp<S>,
{
    if graph.neighbors_directed(idx, pg::Outgoing).take(2).count() > 1 {
        let &mut Node(ref mut dsp, ref mut maybe_buffer) = &mut graph[idx];
        let buffer = match *maybe_buffer {
            Some(ref buffer) => {
                output.clone_from_slice(&buffer[..]);
                return;
            },
            None => {
                let mut buffer = vec![Sample::zero(); settings.buffer_size()];
                dsp.audio_requested(&mut buffer[..], settings);
                output.clone_from_slice(&buffer[..]);
                buffer
            },
        };
        *maybe_buffer = Some(buffer);
    } else {
        let &mut Node(ref mut dsp, _) = &mut graph[idx];
        dsp.audio_requested(output, settings);
    }
}

/// Reset all buffers within all nodes that have incoming connections towards the node at the
/// given index.
fn reset_graph_buffers<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                             idx: pg::graph::NodeIndex,)
    where
        S: Sample,
        D: Dsp<S>,
{
    {
        let graph = graph as *mut pg::Graph<Node<S, D>, ()>;
        for neighbor_idx in unsafe { (*graph).neighbors_directed(idx, pg::Incoming) } {
            let graph: &mut pg::Graph<Node<S, D>, ()> = unsafe { ::std::mem::transmute(graph) };
            reset_graph_buffers(graph, neighbor_idx);
        }
    }
    reset_node_buffer(graph, idx);
}

/// Reset the buffer owned by the node at the given index.
fn reset_node_buffer<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                           idx: pg::graph::NodeIndex)
    where
        S: Sample,
        D: Dsp<S>,
{
    let &mut Node(_, ref mut maybe_buffer) = &mut graph[idx];
    if maybe_buffer.is_some() {
        *maybe_buffer = None;
    }
}

impl ::std::fmt::Display for WouldCycle {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        writeln!(f, "{:?}", self)
    }
}

impl ::std::error::Error for WouldCycle {
    fn description(&self) -> &str {
        "Adding this input would have caused the graph to cycle!"
    }
}

<commit_msg>Fixed #94 by updating to latest petgraph<commit_after>
use dsp::Dsp;
use petgraph as pg;
use sound_stream::{Sample, Settings};

/// A directed, acyclic DSP graph.
#[derive(Clone, Debug)]
pub struct Graph<S, D> {
    graph: pg::Graph<Node<S, D>, ()>,
    maybe_master: Option<NodeIndex>,
    phantom_data: ::std::marker::PhantomData<S>,
}

/// A Dsp object and it's sample buffer.
#[derive(Clone, Debug)]
struct Node<S, D>(D, Option<Vec<S>>);

/// Represents a graph node index.
pub type NodeIndex = pg::graph::NodeIndex<u32>;

/// A type for representing an error on the occasion
/// that a connection would create a cyclic graph.
#[derive(Copy, Clone, Debug)]
pub struct WouldCycle;

/// An iterator over references to the inputs of a Graph node.
pub type Inputs<'a, S, D> = Neighbors<'a, S, D>;
/// An iterator over mutable references to the inputs of a Graph node.
pub type InputsMut<'a, S, D> = NeighborsMut<'a, S, D>;
/// An iterator over references to the outputs of a Graph node.
pub type Outputs<'a, S, D> = Neighbors<'a, S, D>;
/// An iterator over mutable references to the outputs of a Graph node.
pub type OutputsMut<'a, S, D> = NeighborsMut<'a, S, D>;

/// An iterator over references to the neighbors of a Graph node.
pub struct Neighbors<'a, S: 'a, D: 'a> {
    graph: &'a pg::Graph<Node<S, D>, ()>,
    neighbors: pg::graph::Neighbors<'a, (), u32>,
}

/// An iterator over mutable references to the neighbors of a Graph node.
pub struct NeighborsMut<'a, S: 'a, D: 'a> {
    graph: &'a mut pg::Graph<Node<S, D>, ()>,
    neighbors: pg::graph::Neighbors<'a, (), u32>,
}

impl<S, D> Graph<S, D> where S: Sample, D: Dsp<S> {

    /// Constructor for a new dsp Graph.
    pub fn new() -> Graph<S, D> {
        let graph = pg::Graph::new();
        Graph {
            graph: graph,
            maybe_master: None,
            phantom_data: ::std::marker::PhantomData,
        }
    }

    /// Set the master node for the Graph.
    /// Graph will check to see if a node exists for the given index before assigning.
    /// Graph's Dsp implementation will use the dsp at the master node when the audio_requested
    /// method is called.
    pub fn set_master(&mut self, maybe_index: Option<NodeIndex>) {
        let maybe_index = match maybe_index {
            Some(index) => match self.graph.node_weight(index) {
                Some(_) => Some(index),
                None => None,
            },
            None => None,
        };
        self.maybe_master = maybe_index;
    }

    /// Return the master index if there is one.
    pub fn master_index(&self) -> Option<NodeIndex> {
        self.maybe_master
    }

    /// Add a node to the dsp graph.
    pub fn add_node(&mut self, dsp: D) -> NodeIndex {
        self.graph.add_node(Node(dsp, None))
    }

    /// Remove a node from the dsp graph.
    /// Reset maybe_master to None if the index matches the current master index.
    pub fn remove_node(&mut self, idx: NodeIndex) -> Option<D> {
        if let Some(master_idx) = self.maybe_master {
            if idx == master_idx {
                self.maybe_master = None;
            }
        }
        self.graph.remove_node(idx).map(|node| {
            let Node(dsp, _) = node;
            dsp
        })
    }

    /// Adds a connection from `a` to `b`. That is, `a` is now an input to `b`.
    /// Returns an error instead if the input would create a cycle in the graph.
    pub fn add_input(&mut self, a: NodeIndex, b: NodeIndex) -> Result<(), WouldCycle> {
        let edge = self.graph.add_edge(a, b, ());
        if pg::algo::is_cyclic_directed(&self.graph) {
            self.graph.remove_edge(edge);
            Err(WouldCycle)
        } else {
            Ok(())
        }
    }

    /// Remove the input between the nodes at the given indices if there is one.
    pub fn remove_input(&mut self, a: NodeIndex, b: NodeIndex) {
        if let Some(edge) = self.graph.find_edge(a, b) {
            self.graph.remove_edge(edge);
        } else if let Some(edge) = self.graph.find_edge(b, a) {
            self.graph.remove_edge(edge);
        }
    }

    /// Returns an iterator over references to each neighboring node in the given direction.
    fn neighbors<'a>(&'a self, idx: NodeIndex,
                     direction: pg::EdgeDirection) -> Neighbors<'a, S, D> {
        Neighbors {
            graph: &self.graph,
            neighbors: self.graph.neighbors_directed(idx, direction),
        }
    }

    /// Returns an iterator over mutable references to each neighboring node in the given direction.
    fn neighbors_mut<'a>(&'a mut self, idx: NodeIndex,
                         direction: pg::EdgeDirection) -> NeighborsMut<'a, S, D> {
        let graph = &mut self.graph as *mut pg::Graph<Node<S, D>, ()>;
        // Here we use `unsafe` to allow for aliasing references to the Graph.
        // We allow aliasing in this case because we know that it is impossible
        // for a user to use InputsMut unsafely as it's fields are private and
        // it only exposes its Iterator implementation, which we know is safe.
        // (see the Iterator implementation below the Graph implementation).
        NeighborsMut {
            graph: unsafe { ::std::mem::transmute(graph) },
            neighbors: unsafe { (*graph).neighbors_directed(idx, direction) },
        }
    }

    /// Returns an iterator over references to each input node.
    pub fn inputs<'a>(&'a self, idx: NodeIndex) -> Inputs<'a, S, D> {
        self.neighbors(idx, pg::Incoming)
    }

    /// Returns an iterator over mutable references to each input node.
    pub fn inputs_mut<'a>(&'a mut self, idx: NodeIndex) -> InputsMut<'a, S, D> {
        self.neighbors_mut(idx, pg::Incoming)
    }

    /// Returns an iterator over references to each output node.
    pub fn outputs<'a>(&'a self, idx: NodeIndex) -> Outputs<'a, S, D> {
        self.neighbors(idx, pg::Outgoing)
    }

    /// Returns an iterator over mutable references to each output node.
    pub fn outputs_mut<'a>(&'a mut self, idx: NodeIndex) -> OutputsMut<'a, S, D> {
        self.neighbors_mut(idx, pg::Outgoing)
    }

    /// Request audio from the node at the given index.
    pub fn audio_requested_from_node(&mut self,
                                     idx: NodeIndex,
                                     output: &mut[S],
                                     settings: Settings) {
        request_audio_from_graph(&mut self.graph, idx, output, settings);
        reset_graph_buffers(&mut self.graph, idx);
    }

    /// Clear all dsp nodes that have no inputs and that are not inputs to any other nodes.
    pub fn clear_disconnected(&mut self) {
        let no_incoming: Vec<_> = self.graph.without_edges(pg::Incoming).collect();
        let no_outgoing: Vec<_> = self.graph.without_edges(pg::Outgoing).collect();
        let indices_for_removal = no_incoming.into_iter()
            .filter(|incoming| no_outgoing.iter().any(|outgoing| outgoing == incoming));
        for idx in indices_for_removal {
            if let Some(master_idx) = self.maybe_master {
                if master_idx == idx {
                    self.maybe_master = None;
                }
            }
            self.graph.remove_node(idx);
        }
    }

    /// Clear all dsp nodes.
    pub fn clear(&mut self) {
        self.graph.clear();
        self.maybe_master = None;
    }

}

impl<'a, S, D> Iterator for Neighbors<'a, S, D> {
    type Item = &'a D;
    fn next(&mut self) -> Option<&'a D> {
        match self.neighbors.next() {
            Some(idx) => {
                let &Node(ref dsp, _) = &self.graph[idx];
                Some(dsp)
            },
            None => None,
        }
    }
}

impl<'a, S, D> Iterator for NeighborsMut<'a, S, D> {
    type Item = &'a mut D;
    fn next(&mut self) -> Option<&'a mut D> {
        let NeighborsMut { ref mut graph, ref mut neighbors } = *self;
        match neighbors.next() {
            Some(idx) => {
                let &mut Node(ref mut dsp, _) = &mut graph[idx];
                let dsp: &mut D = dsp;
                // Without the following unsafe block, rustc complains about
                // input_ref_mut not having a suitable life time. This is because
                // it is concerned about creating aliasing mutable references,
                // however we know that only one mutable reference will be returned
                // at a time and that they will never alias. Thus, we transmute to
                // silence the lifetime warning!
                Some(unsafe { ::std::mem::transmute(dsp) })
            },
            None => None,
        }
    }
}

impl<S, D> ::std::ops::Index<NodeIndex> for Graph<S, D> {
    type Output = D;
    fn index<'a>(&'a self, index: &NodeIndex) -> &'a D {
        let &Node(ref dsp, _) = &self.graph[*index];
        dsp
    }
}

impl<S, D> ::std::ops::IndexMut<NodeIndex> for Graph<S, D> {
    fn index_mut(&mut self, index: &NodeIndex) -> &mut D {
        let &mut Node(ref mut dsp, _) = &mut self.graph[*index];
        dsp
    }
}

impl<S, D> Dsp<S> for Graph<S, D>
    where
        S: Sample,
        D: Dsp<S>,
{
    fn audio_requested(&mut self, output: &mut [S], settings: Settings) {
        if let Some(idx) = self.maybe_master {
            self.audio_requested_from_node(idx, output, settings);
        }
    }
}

/// Request audio from the node at the given index and all incoming nodes.
/// If the node does have incoming neighbors, they will be requested and summed first.
/// This process will continue recursively until all incoming connections have been visited.
#[inline]
fn request_audio_from_graph<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                                  idx: pg::graph::NodeIndex,
                                  output: &mut [S],
                                  settings: Settings)
    where
        S: Sample,
        D: Dsp<S>,
{
    {
        let graph = graph as *mut pg::Graph<Node<S, D>, ()>;
        for neighbor_idx in unsafe { (*graph).neighbors_directed(idx, pg::Incoming) } {
            let graph: &mut pg::Graph<Node<S, D>, ()> = unsafe { ::std::mem::transmute(graph) };
            let mut working = vec![Sample::zero(); settings.buffer_size()];
            request_audio_from_graph(graph, neighbor_idx, &mut working, settings);
            let Node(ref dsp, _) = graph[neighbor_idx];
            let vol_per_channel = dsp.vol_per_channel();
            Sample::add_buffers(output, &working[..], &vol_per_channel[..]);
        }
    }
    request_audio_from_node(graph, idx, output, settings);
}

/// If the node at the given index already has a prepared buffer, clone that.
/// Otherwise, request a new buffer from the dsp object.
fn request_audio_from_node<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                                 idx: pg::graph::NodeIndex,
                                 output: &mut [S],
                                 settings: Settings)
    where
        S: Sample,
        D: Dsp<S>,
{
    if graph.neighbors_directed(idx, pg::Outgoing).take(2).count() > 1 {
        let &mut Node(ref mut dsp, ref mut maybe_buffer) = &mut graph[idx];
        let buffer = match *maybe_buffer {
            Some(ref buffer) => {
                output.clone_from_slice(&buffer[..]);
                return;
            },
            None => {
                let mut buffer = vec![Sample::zero(); settings.buffer_size()];
                dsp.audio_requested(&mut buffer[..], settings);
                output.clone_from_slice(&buffer[..]);
                buffer
            },
        };
        *maybe_buffer = Some(buffer);
    } else {
        let &mut Node(ref mut dsp, _) = &mut graph[idx];
        dsp.audio_requested(output, settings);
    }
}

/// Reset all buffers within all nodes that have incoming connections towards the node at the
/// given index.
fn reset_graph_buffers<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                             idx: pg::graph::NodeIndex,)
    where
        S: Sample,
        D: Dsp<S>,
{
    {
        let graph = graph as *mut pg::Graph<Node<S, D>, ()>;
        for neighbor_idx in unsafe { (*graph).neighbors_directed(idx, pg::Incoming) } {
            let graph: &mut pg::Graph<Node<S, D>, ()> = unsafe { ::std::mem::transmute(graph) };
            reset_graph_buffers(graph, neighbor_idx);
        }
    }
    reset_node_buffer(graph, idx);
}

/// Reset the buffer owned by the node at the given index.
fn reset_node_buffer<S, D>(graph: &mut pg::Graph<Node<S, D>, ()>,
                           idx: pg::graph::NodeIndex)
    where
        S: Sample,
        D: Dsp<S>,
{
    let &mut Node(_, ref mut maybe_buffer) = &mut graph[idx];
    if maybe_buffer.is_some() {
        *maybe_buffer = None;
    }
}

impl ::std::fmt::Display for WouldCycle {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
        writeln!(f, "{:?}", self)
    }
}

impl ::std::error::Error for WouldCycle {
    fn description(&self) -> &str {
        "Adding this input would have caused the graph to cycle!"
    }
}

<|endoftext|>


<commit_before>#![feature(compiler_builtins_lib, lang_items, asm, pointer_methods)]
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(alloc, allocator_api)]
#![feature(global_allocator)]
#![feature(decl_macro)]

#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate alloc;
extern crate slab_allocator;
extern crate spin;
extern crate stack_vec;
extern crate volatile;

#[macro_use]
extern crate log;

extern crate fat32;

#[macro_use]
#[cfg(not(test))]
pub mod print;

//#[cfg(not(test))]
//pub mod console;
pub mod externs;
#[cfg(not(test))]
pub mod panic;

#[cfg(not(test))]
pub mod util;

#[cfg(not(test))]
pub mod exception;
#[cfg(not(test))]
pub mod mmu;

#[cfg(not(test))]
pub mod pi;
#[cfg(not(test))]
pub mod fb;
#[cfg(not(test))]
pub mod shell;
//pub mod sd;
pub mod sdn;
pub mod gles;

pub mod fs;

pub mod allocator;

use slab_allocator::LockedHeap;
use alloc::*;

#[cfg(not(test))]
#[global_allocator]
static mut ALLOCATOR: LockedHeap = LockedHeap::empty();

const BINARY_START_ADDR: usize = 0x8_0000; // 512kb

const ADDR_1MB: usize   = 0x0010_0000;
const ADDR_2MB: usize   = 0x0020_0000;
const ADDR_4MB: usize   = 0x0040_0000;
const ADDR_8MB: usize   = 0x0080_0000;
const ADDR_16MB: usize  = 0x0100_0000;
const ADDR_32MB: usize  = 0x0200_0000;
const ADDR_64MB: usize  = 0x0400_0000;
const ADDR_128MB: usize = 0x0800_0000;
const ADDR_256MB: usize = 0x1000_0000;
const ADDR_512MB: usize = 0x2000_0000;
const ADDR_1GB: usize   = 0x4000_0000;
const ADDR_2GB: usize   = 0x8000_0000;

static FILE_SYSTEM: fs::FileSystem = fs::FileSystem::uninitialized();

#[cfg(not(test))]
pub fn init_heap() {
    // TODO why?
    let heap_start = 0x0F00_0000;
    let heap_end =   0x1000_0000;
    let heap_size = heap_end - heap_start;
    unsafe {
        ALLOCATOR.init(heap_start, heap_size);
    }
}

#[no_mangle]
#[inline(never)]
#[cfg(not(test))]
pub extern "C" fn kernel_main() -> ! {
    init_heap();

    pi::uart0::Uart0::new().initialize();

    kprintln!("      .  ");
    kprintln!("    < 0 >");
    kprintln!("    ./ \\.");
    kprintln!("");

    unsafe {
        let f: u32 = (1 << 0) | (1 << 1) | (1 << 2);
        asm!("msr cntv_ctl_el0, $0" : : "r"(f) : : "volatile");
    }

    let s = String::from("fucking string!");

    kprintln!("Hello Rust Kernel world! 0x{:X} {}", 0xDEAD, s);

    kprintln!("init fs");
    FILE_SYSTEM.initialize();

    {
        use fat32::traits::{FileSystem, Entry};
        use std::io::Read;
        let f = fs.open("/README.md").unwrap();
        let mut f = f.into_file().unwrap();

        let mut s = String::new();
        f.read_to_string(&mut s).unwrap();
        kprintln!("--------");
        kprintln!("{}", s);
        kprintln!("--------");
    }

    if true {
        unsafe {
            mmu::init();
        }

        kprintln!("enabled mmu");

        if false {
            use volatile::*;
            // generate a Data Abort with a bad address access
            let r = 0xFFFF_FFFF_FF00_0000 as *mut Volatile<u32>;
            unsafe { (*r).write(1) }
        }

        if false {
            const KERNEL_UART0: usize = 0xFFFFFF80_3F201000;

            let s = format!("fuck {:016X}\n", KERNEL_UART0);
            let mut uart = unsafe { pi::uart0::Uart0::from_addr(KERNEL_UART0) };
            for c in s.chars() {
                uart.send(c as u8);
            }
        }
    }

    unsafe {
        let level: u32;
        // read the current level from system register
        asm!("mrs $0, CurrentEL" : "=r" (level) : : : "volatile");
        kprintln!("Current EL is: 0x{:X} [0x{:X}]", (level >> 2) & 3, level);
    }

    {
        kprint!("Waiting 1000000 CPU cycles (ARM CPU): ");
        util::wait_cycles(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (ARM CPU): ");
        util::wait_msec(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (BCM System Timer): ");
        if pi::timer::current_time() == 0 {
            kprintln!("Not available");
        } else {
            pi::timer::spin_sleep_us(1000000);
            kprintln!("OK");
        }
    }

    kprintln!("init fb");

    match fb::FrameBuffer::new(480, 320, 32) {
        Some(mut fb) =>  {
            fb.fill_rgba(0x000000);
            fb::font().uprint(&mut fb, 13, 5, "Prepare uranus!", 0x00FF00, 0x0000FF);
            fb::font().uprint(&mut fb, 13, 6, "Prepare uranus!", 0xFF0000, 0x0000FF);
            fb::font().uprint(&mut fb, 11, 8, "< Prepare uranus! >", 0xFF0000, 0x000000);

            fb::font().uprint(&mut fb, 1, 0, "  .  ",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 1, "< 0 >",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 2, "./ \\.", 0xFFFFFF, 0x000000);

        }
        None => kprintln!("Unable to set screen resolution to 1024x768x32"),
    }

    kprintln!("init gles: {:?}", gles::InitV3D());

    shell::shell("> ")
}
<commit_msg>fix src/kmain.rs<commit_after>#![feature(compiler_builtins_lib, lang_items, asm, pointer_methods)]
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(alloc, allocator_api)]
#![feature(global_allocator)]
#![feature(decl_macro)]

#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate alloc;
extern crate slab_allocator;
extern crate spin;
extern crate stack_vec;
extern crate volatile;

#[macro_use]
extern crate log;

extern crate fat32;

#[macro_use]
#[cfg(not(test))]
pub mod print;

//#[cfg(not(test))]
//pub mod console;
pub mod externs;
#[cfg(not(test))]
pub mod panic;

#[cfg(not(test))]
pub mod util;

#[cfg(not(test))]
pub mod exception;
#[cfg(not(test))]
pub mod mmu;

#[cfg(not(test))]
pub mod pi;
#[cfg(not(test))]
pub mod fb;
#[cfg(not(test))]
pub mod shell;
//pub mod sd;
pub mod sdn;
pub mod gles;

pub mod fs;

pub mod allocator;

use slab_allocator::LockedHeap;
use alloc::*;

#[cfg(not(test))]
#[global_allocator]
static mut ALLOCATOR: LockedHeap = LockedHeap::empty();

const BINARY_START_ADDR: usize = 0x8_0000; // 512kb

const ADDR_1MB: usize   = 0x0010_0000;
const ADDR_2MB: usize   = 0x0020_0000;
const ADDR_4MB: usize   = 0x0040_0000;
const ADDR_8MB: usize   = 0x0080_0000;
const ADDR_16MB: usize  = 0x0100_0000;
const ADDR_32MB: usize  = 0x0200_0000;
const ADDR_64MB: usize  = 0x0400_0000;
const ADDR_128MB: usize = 0x0800_0000;
const ADDR_256MB: usize = 0x1000_0000;
const ADDR_512MB: usize = 0x2000_0000;
const ADDR_1GB: usize   = 0x4000_0000;
const ADDR_2GB: usize   = 0x8000_0000;

static FILE_SYSTEM: fs::FileSystem = fs::FileSystem::uninitialized();

#[cfg(not(test))]
pub fn init_heap() {
    // TODO why?
    let heap_start = 0x0F00_0000;
    let heap_end =   0x1000_0000;
    let heap_size = heap_end - heap_start;
    unsafe {
        ALLOCATOR.init(heap_start, heap_size);
    }
}

#[no_mangle]
#[inline(never)]
#[cfg(not(test))]
pub extern "C" fn kernel_main() -> ! {
    init_heap();

    pi::uart0::Uart0::new().initialize();

    kprintln!("      .  ");
    kprintln!("    < 0 >");
    kprintln!("    ./ \\.");
    kprintln!("");

    unsafe {
        let f: u32 = (1 << 0) | (1 << 1) | (1 << 2);
        asm!("msr cntv_ctl_el0, $0" : : "r"(f) : : "volatile");
    }

    let s = String::from("fucking string!");

    kprintln!("Hello Rust Kernel world! 0x{:X} {}", 0xDEAD, s);

    kprintln!("init fs");
    FILE_SYSTEM.initialize();

    {
        use fat32::traits::{FileSystem, Entry};
        use std::io::Read;
        let f = FILE_SYSTEM.open("/README.md").unwrap();
        let mut f = f.into_file().unwrap();

        let mut s = String::new();
        f.read_to_string(&mut s).unwrap();
        kprintln!("--------");
        kprintln!("{}", s);
        kprintln!("--------");
    }

    if true {
        unsafe {
            mmu::init();
        }

        kprintln!("enabled mmu");

        if false {
            use volatile::*;
            // generate a Data Abort with a bad address access
            let r = 0xFFFF_FFFF_FF00_0000 as *mut Volatile<u32>;
            unsafe { (*r).write(1) }
        }

        if false {
            const KERNEL_UART0: usize = 0xFFFFFF80_3F201000;

            let s = format!("fuck {:016X}\n", KERNEL_UART0);
            let mut uart = unsafe { pi::uart0::Uart0::from_addr(KERNEL_UART0) };
            for c in s.chars() {
                uart.send(c as u8);
            }
        }
    }

    unsafe {
        let level: u32;
        // read the current level from system register
        asm!("mrs $0, CurrentEL" : "=r" (level) : : : "volatile");
        kprintln!("Current EL is: 0x{:X} [0x{:X}]", (level >> 2) & 3, level);
    }

    {
        kprint!("Waiting 1000000 CPU cycles (ARM CPU): ");
        util::wait_cycles(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (ARM CPU): ");
        util::wait_msec(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (BCM System Timer): ");
        if pi::timer::current_time() == 0 {
            kprintln!("Not available");
        } else {
            pi::timer::spin_sleep_us(1000000);
            kprintln!("OK");
        }
    }

    kprintln!("init fb");

    match fb::FrameBuffer::new(480, 320, 32) {
        Some(mut fb) =>  {
            fb.fill_rgba(0x000000);
            fb::font().uprint(&mut fb, 13, 5, "Prepare uranus!", 0x00FF00, 0x0000FF);
            fb::font().uprint(&mut fb, 13, 6, "Prepare uranus!", 0xFF0000, 0x0000FF);
            fb::font().uprint(&mut fb, 11, 8, "< Prepare uranus! >", 0xFF0000, 0x000000);

            fb::font().uprint(&mut fb, 1, 0, "  .  ",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 1, "< 0 >",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 2, "./ \\.", 0xFFFFFF, 0x000000);

        }
        None => kprintln!("Unable to set screen resolution to 1024x768x32"),
    }

    kprintln!("init gles: {:?}", gles::InitV3D());

    shell::shell("> ")
}
<|endoftext|>


<commit_before>use jsrs_common::ast::BinOp::*;

#[test]
fn star() {
    assert!(Star.precedence() == Slash.precedence());
    assert!(Star.precedence() > Plus.precedence());
    assert!(Star.precedence() > Minus.precedence());
    assert!(Star.precedence() > Eql.precedence());
    assert!(Star.precedence() > Neq.precedence());
    assert!(Star.precedence() > Gt.precedence());
    assert!(Star.precedence() > Ge.precedence());
    assert!(Star.precedence() > Lt.precedence());
    assert!(Star.precedence() > Le.precedence());
    assert!(Star.precedence() > And.precedence());
    assert!(Star.precedence() > Or.precedence());
}

#[test]
fn slash() {
    assert!(Slash.precedence() == Star.precedence());
    assert!(Slash.precedence() > Plus.precedence());
    assert!(Slash.precedence() > Minus.precedence());
    assert!(Slash.precedence() > Eql.precedence());
    assert!(Slash.precedence() > Neq.precedence());
    assert!(Slash.precedence() > Gt.precedence());
    assert!(Slash.precedence() > Ge.precedence());
    assert!(Slash.precedence() > Lt.precedence());
    assert!(Slash.precedence() > Le.precedence());
    assert!(Slash.precedence() > And.precedence());
    assert!(Slash.precedence() > Or.precedence());
}

#[test]
fn plus() {
    assert!(Plus.precedence() < Star.precedence());
    assert!(Plus.precedence() < Slash.precedence());
    assert!(Plus.precedence() == Minus.precedence());
    assert!(Plus.precedence() > Eql.precedence());
    assert!(Plus.precedence() > Neq.precedence());
    assert!(Plus.precedence() > Gt.precedence());
    assert!(Plus.precedence() > Ge.precedence());
    assert!(Plus.precedence() > Lt.precedence());
    assert!(Plus.precedence() > Le.precedence());
    assert!(Plus.precedence() > And.precedence());
    assert!(Plus.precedence() > Or.precedence());
}

#[test]
fn minus() {
    assert!(Minus.precedence() < Star.precedence());
    assert!(Minus.precedence() < Slash.precedence());
    assert!(Minus.precedence() == Plus.precedence());
    assert!(Minus.precedence() > Eql.precedence());
    assert!(Minus.precedence() > Neq.precedence());
    assert!(Minus.precedence() > Gt.precedence());
    assert!(Minus.precedence() > Ge.precedence());
    assert!(Minus.precedence() > Lt.precedence());
    assert!(Minus.precedence() > Le.precedence());
    assert!(Minus.precedence() > And.precedence());
    assert!(Minus.precedence() > Or.precedence());
}

#[test]
fn eql() {
    assert!(Eql.precedence() < Star.precedence());
    assert!(Eql.precedence() < Slash.precedence());
    assert!(Eql.precedence() < Plus.precedence());
    assert!(Eql.precedence() < Minus.precedence());
    assert!(Eql.precedence() == Neq.precedence());
    assert!(Eql.precedence() == Gt.precedence());
    assert!(Eql.precedence() == Ge.precedence());
    assert!(Eql.precedence() == Lt.precedence());
    assert!(Eql.precedence() == Le.precedence());
    assert!(Eql.precedence() > And.precedence());
    assert!(Eql.precedence() > Or.precedence());
}

#[test]
fn neq() {
    assert!(Neq.precedence() < Star.precedence());
    assert!(Neq.precedence() < Slash.precedence());
    assert!(Neq.precedence() < Plus.precedence());
    assert!(Neq.precedence() < Minus.precedence());
    assert!(Neq.precedence() == Eql.precedence());
    assert!(Neq.precedence() == Gt.precedence());
    assert!(Neq.precedence() == Ge.precedence());
    assert!(Neq.precedence() == Lt.precedence());
    assert!(Neq.precedence() == Le.precedence());
    assert!(Neq.precedence() > And.precedence());
    assert!(Neq.precedence() > Or.precedence());
}

#[test]
fn gt() {
    assert!(Gt.precedence() < Star.precedence());
    assert!(Gt.precedence() < Slash.precedence());
    assert!(Gt.precedence() < Plus.precedence());
    assert!(Gt.precedence() < Minus.precedence());
    assert!(Gt.precedence() == Eql.precedence());
    assert!(Gt.precedence() == Neq.precedence());
    assert!(Gt.precedence() == Ge.precedence());
    assert!(Gt.precedence() == Lt.precedence());
    assert!(Gt.precedence() == Le.precedence());
    assert!(Gt.precedence() > And.precedence());
    assert!(Gt.precedence() > Or.precedence());
}

#[test]
fn ge() {
    assert!(Ge.precedence() < Star.precedence());
    assert!(Ge.precedence() < Slash.precedence());
    assert!(Ge.precedence() < Plus.precedence());
    assert!(Ge.precedence() < Minus.precedence());
    assert!(Ge.precedence() == Eql.precedence());
    assert!(Ge.precedence() == Neq.precedence());
    assert!(Ge.precedence() == Gt.precedence());
    assert!(Ge.precedence() == Lt.precedence());
    assert!(Ge.precedence() == Le.precedence());
    assert!(Ge.precedence() > And.precedence());
    assert!(Ge.precedence() > Or.precedence());
}

#[test]
fn lt() {
    assert!(Lt.precedence() < Star.precedence());
    assert!(Lt.precedence() < Slash.precedence());
    assert!(Lt.precedence() < Plus.precedence());
    assert!(Lt.precedence() < Minus.precedence());
    assert!(Lt.precedence() == Eql.precedence());
    assert!(Lt.precedence() == Neq.precedence());
    assert!(Lt.precedence() == Gt.precedence());
    assert!(Lt.precedence() == Ge.precedence());
    assert!(Lt.precedence() == Le.precedence());
    assert!(Lt.precedence() > And.precedence());
    assert!(Lt.precedence() > Or.precedence());
}

#[test]
fn le() {
    assert!(Le.precedence() < Star.precedence());
    assert!(Le.precedence() < Slash.precedence());
    assert!(Le.precedence() < Plus.precedence());
    assert!(Le.precedence() < Minus.precedence());
    assert!(Le.precedence() == Eql.precedence());
    assert!(Le.precedence() == Neq.precedence());
    assert!(Le.precedence() == Gt.precedence());
    assert!(Le.precedence() == Ge.precedence());
    assert!(Le.precedence() == Lt.precedence());
    assert!(Le.precedence() > And.precedence());
    assert!(Le.precedence() > Or.precedence());
}

#[test]
fn and() {
    assert!(And.precedence() < Star.precedence());
    assert!(And.precedence() < Slash.precedence());
    assert!(And.precedence() < Plus.precedence());
    assert!(And.precedence() < Minus.precedence());
    assert!(And.precedence() < Eql.precedence());
    assert!(And.precedence() < Neq.precedence());
    assert!(And.precedence() < Gt.precedence());
    assert!(And.precedence() < Ge.precedence());
    assert!(And.precedence() < Lt.precedence());
    assert!(And.precedence() < Le.precedence());
    assert!(And.precedence() > Or.precedence());
}

#[test]
fn or() {
    assert!(Or.precedence() < Star.precedence());
    assert!(Or.precedence() < Slash.precedence());
    assert!(Or.precedence() < Plus.precedence());
    assert!(Or.precedence() < Minus.precedence());
    assert!(Or.precedence() < Eql.precedence());
    assert!(Or.precedence() < Neq.precedence());
    assert!(Or.precedence() < Gt.precedence());
    assert!(Or.precedence() < Ge.precedence());
    assert!(Or.precedence() < Lt.precedence());
    assert!(Or.precedence() < Le.precedence());
    assert!(Or.precedence() < And.precedence());
}
<commit_msg>Update tests<commit_after>use jsrs_common::ast::BinOp::*;

#[test]
fn star() {
    assert!(Star.precedence() == Slash.precedence());
    assert!(Star.precedence() > Plus.precedence());
    assert!(Star.precedence() > Minus.precedence());
    assert!(Star.precedence() > Eql.precedence());
    assert!(Star.precedence() > Neq.precedence());
    assert!(Star.precedence() > Gt.precedence());
    assert!(Star.precedence() > Ge.precedence());
    assert!(Star.precedence() > Lt.precedence());
    assert!(Star.precedence() > Le.precedence());
    assert!(Star.precedence() > And.precedence());
    assert!(Star.precedence() > Or.precedence());
}

#[test]
fn slash() {
    assert!(Slash.precedence() == Star.precedence());
    assert!(Slash.precedence() > Plus.precedence());
    assert!(Slash.precedence() > Minus.precedence());
    assert!(Slash.precedence() > Eql.precedence());
    assert!(Slash.precedence() > Neq.precedence());
    assert!(Slash.precedence() > Gt.precedence());
    assert!(Slash.precedence() > Ge.precedence());
    assert!(Slash.precedence() > Lt.precedence());
    assert!(Slash.precedence() > Le.precedence());
    assert!(Slash.precedence() > And.precedence());
    assert!(Slash.precedence() > Or.precedence());
}

#[test]
fn plus() {
    assert!(Plus.precedence() < Star.precedence());
    assert!(Plus.precedence() < Slash.precedence());
    assert!(Plus.precedence() == Minus.precedence());
    assert!(Plus.precedence() > Eql.precedence());
    assert!(Plus.precedence() > Neq.precedence());
    assert!(Plus.precedence() > Gt.precedence());
    assert!(Plus.precedence() > Ge.precedence());
    assert!(Plus.precedence() > Lt.precedence());
    assert!(Plus.precedence() > Le.precedence());
    assert!(Plus.precedence() > And.precedence());
    assert!(Plus.precedence() > Or.precedence());
}

#[test]
fn minus() {
    assert!(Minus.precedence() < Star.precedence());
    assert!(Minus.precedence() < Slash.precedence());
    assert!(Minus.precedence() == Plus.precedence());
    assert!(Minus.precedence() > Eql.precedence());
    assert!(Minus.precedence() > Neq.precedence());
    assert!(Minus.precedence() > Gt.precedence());
    assert!(Minus.precedence() > Ge.precedence());
    assert!(Minus.precedence() > Lt.precedence());
    assert!(Minus.precedence() > Le.precedence());
    assert!(Minus.precedence() > And.precedence());
    assert!(Minus.precedence() > Or.precedence());
}

#[test]
fn eql() {
    assert!(Eql.precedence() < Star.precedence());
    assert!(Eql.precedence() < Slash.precedence());
    assert!(Eql.precedence() < Plus.precedence());
    assert!(Eql.precedence() < Minus.precedence());
    assert!(Eql.precedence() == Neq.precedence());
    assert!(Eql.precedence() < Gt.precedence());
    assert!(Eql.precedence() < Ge.precedence());
    assert!(Eql.precedence() < Lt.precedence());
    assert!(Eql.precedence() < Le.precedence());
    assert!(Eql.precedence() > And.precedence());
    assert!(Eql.precedence() > Or.precedence());
}

#[test]
fn neq() {
    assert!(Neq.precedence() < Star.precedence());
    assert!(Neq.precedence() < Slash.precedence());
    assert!(Neq.precedence() < Plus.precedence());
    assert!(Neq.precedence() < Minus.precedence());
    assert!(Neq.precedence() == Eql.precedence());
    assert!(Neq.precedence() < Gt.precedence());
    assert!(Neq.precedence() < Ge.precedence());
    assert!(Neq.precedence() < Lt.precedence());
    assert!(Neq.precedence() < Le.precedence());
    assert!(Neq.precedence() > And.precedence());
    assert!(Neq.precedence() > Or.precedence());
}

#[test]
fn gt() {
    assert!(Gt.precedence() < Star.precedence());
    assert!(Gt.precedence() < Slash.precedence());
    assert!(Gt.precedence() < Plus.precedence());
    assert!(Gt.precedence() < Minus.precedence());
    assert!(Gt.precedence() > Eql.precedence());
    assert!(Gt.precedence() > Neq.precedence());
    assert!(Gt.precedence() == Ge.precedence());
    assert!(Gt.precedence() == Lt.precedence());
    assert!(Gt.precedence() == Le.precedence());
    assert!(Gt.precedence() > And.precedence());
    assert!(Gt.precedence() > Or.precedence());
}

#[test]
fn ge() {
    assert!(Ge.precedence() < Star.precedence());
    assert!(Ge.precedence() < Slash.precedence());
    assert!(Ge.precedence() < Plus.precedence());
    assert!(Ge.precedence() < Minus.precedence());
    assert!(Ge.precedence() > Eql.precedence());
    assert!(Ge.precedence() > Neq.precedence());
    assert!(Ge.precedence() == Gt.precedence());
    assert!(Ge.precedence() == Lt.precedence());
    assert!(Ge.precedence() == Le.precedence());
    assert!(Ge.precedence() > And.precedence());
    assert!(Ge.precedence() > Or.precedence());
}

#[test]
fn lt() {
    assert!(Lt.precedence() < Star.precedence());
    assert!(Lt.precedence() < Slash.precedence());
    assert!(Lt.precedence() < Plus.precedence());
    assert!(Lt.precedence() < Minus.precedence());
    assert!(Lt.precedence() > Eql.precedence());
    assert!(Lt.precedence() > Neq.precedence());
    assert!(Lt.precedence() == Gt.precedence());
    assert!(Lt.precedence() == Ge.precedence());
    assert!(Lt.precedence() == Le.precedence());
    assert!(Lt.precedence() > And.precedence());
    assert!(Lt.precedence() > Or.precedence());
}

#[test]
fn le() {
    assert!(Le.precedence() < Star.precedence());
    assert!(Le.precedence() < Slash.precedence());
    assert!(Le.precedence() < Plus.precedence());
    assert!(Le.precedence() < Minus.precedence());
    assert!(Le.precedence() > Eql.precedence());
    assert!(Le.precedence() > Neq.precedence());
    assert!(Le.precedence() == Gt.precedence());
    assert!(Le.precedence() == Ge.precedence());
    assert!(Le.precedence() == Lt.precedence());
    assert!(Le.precedence() > And.precedence());
    assert!(Le.precedence() > Or.precedence());
}

#[test]
fn and() {
    assert!(And.precedence() < Star.precedence());
    assert!(And.precedence() < Slash.precedence());
    assert!(And.precedence() < Plus.precedence());
    assert!(And.precedence() < Minus.precedence());
    assert!(And.precedence() < Eql.precedence());
    assert!(And.precedence() < Neq.precedence());
    assert!(And.precedence() < Gt.precedence());
    assert!(And.precedence() < Ge.precedence());
    assert!(And.precedence() < Lt.precedence());
    assert!(And.precedence() < Le.precedence());
    assert!(And.precedence() > Or.precedence());
}

#[test]
fn or() {
    assert!(Or.precedence() < Star.precedence());
    assert!(Or.precedence() < Slash.precedence());
    assert!(Or.precedence() < Plus.precedence());
    assert!(Or.precedence() < Minus.precedence());
    assert!(Or.precedence() < Eql.precedence());
    assert!(Or.precedence() < Neq.precedence());
    assert!(Or.precedence() < Gt.precedence());
    assert!(Or.precedence() < Ge.precedence());
    assert!(Or.precedence() < Lt.precedence());
    assert!(Or.precedence() < Le.precedence());
    assert!(Or.precedence() < And.precedence());
}
<|endoftext|>


<commit_before>pub use std::collections::HashMap;
pub use api::*;
use errors::*;
use serde::{Deserialize, Serialize};
use serde_json::{from_value, to_value, Value, Map};

/// A trait for any struct that can be converted from/into a Resource.
/// The only requirement is that your struct has an 'id: String' field.
/// You shouldn't be implementing JsonApiModel manually, look at the
/// `jsonapi_model!` macro instead.
pub trait JsonApiModel: Serialize
where
    for<'de> Self: Deserialize<'de>,
{
    #[doc(hidden)]
    fn jsonapi_type(&self) -> String;
    #[doc(hidden)]
    fn jsonapi_id(&self) -> String;
    #[doc(hidden)]
    fn relationship_fields() -> Option<&'static [&'static str]>;
    #[doc(hidden)]
    fn build_relationships(&self) -> Option<Relationships>;
    #[doc(hidden)]
    fn build_included(&self) -> Option<Resources>;

    fn from_jsonapi_resource(resource: &Resource, included: &Option<Resources>) -> Result<Self> {
        Self::from_serializable(Self::resource_to_attrs(resource, included))
    }

    fn from_jsonapi_document(doc: &JsonApiDocument) -> Result<Self> {
        match doc.data.as_ref() {
            Some(primary_data) => {
                match *primary_data {
                    PrimaryData::None => bail!("Document had no data"),
                    PrimaryData::Single(ref resource) => {
                        Self::from_jsonapi_resource(resource, &doc.included)
                    }
                    PrimaryData::Multiple(ref resources) => {
                        let all: Vec<ResourceAttributes> = resources
                            .iter()
                            .map(|r| Self::resource_to_attrs(r, &doc.included))
                            .collect();
                        Self::from_serializable(all)
                    }
                }
            }
            None => bail!("Document had no data"),
        }
    }

    fn to_jsonapi_resource(&self) -> (Resource, Option<Resources>) {
        if let Value::Object(mut attrs) = to_value(self).unwrap() {
            let _ = attrs.remove("id");
            let resource = Resource {
                _type: self.jsonapi_type(),
                id: self.jsonapi_id(),
                relationships: self.build_relationships(),
                attributes: Self::extract_attributes(&attrs),
                ..Default::default()
            };

            (resource, self.build_included())
        } else {
            panic!(format!("{} is not a Value::Object", self.jsonapi_type()))
        }
    }

    fn to_jsonapi_document(&self) -> JsonApiDocument {
        let (resource, included) = self.to_jsonapi_resource();
        JsonApiDocument {
            data: Some(PrimaryData::Single(Box::new(resource))),
            included,
            ..Default::default()
        }
    }

    #[doc(hidden)]
    fn build_has_one<M: JsonApiModel>(model: &M) -> Relationship {
        Relationship {
            data: IdentifierData::Single(model.as_resource_identifier()),
            links: None,
        }
    }

    #[doc(hidden)]
    fn build_has_many<M: JsonApiModel>(models: &[M]) -> Relationship {
        Relationship {
            data: IdentifierData::Multiple(
                models.iter().map(|m| m.as_resource_identifier()).collect(),
            ),
            links: None,
        }
    }

    #[doc(hidden)]
    fn as_resource_identifier(&self) -> ResourceIdentifier {
        ResourceIdentifier {
            _type: self.jsonapi_type(),
            id: self.jsonapi_id(),
        }
    }

    /* Attribute corresponding to the model is removed from the Map
     * before calling this, so there's no need to ignore it like we do
     * with the attributes that correspond with relationships.
     * */
    #[doc(hidden)]
    fn extract_attributes(attrs: &Map<String, Value>) -> ResourceAttributes {
        attrs
            .iter()
            .filter(|&(key, _)| {
                if let Some(fields) = Self::relationship_fields() {
                    if fields.contains(&key.as_str()) {
                        return false;
                    }
                }
                true
            })
            .map(|(k, v)| (k.clone(), v.clone()))
            .collect()
    }

    #[doc(hidden)]
    fn to_resources(&self) -> Resources {
        let (me, maybe_others) = self.to_jsonapi_resource();
        let mut flattened = vec![me];
        if let Some(mut others) = maybe_others {
            flattened.append(&mut others);
        }
        flattened
    }

    #[doc(hidden)]
    fn lookup<'a>(needle: &ResourceIdentifier, haystack: &'a [Resource]) -> Option<&'a Resource> {
        for resource in haystack {
            if resource._type == needle._type && resource.id == needle.id {
                return Some(resource);
            }
        }
        None
    }

    #[doc(hidden)]
    fn resource_to_attrs(resource: &Resource, included: &Option<Resources>) -> ResourceAttributes {
        let mut new_attrs = HashMap::new();
        new_attrs.clone_from(&resource.attributes);
        new_attrs.insert("id".into(), resource.id.clone().into());

        if let Some(relations) = resource.relationships.as_ref() {
            if let Some(inc) = included.as_ref() {
                for (name, relation) in relations {
                    let value =
                        match relation.data {
                            IdentifierData::None => Value::Null,
                            IdentifierData::Single(ref identifier) => {
                                let found = Self::lookup(identifier, inc).map(|r| {
                                    Self::resource_to_attrs(r, included)
                                });
                                to_value(found).expect("Casting Single relation to value")
                            }
                            IdentifierData::Multiple(ref identifiers) => {
                                let found: Vec<Option<ResourceAttributes>> =
                                identifiers.iter().map(|id|{
                                    Self::lookup(id, inc).map(|r|{
                                        Self::resource_to_attrs(r, included)
                                    })
                                }).collect();
                                to_value(found).expect("Casting Multiple relation to value")
                            }
                        };
                    new_attrs.insert(name.to_string(), value);
                }
            }
        }

        new_attrs
    }

    #[doc(hidden)]
    fn from_serializable<S: Serialize>(s: S) -> Result<Self> {
        from_value(to_value(s).unwrap()).chain_err(|| "Error casting via serde_json")
    }
}

pub fn vec_to_jsonapi_resources<T: JsonApiModel>(
    objects: Vec<T>,
) -> (Resources, Option<Resources>) {
    let mut included = vec![];
    let resources = objects
        .iter()
        .map(|obj| {
            let (res, mut opt_incl) = obj.to_jsonapi_resource();
            if let Some(ref mut incl) = opt_incl {
                included.append(incl);
            }
            res
        })
        .collect::<Vec<_>>();
    let opt_included = if included.is_empty() {
        None
    } else {
        Some(included)
    };
    (resources, opt_included)
}

pub fn vec_to_jsonapi_document<T: JsonApiModel>(objects: Vec<T>) -> JsonApiDocument {
    let (resources, included) = vec_to_jsonapi_resources(objects);
    JsonApiDocument {
        data: Some(PrimaryData::Multiple(resources)),
        included,
        ..Default::default()
    }
}

#[macro_export]
macro_rules! jsonapi_model {
    ($model:ty; $type:expr) => (
        impl JsonApiModel for $model {
            fn jsonapi_type(&self) -> String { $type.to_string() }
            fn jsonapi_id(&self) -> String { self.id.to_string() }
            fn relationship_fields() -> Option<&'static [&'static str]> { None }
            fn build_relationships(&self) -> Option<Relationships> { None }
            fn build_included(&self) -> Option<Resources> { None }
        }
    );
    ($model:ty; $type:expr;
        has one $( $has_one:ident ),*
    ) => (
        jsonapi_model!($model; $type; has one $( $has_one ),*; has many);
    );
    ($model:ty; $type:expr;
        has many $( $has_many:ident ),*
    ) => (
        jsonapi_model!($model; $type; has one; has many $( $has_many ),*);
    );
    ($model:ty; $type:expr;
        has one $( $has_one:ident ),*;
        has many $( $has_many:ident ),*
    ) => (
        impl JsonApiModel for $model {
            fn jsonapi_type(&self) -> String { $type.to_string() }
            fn jsonapi_id(&self) -> String { self.id.to_string() }

            fn relationship_fields() -> Option<&'static [&'static str]> {
                static FIELDS: &'static [&'static str] = &[
                     $( stringify!($has_one),)*
                     $( stringify!($has_many),)*
                ];

                Some(FIELDS)
            }

            fn build_relationships(&self) -> Option<Relationships> {
                let mut relationships = HashMap::new();
                $(
                    relationships.insert(stringify!($has_one).into(),
                        Self::build_has_one(&self.$has_one)
                    );
                )*
                $(
                    relationships.insert(stringify!($has_many).into(),
                        Self::build_has_many(&self.$has_many)
                    );
                )*
                Some(relationships)
            }

            fn build_included(&self) -> Option<Resources> {
                let mut included:Resources = vec![];
                $( included.append(&mut self.$has_one.to_resources()); )*
                $(
                    for model in &self.$has_many {
                        included.append(&mut model.to_resources());
                    }
                )*
                Some(included)
            }
        }
    );
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Dog {
    id: String,
    name: String,
    age: i32,
    main_flea: Flea,
    fleas: Vec<Flea>,
}
jsonapi_model!(Dog; "dog"; has one main_flea; has many fleas);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Flea {
    id: String,
    name: String,
}
jsonapi_model!(Flea; "flea");
<commit_msg>:sparkles: Derive JsonApiModel for Box<M> where M: JsonApiModel<commit_after>pub use std::collections::HashMap;
pub use api::*;
use errors::*;
use serde::{Deserialize, Serialize};
use serde_json::{from_value, to_value, Value, Map};

/// A trait for any struct that can be converted from/into a Resource.
/// The only requirement is that your struct has an 'id: String' field.
/// You shouldn't be implementing JsonApiModel manually, look at the
/// `jsonapi_model!` macro instead.
pub trait JsonApiModel: Serialize
where
    for<'de> Self: Deserialize<'de>,
{
    #[doc(hidden)]
    fn jsonapi_type(&self) -> String;
    #[doc(hidden)]
    fn jsonapi_id(&self) -> String;
    #[doc(hidden)]
    fn relationship_fields() -> Option<&'static [&'static str]>;
    #[doc(hidden)]
    fn build_relationships(&self) -> Option<Relationships>;
    #[doc(hidden)]
    fn build_included(&self) -> Option<Resources>;

    fn from_jsonapi_resource(resource: &Resource, included: &Option<Resources>) -> Result<Self> {
        Self::from_serializable(Self::resource_to_attrs(resource, included))
    }

    fn from_jsonapi_document(doc: &JsonApiDocument) -> Result<Self> {
        match doc.data.as_ref() {
            Some(primary_data) => {
                match *primary_data {
                    PrimaryData::None => bail!("Document had no data"),
                    PrimaryData::Single(ref resource) => {
                        Self::from_jsonapi_resource(resource, &doc.included)
                    }
                    PrimaryData::Multiple(ref resources) => {
                        let all: Vec<ResourceAttributes> = resources
                            .iter()
                            .map(|r| Self::resource_to_attrs(r, &doc.included))
                            .collect();
                        Self::from_serializable(all)
                    }
                }
            }
            None => bail!("Document had no data"),
        }
    }

    fn to_jsonapi_resource(&self) -> (Resource, Option<Resources>) {
        if let Value::Object(mut attrs) = to_value(self).unwrap() {
            let _ = attrs.remove("id");
            let resource = Resource {
                _type: self.jsonapi_type(),
                id: self.jsonapi_id(),
                relationships: self.build_relationships(),
                attributes: Self::extract_attributes(&attrs),
                ..Default::default()
            };

            (resource, self.build_included())
        } else {
            panic!(format!("{} is not a Value::Object", self.jsonapi_type()))
        }
    }

    fn to_jsonapi_document(&self) -> JsonApiDocument {
        let (resource, included) = self.to_jsonapi_resource();
        JsonApiDocument {
            data: Some(PrimaryData::Single(Box::new(resource))),
            included,
            ..Default::default()
        }
    }

    #[doc(hidden)]
    fn build_has_one<M: JsonApiModel>(model: &M) -> Relationship {
        Relationship {
            data: IdentifierData::Single(model.as_resource_identifier()),
            links: None,
        }
    }

    #[doc(hidden)]
    fn build_has_many<M: JsonApiModel>(models: &[M]) -> Relationship {
        Relationship {
            data: IdentifierData::Multiple(
                models.iter().map(|m| m.as_resource_identifier()).collect(),
            ),
            links: None,
        }
    }

    #[doc(hidden)]
    fn as_resource_identifier(&self) -> ResourceIdentifier {
        ResourceIdentifier {
            _type: self.jsonapi_type(),
            id: self.jsonapi_id(),
        }
    }

    /* Attribute corresponding to the model is removed from the Map
     * before calling this, so there's no need to ignore it like we do
     * with the attributes that correspond with relationships.
     * */
    #[doc(hidden)]
    fn extract_attributes(attrs: &Map<String, Value>) -> ResourceAttributes {
        attrs
            .iter()
            .filter(|&(key, _)| {
                if let Some(fields) = Self::relationship_fields() {
                    if fields.contains(&key.as_str()) {
                        return false;
                    }
                }
                true
            })
            .map(|(k, v)| (k.clone(), v.clone()))
            .collect()
    }

    #[doc(hidden)]
    fn to_resources(&self) -> Resources {
        let (me, maybe_others) = self.to_jsonapi_resource();
        let mut flattened = vec![me];
        if let Some(mut others) = maybe_others {
            flattened.append(&mut others);
        }
        flattened
    }

    #[doc(hidden)]
    fn lookup<'a>(needle: &ResourceIdentifier, haystack: &'a [Resource]) -> Option<&'a Resource> {
        for resource in haystack {
            if resource._type == needle._type && resource.id == needle.id {
                return Some(resource);
            }
        }
        None
    }

    #[doc(hidden)]
    fn resource_to_attrs(resource: &Resource, included: &Option<Resources>) -> ResourceAttributes {
        let mut new_attrs = HashMap::new();
        new_attrs.clone_from(&resource.attributes);
        new_attrs.insert("id".into(), resource.id.clone().into());

        if let Some(relations) = resource.relationships.as_ref() {
            if let Some(inc) = included.as_ref() {
                for (name, relation) in relations {
                    let value =
                        match relation.data {
                            IdentifierData::None => Value::Null,
                            IdentifierData::Single(ref identifier) => {
                                let found = Self::lookup(identifier, inc).map(|r| {
                                    Self::resource_to_attrs(r, included)
                                });
                                to_value(found).expect("Casting Single relation to value")
                            }
                            IdentifierData::Multiple(ref identifiers) => {
                                let found: Vec<Option<ResourceAttributes>> =
                                identifiers.iter().map(|id|{
                                    Self::lookup(id, inc).map(|r|{
                                        Self::resource_to_attrs(r, included)
                                    })
                                }).collect();
                                to_value(found).expect("Casting Multiple relation to value")
                            }
                        };
                    new_attrs.insert(name.to_string(), value);
                }
            }
        }

        new_attrs
    }

    #[doc(hidden)]
    fn from_serializable<S: Serialize>(s: S) -> Result<Self> {
        from_value(to_value(s).unwrap()).chain_err(|| "Error casting via serde_json")
    }
}

pub fn vec_to_jsonapi_resources<T: JsonApiModel>(
    objects: Vec<T>,
) -> (Resources, Option<Resources>) {
    let mut included = vec![];
    let resources = objects
        .iter()
        .map(|obj| {
            let (res, mut opt_incl) = obj.to_jsonapi_resource();
            if let Some(ref mut incl) = opt_incl {
                included.append(incl);
            }
            res
        })
        .collect::<Vec<_>>();
    let opt_included = if included.is_empty() {
        None
    } else {
        Some(included)
    };
    (resources, opt_included)
}

pub fn vec_to_jsonapi_document<T: JsonApiModel>(objects: Vec<T>) -> JsonApiDocument {
    let (resources, included) = vec_to_jsonapi_resources(objects);
    JsonApiDocument {
        data: Some(PrimaryData::Multiple(resources)),
        included,
        ..Default::default()
    }
}

impl<M: JsonApiModel> JsonApiModel for Box<M> {
    fn jsonapi_type(&self) -> String {
        self.as_ref().jsonapi_type()
    }

    fn jsonapi_id(&self) -> String {
        self.as_ref().jsonapi_id()
    }

    fn relationship_fields() -> Option<&'static [&'static str]> {
        M::relationship_fields()
    }

    fn build_relationships(&self) -> Option<Relationships> {
        self.as_ref().build_relationships()
    }

    fn build_included(&self) -> Option<Resources> {
        self.as_ref().build_included()
    }
}

#[macro_export]
macro_rules! jsonapi_model {
    ($model:ty; $type:expr) => (
        impl JsonApiModel for $model {
            fn jsonapi_type(&self) -> String { $type.to_string() }
            fn jsonapi_id(&self) -> String { self.id.to_string() }
            fn relationship_fields() -> Option<&'static [&'static str]> { None }
            fn build_relationships(&self) -> Option<Relationships> { None }
            fn build_included(&self) -> Option<Resources> { None }
        }
    );
    ($model:ty; $type:expr;
        has one $( $has_one:ident ),*
    ) => (
        jsonapi_model!($model; $type; has one $( $has_one ),*; has many);
    );
    ($model:ty; $type:expr;
        has many $( $has_many:ident ),*
    ) => (
        jsonapi_model!($model; $type; has one; has many $( $has_many ),*);
    );
    ($model:ty; $type:expr;
        has one $( $has_one:ident ),*;
        has many $( $has_many:ident ),*
    ) => (
        impl JsonApiModel for $model {
            fn jsonapi_type(&self) -> String { $type.to_string() }
            fn jsonapi_id(&self) -> String { self.id.to_string() }

            fn relationship_fields() -> Option<&'static [&'static str]> {
                static FIELDS: &'static [&'static str] = &[
                     $( stringify!($has_one),)*
                     $( stringify!($has_many),)*
                ];

                Some(FIELDS)
            }

            fn build_relationships(&self) -> Option<Relationships> {
                let mut relationships = HashMap::new();
                $(
                    relationships.insert(stringify!($has_one).into(),
                        Self::build_has_one(&self.$has_one)
                    );
                )*
                $(
                    relationships.insert(stringify!($has_many).into(),
                        Self::build_has_many(&self.$has_many)
                    );
                )*
                Some(relationships)
            }

            fn build_included(&self) -> Option<Resources> {
                let mut included:Resources = vec![];
                $( included.append(&mut self.$has_one.to_resources()); )*
                $(
                    for model in &self.$has_many {
                        included.append(&mut model.to_resources());
                    }
                )*
                Some(included)
            }
        }
    );
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Dog {
    id: String,
    name: String,
    age: i32,
    main_flea: Flea,
    fleas: Vec<Flea>,
}
jsonapi_model!(Dog; "dog"; has one main_flea; has many fleas);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Flea {
    id: String,
    name: String,
}
jsonapi_model!(Flea; "flea");
<|endoftext|>


<commit_before>use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering, fence};

use pause::pause;

pub struct Slot {
    next: AtomicPtr<AtomicBool>
}

pub struct Guard<'a, T: ?Sized + 'a> {
    lock: &'a Mutex<T>,
    slot: &'a Slot
}

pub struct Mutex<T: ?Sized> {
    queue: AtomicPtr<Slot>,
    data: UnsafeCell<T>
}

unsafe impl<T: Send> Sync for Mutex<T> { }
unsafe impl<T: Send> Send for Mutex<T> { }

impl Slot {
    pub const fn new() -> Slot {
        Slot {
            next: AtomicPtr::new(ptr::null_mut())
        }
    }
}

impl<T> Mutex<T> {
    pub const fn new(value: T) -> Mutex<T> {
        Mutex {
            queue: AtomicPtr::new(ptr::null_mut()),
            data: UnsafeCell::new(value)
        }
    }

    pub fn into_inner(self) -> T {
        unsafe {
            self.data.into_inner()
        }
    }
}

impl<T: ?Sized> Mutex<T> {
    pub fn try_lock<'a>(&'a self, slot: &'a mut Slot) -> Option<Guard<'a, T>> {
        slot.next = AtomicPtr::new(ptr::null_mut());

        if self.queue.compare_and_swap(ptr::null_mut(), slot, Ordering::AcqRel).is_null() {
            Some(Guard {
                lock: self,
                slot: slot
            })
        } else {
            None
        }
    }

    pub fn lock<'a>(&'a self, slot: &'a mut Slot) -> Guard<'a, T> {
        slot.next = AtomicPtr::new(ptr::null_mut());
        let pred = self.queue.swap(slot, Ordering::AcqRel);
        if !pred.is_null() {
            let pred = unsafe { &*pred };
            let locked = AtomicBool::new(true);
            pred.next.store(&locked as *const _ as *mut _, Ordering::Release);
            while locked.load(Ordering::Relaxed) {
                pause();
            }
            fence(Ordering::Acquire);
        }

        Guard {
            lock: self,
            slot: slot
        }
    }

    pub fn get_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

impl<'a, T: ?Sized> Deref for Guard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> DerefMut for Guard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> Drop for Guard<'a, T> {
    #[unsafe_destructor_blind_to_params]
    fn drop(&mut self) {
        let succ = self.slot.next.load(Ordering::Relaxed);
        if succ.is_null() {
            let slot_ptr = self.slot as *const _ as *mut _;
            if self.lock.queue.compare_and_swap(slot_ptr, ptr::null_mut(), Ordering::Release) != slot_ptr {
                let mut succ;
                loop {
                    succ = self.slot.next.load(Ordering::Relaxed);
                    if !succ.is_null() {
                        break;
                    }
                    pause();
                }
                fence(Ordering::Acquire);
                let succ = unsafe { &*succ };
                succ.store(false, Ordering::Release);
            }
        } else {
            fence(Ordering::Acquire);
            let succ = unsafe { &*succ };
            succ.store(false, Ordering::Release);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate std;

    use super::{Mutex, Slot};

    // Mostly stoled from the Rust standard Mutex implementation's tests, so

    // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
    // file 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.

    use self::std::sync::Arc;
    use self::std::sync::mpsc::channel;
    use self::std::sync::atomic::{AtomicUsize, Ordering};
    use self::std::thread;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let mut slot = Slot::new();
        let m = Mutex::new(());
        drop(m.lock(&mut slot));
        drop(m.lock(&mut slot));
    }

    #[test]
    fn lots_and_lots() {
        static LOCK: Mutex<u32> = Mutex::new(0);
        const ITERS: u32 = 1000;
        const CONCURRENCY: u32 = 3;

        fn inc() {
            let mut slot = Slot::new();
            for _ in 0..ITERS {
                let mut g = LOCK.lock(&mut slot);
                *g += 1;
            }
        };

        let (tx, rx) = channel();
        for _ in 0..CONCURRENCY {
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
        }

        drop(tx);
        for _ in 0..2 * CONCURRENCY {
            rx.recv().unwrap();
        }
        let mut slot = Slot::new();
        assert_eq!(*LOCK.lock(&mut slot), ITERS * CONCURRENCY * 2);
    }

    #[test]
    fn try_lock() {
        let mut slot = Slot::new();
        let m = Mutex::new(());
        *m.try_lock(&mut slot).unwrap() = ();
    }

    #[test]
    fn test_into_inner() {
        let m = Mutex::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = Mutex::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_get_mut() {
        let mut m = Mutex::new(NonCopy(10));
        *m.get_mut() = NonCopy(20);
        assert_eq!(m.into_inner(), NonCopy(20));
    }

    #[test]
    fn test_lock_arc_nested() {
        // Tests nested locks and access
        // to underlying data.
        let arc = Arc::new(Mutex::new(1));
        let arc2 = Arc::new(Mutex::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move|| {
            let mut slot1 = Slot::new();
            let mut slot2 = Slot::new();

            let lock = arc2.lock(&mut slot1);
            let lock2 = lock.lock(&mut slot2);
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_lock_arc_access_in_unwind() {
        let arc = Arc::new(Mutex::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move|| -> () {
            struct Unwinder {
                i: Arc<Mutex<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    let mut slot = Slot::new();
                    *self.i.lock(&mut slot) += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        }).join();
        let mut slot = Slot::new();
        let lock = arc.lock(&mut slot);
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_lock_unsized() {
        let mut slot = Slot::new();
        let lock: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
        {
            let b = &mut *lock.lock(&mut slot);
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*lock.lock(&mut slot), comp);
    }
}
<commit_msg>Add some docs (stolen from std)<commit_after>use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering, fence};

use pause::pause;

pub struct Slot {
    next: AtomicPtr<AtomicBool>
}

/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
/// dropped (falls out of scope), the lock will be unlocked.
///
/// The data protected by the mutex can be access through this guard via its
/// `Deref` and `DerefMut` implementations
#[must_use]
pub struct Guard<'a, T: ?Sized + 'a> {
    lock: &'a Mutex<T>,
    slot: &'a Slot
}

/// A mutual exclusion primitive useful for protecting shared data
///
/// This mutex will block threads waiting for the lock to become available. The
/// mutex can also be statically initialized or created via a `new`
/// constructor. Each mutex has a type parameter which represents the data that
/// it is protecting. The data can only be accessed through the RAII guards
/// returned from `lock` and `try_lock`, which guarantees that the data is only
/// ever accessed when the mutex is locked.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
/// use std::thread;
/// use std::sync::mpsc::channel;
/// use mcs::{Mutex, Slot};
///
/// const N: usize = 10;
///
/// // Spawn a few threads to increment a shared variable (non-atomically), and
/// // let the main thread know once all increments are done.
/// //
/// // Here we're using an Arc to share memory among threads, and the data inside
/// // the Arc is protected with a mutex.
/// let data = Arc::new(Mutex::new(0));
///
/// let (tx, rx) = channel();
/// for _ in 0..10 {
///     let (data, tx) = (data.clone(), tx.clone());
///     thread::spawn(move || {
///         let mut slot = Slot::new();
///
///         // The shared state can only be accessed once the lock is held.
///         // Our non-atomic increment is safe because we're the only thread
///         // which can access the shared state when the lock is held.
///         //
///         // We unwrap() the return value to assert that we are not expecting
///         // threads to ever fail while holding the lock.
///         let mut data = data.lock(&mut slot);
///         *data += 1;
///         if *data == N {
///             tx.send(()).unwrap();
///         }
///         // the lock is unlocked here when `data` goes out of scope.
///     });
/// }
///
/// rx.recv().unwrap();
/// ```
pub struct Mutex<T: ?Sized> {
    queue: AtomicPtr<Slot>,
    data: UnsafeCell<T>
}

unsafe impl<T: Send> Sync for Mutex<T> { }
unsafe impl<T: Send> Send for Mutex<T> { }

impl Slot {
    pub const fn new() -> Slot {
        Slot {
            next: AtomicPtr::new(ptr::null_mut())
        }
    }
}

impl<T> Mutex<T> {
    /// Creates a new mutex in an unlocked state ready for use.
    pub const fn new(value: T) -> Mutex<T> {
        Mutex {
            queue: AtomicPtr::new(ptr::null_mut()),
            data: UnsafeCell::new(value)
        }
    }

    /// Consumes this mutex, returning the underlying data.
    pub fn into_inner(self) -> T {
        unsafe {
            self.data.into_inner()
        }
    }
}

impl<T: ?Sized> Mutex<T> {
    /// Attempts to acquire this lock.
    ///
    /// If the lock could not be acquired at this time, then `Err` is returned.
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
    /// guard is dropped.
    ///
    /// This function does not block.
    pub fn try_lock<'a>(&'a self, slot: &'a mut Slot) -> Result<Guard<'a, T>, ()> {
        slot.next = AtomicPtr::new(ptr::null_mut());

        if self.queue.compare_and_swap(ptr::null_mut(), slot, Ordering::AcqRel).is_null() {
            Ok(Guard {
                lock: self,
                slot: slot
            })
        } else {
            Err(())
        }
    }

    /// Acquires a mutex, blocking the current thread until it is able to do so.
    ///
    /// This function will block the local thread until it is available to acquire
    /// the mutex. Upon returning, the thread is the only thread with the mutex
    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
    /// the guard goes out of scope, the mutex will be unlocked.
    pub fn lock<'a>(&'a self, slot: &'a mut Slot) -> Guard<'a, T> {
        slot.next = AtomicPtr::new(ptr::null_mut());
        let pred = self.queue.swap(slot, Ordering::AcqRel);
        if !pred.is_null() {
            let pred = unsafe { &*pred };
            let locked = AtomicBool::new(true);
            pred.next.store(&locked as *const _ as *mut _, Ordering::Release);
            while locked.load(Ordering::Relaxed) {
                pause();
            }
            fence(Ordering::Acquire);
        }

        Guard {
            lock: self,
            slot: slot
        }
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
    /// take place---the mutable borrow statically guarantees no locks exist.
    pub fn get_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

impl<'a, T: ?Sized> Deref for Guard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> DerefMut for Guard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> Drop for Guard<'a, T> {
    #[unsafe_destructor_blind_to_params]
    fn drop(&mut self) {
        let succ = self.slot.next.load(Ordering::Relaxed);
        if succ.is_null() {
            let slot_ptr = self.slot as *const _ as *mut _;
            if self.lock.queue.compare_and_swap(slot_ptr, ptr::null_mut(), Ordering::Release) != slot_ptr {
                let mut succ;
                loop {
                    succ = self.slot.next.load(Ordering::Relaxed);
                    if !succ.is_null() {
                        break;
                    }
                    pause();
                }
                fence(Ordering::Acquire);
                let succ = unsafe { &*succ };
                succ.store(false, Ordering::Release);
            }
        } else {
            fence(Ordering::Acquire);
            let succ = unsafe { &*succ };
            succ.store(false, Ordering::Release);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate std;

    use super::{Mutex, Slot};

    // Mostly stoled from the Rust standard Mutex implementation's tests, so

    // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
    // file 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.

    use self::std::sync::Arc;
    use self::std::sync::mpsc::channel;
    use self::std::sync::atomic::{AtomicUsize, Ordering};
    use self::std::thread;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let mut slot = Slot::new();
        let m = Mutex::new(());
        drop(m.lock(&mut slot));
        drop(m.lock(&mut slot));
    }

    #[test]
    fn lots_and_lots() {
        static LOCK: Mutex<u32> = Mutex::new(0);
        const ITERS: u32 = 1000;
        const CONCURRENCY: u32 = 3;

        fn inc() {
            let mut slot = Slot::new();
            for _ in 0..ITERS {
                let mut g = LOCK.lock(&mut slot);
                *g += 1;
            }
        };

        let (tx, rx) = channel();
        for _ in 0..CONCURRENCY {
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
        }

        drop(tx);
        for _ in 0..2 * CONCURRENCY {
            rx.recv().unwrap();
        }
        let mut slot = Slot::new();
        assert_eq!(*LOCK.lock(&mut slot), ITERS * CONCURRENCY * 2);
    }

    #[test]
    fn try_lock() {
        let mut slot = Slot::new();
        let m = Mutex::new(());
        *m.try_lock(&mut slot).unwrap() = ();
    }

    #[test]
    fn test_into_inner() {
        let m = Mutex::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = Mutex::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_get_mut() {
        let mut m = Mutex::new(NonCopy(10));
        *m.get_mut() = NonCopy(20);
        assert_eq!(m.into_inner(), NonCopy(20));
    }

    #[test]
    fn test_lock_arc_nested() {
        // Tests nested locks and access
        // to underlying data.
        let arc = Arc::new(Mutex::new(1));
        let arc2 = Arc::new(Mutex::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move|| {
            let mut slot1 = Slot::new();
            let mut slot2 = Slot::new();

            let lock = arc2.lock(&mut slot1);
            let lock2 = lock.lock(&mut slot2);
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_lock_arc_access_in_unwind() {
        let arc = Arc::new(Mutex::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move|| -> () {
            struct Unwinder {
                i: Arc<Mutex<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    let mut slot = Slot::new();
                    *self.i.lock(&mut slot) += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        }).join();
        let mut slot = Slot::new();
        let lock = arc.lock(&mut slot);
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_lock_unsized() {
        let mut slot = Slot::new();
        let lock: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
        {
            let b = &mut *lock.lock(&mut slot);
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*lock.lock(&mut slot), comp);
    }
}
<|endoftext|>