<commit_before>//! Graph visitor algorithms.
//!

use std::collections::{
    HashSet,
    VecDeque,
};
use std::hash::Hash;
use fb::FixedBitSet;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

/// Base trait for graphs that defines the node identifier.
pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike {
    type Iter: Iterator<Item=Self::NodeId>;

    /// Return an iterator that visits all neighbors of the node **n**.
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Ord + Hash + Eq
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for GraphMap that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<Self::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = FixedBitSet;
    fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// The **GraphMap** keeps an adjacency matrix internally.
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type AdjMatrix = ();
    #[inline]
    fn adjacency_matrix(&self) { }
    #[inline]
    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
        self.contains_edge(a, b)
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub discovered: VM,
}

impl<G: Visitable> Dfs<G::NodeId, G::Map>
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty(graph: &G) -> Self
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Dfs::new to
        // work around rust bug #22841
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        DfsIter {
            graph: graph,
            dfs: dfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    pub stack: VecDeque<N>,
    pub discovered: VM,
}

impl<G: Visitable> Bfs<G::NodeId, G::Map>
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }
}

impl<N, VM> Bfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Bfs::new to
        // work around rust bug #22841
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        let bfs = Bfs {
            stack: stack,
            discovered: discovered,
        };
        BfsIter {
            graph: graph,
            bfs: bfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }
}
<commit_msg>Put move_to and next in the same impl<commit_after>//! Graph visitor algorithms.
//!

use std::collections::{
    HashSet,
    VecDeque,
};
use std::hash::Hash;
use fb::FixedBitSet;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

/// Base trait for graphs that defines the node identifier.
pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike {
    type Iter: Iterator<Item=Self::NodeId>;

    /// Return an iterator that visits all neighbors of the node **n**.
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Ord + Hash + Eq
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for GraphMap that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<Self::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = FixedBitSet;
    fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// The **GraphMap** keeps an adjacency matrix internally.
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type AdjMatrix = ();
    #[inline]
    fn adjacency_matrix(&self) { }
    #[inline]
    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
        self.contains_edge(a, b)
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub discovered: VM,
}

impl<G: Visitable> Dfs<G::NodeId, G::Map>
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty(graph: &G) -> Self
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Dfs::new to
        // work around rust bug #22841
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        DfsIter {
            graph: graph,
            dfs: dfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    pub stack: VecDeque<N>,
    pub discovered: VM,
}

impl<G: Visitable> Bfs<G::NodeId, G::Map>
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }
}

impl<N, VM> Bfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Bfs::new to
        // work around rust bug #22841
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        let bfs = Bfs {
            stack: stack,
            discovered: discovered,
        };
        BfsIter {
            graph: graph,
            bfs: bfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }
}
<|endoftext|>


<commit_before>
//! Management of entities, components, systems, and managers

use std::cell::{RefMut, RefCell};
use std::collections::HashMap;
use std::intrinsics::TypeId;
use std::mem;

use {Component, ComponentId};
use {Entity, EntityBuilder, EntityModifier};
use {Manager, MutableManager};
use {Passive, System};
use component::ComponentList;
use entity::EntityManager;

pub struct World
{
    build_queue: RefCell<Vec<(Entity, Box<EntityBuilder+'static>)>>,
    modify_queue: RefCell<Vec<(Entity, Box<EntityModifier+'static>)>>,
    entities: RefCell<EntityManager>,
    components: RefCell<ComponentManager>,
    systems: RefCell<SystemManager>,
    mut_managers: Vec<RefCell<Box<MutableManager>>>,
    managers: Vec<Box<Manager>>,
}

#[experimental]
pub struct WorldBuilder
{
    world: World,
}

#[experimental]
pub struct Components<'a>
{
    inner: RefMut<'a, ComponentManager>,
}

#[experimental]
pub struct EntityData<'a>
{
    inner: RefMut<'a, ComponentManager>,
}

struct ComponentManager
{
    components: HashMap<ComponentId, ComponentList>,
}

struct SystemManager
{
    systems: Vec<Box<System>>,
    passive: HashMap<&'static str, Box<Passive>>,
}

impl World
{
    /// Returns if an entity is valid (registered with the entity manager).
    #[inline]
    pub fn is_valid(&self, entity: &Entity) -> bool
    {
        self.entities.borrow().is_valid(entity)
    }

    /// Updates the world by processing all systems.
    pub fn update(&mut self)
    {
        self.systems.borrow_mut().preprocess(self);
        self.systems.borrow().process(self.entity_data());
        self.systems.borrow_mut().postprocess(self);
        let mut queue = Vec::new();
        mem::swap(&mut queue, &mut *self.build_queue.borrow_mut());
        for (entity, mut builder) in queue.into_iter()
        {
            if self.is_valid(&entity)
            {
                builder.build(&mut self.components(), entity);
                self.activate_entity(&entity);
            }
            else
            {
                println!("[ecs] WARNING: Couldn't build invalid entity");
            }
        }
        let mut queue = Vec::new();
        mem::swap(&mut queue, &mut *self.modify_queue.borrow_mut());
        for (entity, mut modifier) in queue.into_iter()
        {
            if self.is_valid(&entity)
            {
                modifier.modify(&mut self.components(), entity);
                self.reactivate_entity(&entity);
            }
            else
            {
                println!("[ecs] WARNING: Couldn't modify invalid entity");
            }
        }
    }

    /// Updates the passive system corresponding to `key`
    pub fn update_passive(&mut self, key: &'static str)
    {
        self.systems.borrow_mut().update_passive(key, self);
    }

    /// Create an entity with the given builder.
    pub fn build_entity<T: EntityBuilder>(&mut self, mut builder: T) -> Entity
    {
        let entity = self.entities.borrow_mut().create_entity();
        builder.build(&mut self.components(), entity);
        self.activate_entity(&entity);
        entity
    }

    /// Modifies an entity with the given modifier.
    pub fn modify_entity<T: EntityModifier>(&mut self, entity: Entity, mut modifier: T)
    {
        modifier.modify(&mut self.components(), entity);
        self.reactivate_entity(&entity);
    }

    /// Queues a entity to be built at the end of the next update cycle.
    pub fn queue_builder<T: EntityBuilder>(&self, builder: T) -> Entity
    {
        let entity = self.entities.borrow_mut().create_entity();
        self.build_queue.borrow_mut().push((entity, box builder));
        entity
    }

    /// Queues a entity to be modified at the end of the next update cycle.
    pub fn queue_modifier<T: EntityModifier>(&self, entity: Entity, modifier: T)
    {
        self.modify_queue.borrow_mut().push((entity, box modifier));
    }

    /// Deletes an entity, deactivating it if it is activated
    ///
    /// If the entity is invalid a warning is issued and this method does nothing.
    pub fn delete_entity(&mut self, entity: &Entity)
    {
        if self.is_valid(entity)
        {
            self.systems.borrow_mut().deactivated(entity, self);
            for ref manager in self.mut_managers.iter()
            {
                manager.borrow_mut().deactivated(entity, self);
            }
            for ref manager in self.managers.iter()
            {
                manager.deactivated(entity, self);
            }
            self.entities.borrow_mut().delete_entity(entity);
            self.components.borrow_mut().delete_entity(entity);
        }
        else
        {
            println!("[ecs] WARNING: Cannot delete invalid entity")
        }
    }

    /// Returns the value of a component for an entity (or None)
    pub fn get_component<T: Component>(&self, entity: &Entity) -> Option<T>
    {
        if self.is_valid(entity)
        {
            self.components.borrow().get::<T>(entity)
        }
        else
        {
            None
        }
    }

    /// Returns if an entity contains a component.
    pub fn has_component(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components.borrow().has(entity, id)
    }

    fn activate_entity(&mut self, entity: &Entity)
    {
        self.systems.borrow_mut().activated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().activated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.activated(entity, self);
        }
    }

    fn reactivate_entity(&mut self, entity: &Entity)
    {
        self.systems.borrow_mut().reactivated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().reactivated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.reactivated(entity, self);
        }
    }

    fn entity_data(&self) -> EntityData
    {
        EntityData
        {
            inner: self.components.borrow_mut()
        }
    }

    fn components(&self) -> Components
    {
        Components
        {
            inner: self.components.borrow_mut()
        }
    }
}

impl SystemManager
{
    pub fn new() -> SystemManager
    {
        SystemManager
        {
            systems: Vec::new(),
            passive: HashMap::new(),
        }
    }

    pub fn register(&mut self, sys: Box<System>)
    {
        self.systems.push(sys);
    }

    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.passive.insert(key, sys);
    }

    pub fn preprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.preprocess(world);
        }
    }

    pub fn process(&self, mut components: EntityData)
    {
        for sys in self.systems.iter()
        {
            sys.process(&mut components);
        }
    }

    pub fn postprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.postprocess(world);
        }
    }

    pub fn update_passive(&mut self, key: &'static str, world: &World)
    {
        if self.passive.contains_key(&key)
        {
            self.passive.get_mut(&key).process(world);
        }
        else
        {
            println!("[ecs] WARNING: No passive system registered for key '{}'", key);
        }
    }
}

impl MutableManager for SystemManager
{
    fn activated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.activated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.activated(e, w);
        }
    }

    fn reactivated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.reactivated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.reactivated(e, w);
        }
    }

    fn deactivated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.deactivated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.deactivated(e, w);
        }
    }
}

impl ComponentManager
{
    pub fn new() -> ComponentManager
    {
        ComponentManager
        {
            components: HashMap::new(),
        }
    }

    pub fn register(&mut self, list: ComponentList)
    {
        self.components.insert(list.get_cid(), list);
    }

    fn delete_entity(&mut self, entity: &Entity)
    {
        for (_, list) in self.components.iter_mut()
        {
            list.rm(entity);
        }
    }

    fn add<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).add::<T>(entity, &component)
    }

    fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).set::<T>(entity, &component)
    }

    fn get<T:Component>(&self, entity: &Entity) -> Option<T>
    {
        self.components[TypeId::of::<T>().hash()].get::<T>(entity)
    }

    pub fn has(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components[id].has(entity)
    }

    fn borrow_mut<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).borrow_mut::<T>(entity)
    }

    fn remove<T:Component>(&mut self, entity: &Entity) -> bool
    {
        self.components.get_mut(&TypeId::of::<T>().hash()).rm(entity)
    }
}

#[experimental]
impl<'a> Components<'a>
{
    pub fn add<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.add::<T>(entity, component)
    }

    pub fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.set::<T>(entity, component)
    }

    pub fn get<T:Component>(&mut self, entity: &Entity) -> Option<T>
    {
        self.inner.get::<T>(entity)
    }

    pub fn has(&mut self, entity: &Entity, id: ComponentId) -> bool
    {
        self.inner.has(entity, id)
    }

    pub fn remove<T:Component>(&mut self, entity: &Entity) -> bool
    {
        self.inner.remove::<T>(entity)
    }
}

#[experimental]
impl<'a> EntityData<'a>
{
    pub fn borrow<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.inner.borrow_mut::<T>(entity)
    }

    pub fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.set::<T>(entity, component)
    }

    pub fn get<T:Component>(&mut self, entity: &Entity) -> Option<T>
    {
        self.inner.get::<T>(entity)
    }

    pub fn has(&mut self, entity: &Entity, id: ComponentId) -> bool
    {
        self.inner.has(entity, id)
    }
}

impl WorldBuilder
{
    /// Create a new world builder.
    pub fn new() -> WorldBuilder
    {
        WorldBuilder {
            world: World {
                build_queue: RefCell::new(Vec::new()),
                modify_queue: RefCell::new(Vec::new()),
                entities: RefCell::new(EntityManager::new()),
                components: RefCell::new(ComponentManager::new()),
                systems: RefCell::new(SystemManager::new()),
                mut_managers: Vec::new(),
                managers: Vec::new(),
            }
        }
    }

    /// Completes the world setup and return the World object for use.
    pub fn build(self) -> World
    {
        self.world
    }

    /// Registers a mutable manager.
    #[experimental]
    pub fn register_manager_mut(&mut self, manager: Box<MutableManager>)
    {
        self.world.mut_managers.push(RefCell::new(manager));
    }

    /// Registers an immutable manager.
    #[experimental]
    pub fn register_manager(&mut self, manager: Box<Manager>)
    {
        self.world.managers.push(manager);
    }

    /// Registers a component.
    pub fn register_component<T: Component>(&mut self)
    {
        self.world.components.borrow_mut().register(ComponentList::new::<T>());
    }

    /// Registers a system.
    pub fn register_system(&mut self, sys: Box<System>)
    {
        self.world.systems.borrow_mut().register(sys);
    }

    /// Registers a passive system.
    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.world.systems.borrow_mut().register_passive(key, sys);
    }
}
<commit_msg>Replace `get_mut` and `get` on HashMap with indexing<commit_after>
//! Management of entities, components, systems, and managers

use std::cell::{RefMut, RefCell};
use std::collections::HashMap;
use std::intrinsics::TypeId;
use std::mem;

use {Component, ComponentId};
use {Entity, EntityBuilder, EntityModifier};
use {Manager, MutableManager};
use {Passive, System};
use component::ComponentList;
use entity::EntityManager;

pub struct World
{
    build_queue: RefCell<Vec<(Entity, Box<EntityBuilder+'static>)>>,
    modify_queue: RefCell<Vec<(Entity, Box<EntityModifier+'static>)>>,
    entities: RefCell<EntityManager>,
    components: RefCell<ComponentManager>,
    systems: RefCell<SystemManager>,
    mut_managers: Vec<RefCell<Box<MutableManager>>>,
    managers: Vec<Box<Manager>>,
}

#[experimental]
pub struct WorldBuilder
{
    world: World,
}

#[experimental]
pub struct Components<'a>
{
    inner: RefMut<'a, ComponentManager>,
}

#[experimental]
pub struct EntityData<'a>
{
    inner: RefMut<'a, ComponentManager>,
}

struct ComponentManager
{
    components: HashMap<ComponentId, ComponentList>,
}

struct SystemManager
{
    systems: Vec<Box<System>>,
    passive: HashMap<&'static str, Box<Passive>>,
}

impl World
{
    /// Returns if an entity is valid (registered with the entity manager).
    #[inline]
    pub fn is_valid(&self, entity: &Entity) -> bool
    {
        self.entities.borrow().is_valid(entity)
    }

    /// Updates the world by processing all systems.
    pub fn update(&mut self)
    {
        self.systems.borrow_mut().preprocess(self);
        self.systems.borrow().process(self.entity_data());
        self.systems.borrow_mut().postprocess(self);
        let mut queue = Vec::new();
        mem::swap(&mut queue, &mut *self.build_queue.borrow_mut());
        for (entity, mut builder) in queue.into_iter()
        {
            if self.is_valid(&entity)
            {
                builder.build(&mut self.components(), entity);
                self.activate_entity(&entity);
            }
            else
            {
                println!("[ecs] WARNING: Couldn't build invalid entity");
            }
        }
        let mut queue = Vec::new();
        mem::swap(&mut queue, &mut *self.modify_queue.borrow_mut());
        for (entity, mut modifier) in queue.into_iter()
        {
            if self.is_valid(&entity)
            {
                modifier.modify(&mut self.components(), entity);
                self.reactivate_entity(&entity);
            }
            else
            {
                println!("[ecs] WARNING: Couldn't modify invalid entity");
            }
        }
    }

    /// Updates the passive system corresponding to `key`
    pub fn update_passive(&mut self, key: &'static str)
    {
        self.systems.borrow_mut().update_passive(key, self);
    }

    /// Create an entity with the given builder.
    pub fn build_entity<T: EntityBuilder>(&mut self, mut builder: T) -> Entity
    {
        let entity = self.entities.borrow_mut().create_entity();
        builder.build(&mut self.components(), entity);
        self.activate_entity(&entity);
        entity
    }

    /// Modifies an entity with the given modifier.
    pub fn modify_entity<T: EntityModifier>(&mut self, entity: Entity, mut modifier: T)
    {
        modifier.modify(&mut self.components(), entity);
        self.reactivate_entity(&entity);
    }

    /// Queues a entity to be built at the end of the next update cycle.
    pub fn queue_builder<T: EntityBuilder>(&self, builder: T) -> Entity
    {
        let entity = self.entities.borrow_mut().create_entity();
        self.build_queue.borrow_mut().push((entity, box builder));
        entity
    }

    /// Queues a entity to be modified at the end of the next update cycle.
    pub fn queue_modifier<T: EntityModifier>(&self, entity: Entity, modifier: T)
    {
        self.modify_queue.borrow_mut().push((entity, box modifier));
    }

    /// Deletes an entity, deactivating it if it is activated
    ///
    /// If the entity is invalid a warning is issued and this method does nothing.
    pub fn delete_entity(&mut self, entity: &Entity)
    {
        if self.is_valid(entity)
        {
            self.systems.borrow_mut().deactivated(entity, self);
            for ref manager in self.mut_managers.iter()
            {
                manager.borrow_mut().deactivated(entity, self);
            }
            for ref manager in self.managers.iter()
            {
                manager.deactivated(entity, self);
            }
            self.entities.borrow_mut().delete_entity(entity);
            self.components.borrow_mut().delete_entity(entity);
        }
        else
        {
            println!("[ecs] WARNING: Cannot delete invalid entity")
        }
    }

    /// Returns the value of a component for an entity (or None)
    pub fn get_component<T: Component>(&self, entity: &Entity) -> Option<T>
    {
        if self.is_valid(entity)
        {
            self.components.borrow().get::<T>(entity)
        }
        else
        {
            None
        }
    }

    /// Returns if an entity contains a component.
    pub fn has_component(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components.borrow().has(entity, id)
    }

    fn activate_entity(&mut self, entity: &Entity)
    {
        self.systems.borrow_mut().activated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().activated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.activated(entity, self);
        }
    }

    fn reactivate_entity(&mut self, entity: &Entity)
    {
        self.systems.borrow_mut().reactivated(entity, self);
        for ref manager in self.mut_managers.iter()
        {
            manager.borrow_mut().reactivated(entity, self);
        }
        for ref manager in self.managers.iter()
        {
            manager.reactivated(entity, self);
        }
    }

    fn entity_data(&self) -> EntityData
    {
        EntityData
        {
            inner: self.components.borrow_mut()
        }
    }

    fn components(&self) -> Components
    {
        Components
        {
            inner: self.components.borrow_mut()
        }
    }
}

impl SystemManager
{
    pub fn new() -> SystemManager
    {
        SystemManager
        {
            systems: Vec::new(),
            passive: HashMap::new(),
        }
    }

    pub fn register(&mut self, sys: Box<System>)
    {
        self.systems.push(sys);
    }

    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.passive.insert(key, sys);
    }

    pub fn preprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.preprocess(world);
        }
    }

    pub fn process(&self, mut components: EntityData)
    {
        for sys in self.systems.iter()
        {
            sys.process(&mut components);
        }
    }

    pub fn postprocess(&mut self, world: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.postprocess(world);
        }
    }

    pub fn update_passive(&mut self, key: &'static str, world: &World)
    {
        if self.passive.contains_key(&key)
        {
            self.passive[key].process(world);
        }
        else
        {
            println!("[ecs] WARNING: No passive system registered for key '{}'", key);
        }
    }
}

impl MutableManager for SystemManager
{
    fn activated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.activated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.activated(e, w);
        }
    }

    fn reactivated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.reactivated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.reactivated(e, w);
        }
    }

    fn deactivated(&mut self, e: &Entity, w: &World)
    {
        for sys in self.systems.iter_mut()
        {
            sys.deactivated(e, w);
        }
        for (_, sys) in self.passive.iter_mut()
        {
            sys.deactivated(e, w);
        }
    }
}

impl ComponentManager
{
    pub fn new() -> ComponentManager
    {
        ComponentManager
        {
            components: HashMap::new(),
        }
    }

    pub fn register(&mut self, list: ComponentList)
    {
        self.components.insert(list.get_cid(), list);
    }

    fn delete_entity(&mut self, entity: &Entity)
    {
        for (_, list) in self.components.iter_mut()
        {
            list.rm(entity);
        }
    }

    fn add<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components[TypeId::of::<T>().hash()].add::<T>(entity, &component)
    }

    fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.components[TypeId::of::<T>().hash()].set::<T>(entity, &component)
    }

    fn get<T:Component>(&self, entity: &Entity) -> Option<T>
    {
        self.components[TypeId::of::<T>().hash()].get::<T>(entity)
    }

    pub fn has(&self, entity: &Entity, id: ComponentId) -> bool
    {
        self.components[id].has(entity)
    }

    fn borrow_mut<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.components[TypeId::of::<T>().hash()].borrow_mut::<T>(entity)
    }

    fn remove<T:Component>(&mut self, entity: &Entity) -> bool
    {
        self.components[TypeId::of::<T>().hash()].rm(entity)
    }
}

#[experimental]
impl<'a> Components<'a>
{
    pub fn add<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.add::<T>(entity, component)
    }

    pub fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.set::<T>(entity, component)
    }

    pub fn get<T:Component>(&mut self, entity: &Entity) -> Option<T>
    {
        self.inner.get::<T>(entity)
    }

    pub fn has(&mut self, entity: &Entity, id: ComponentId) -> bool
    {
        self.inner.has(entity, id)
    }

    pub fn remove<T:Component>(&mut self, entity: &Entity) -> bool
    {
        self.inner.remove::<T>(entity)
    }
}

#[experimental]
impl<'a> EntityData<'a>
{
    pub fn borrow<T:Component>(&mut self, entity: &Entity) -> Option<&mut T>
    {
        self.inner.borrow_mut::<T>(entity)
    }

    pub fn set<T:Component>(&mut self, entity: &Entity, component: T) -> bool
    {
        self.inner.set::<T>(entity, component)
    }

    pub fn get<T:Component>(&mut self, entity: &Entity) -> Option<T>
    {
        self.inner.get::<T>(entity)
    }

    pub fn has(&mut self, entity: &Entity, id: ComponentId) -> bool
    {
        self.inner.has(entity, id)
    }
}

impl WorldBuilder
{
    /// Create a new world builder.
    pub fn new() -> WorldBuilder
    {
        WorldBuilder {
            world: World {
                build_queue: RefCell::new(Vec::new()),
                modify_queue: RefCell::new(Vec::new()),
                entities: RefCell::new(EntityManager::new()),
                components: RefCell::new(ComponentManager::new()),
                systems: RefCell::new(SystemManager::new()),
                mut_managers: Vec::new(),
                managers: Vec::new(),
            }
        }
    }

    /// Completes the world setup and return the World object for use.
    pub fn build(self) -> World
    {
        self.world
    }

    /// Registers a mutable manager.
    #[experimental]
    pub fn register_manager_mut(&mut self, manager: Box<MutableManager>)
    {
        self.world.mut_managers.push(RefCell::new(manager));
    }

    /// Registers an immutable manager.
    #[experimental]
    pub fn register_manager(&mut self, manager: Box<Manager>)
    {
        self.world.managers.push(manager);
    }

    /// Registers a component.
    pub fn register_component<T: Component>(&mut self)
    {
        self.world.components.borrow_mut().register(ComponentList::new::<T>());
    }

    /// Registers a system.
    pub fn register_system(&mut self, sys: Box<System>)
    {
        self.world.systems.borrow_mut().register(sys);
    }

    /// Registers a passive system.
    pub fn register_passive(&mut self, key: &'static str, sys: Box<Passive>)
    {
        self.world.systems.borrow_mut().register_passive(key, sys);
    }
}
<|endoftext|>


<commit_before>use std::any::TypeId;
use std::collections::HashMap;
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::sync::atomic::{AtomicUsize, Ordering};
use mopa::Any;
use bitset::{AtomicBitSet, BitSet, BitSetLike, BitSetOr};
use join::Join;
use storage::{Storage, MaskedStorage, UnprotectedStorage};
use {Index, Generation, Entity};

/// Abstract component type. Doesn't have to be Copy or even Clone.
pub trait Component: Any + Sized {
    /// Associated storage type for this component.
    type Storage: UnprotectedStorage<Self> + Any + Send + Sync;
}

/// A custom entity guard used to hide the the fact that Generations
/// is lazily created and updated. For this to be useful it _must_
/// be joined with a component. This is because the Generation table
/// includes every possible Generation of Entities even if they
/// have never been
pub struct Entities<'a> {
    guard: RwLockReadGuard<'a, Allocator>,
}

impl<'a> Join for &'a Entities<'a> {
    type Type = Entity;
    type Value = Self;
    type Mask = BitSetOr<&'a BitSet, &'a AtomicBitSet>;
    fn open(self) -> (Self::Mask, Self) {
        (BitSetOr(&self.guard.alive, &self.guard.raised), self)
    }
    unsafe fn get(v: &mut Self, idx: Index) -> Entity {
        let gen = v.guard.generations.get(idx as usize)
            .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
            .unwrap_or(Generation(1));
        Entity(idx, gen)
    }
}

/// Helper builder for entities.
pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    /// Adds a `Component` value to the new `Entity`.
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.write::<T>().insert(self.0, value);
        self
    }
    /// Finishes entity construction.
    pub fn build(self) -> Entity {
        self.0
    }
}

/// Internally used structure for `Entity` allocation.
pub struct Allocator {
    #[doc(hidden)]
    pub generations: Vec<Generation>,
    alive: BitSet,
    raised: AtomicBitSet,
    killed: AtomicBitSet,
    start_from: AtomicUsize
}

impl Allocator {
    #[doc(hidden)]
    pub fn new() -> Allocator {
        Allocator {
            generations: vec![],
            alive: BitSet::new(),
            raised: AtomicBitSet::new(),
            killed: AtomicBitSet::new(),
            start_from: AtomicUsize::new(0)
        }
    }

    fn kill(&self, e: Entity) {
        self.killed.add_atomic(e.get_id());
    }

    /// Return `true` if the entity is alive.
    pub fn is_alive(&self, e: Entity) -> bool {
        e.get_gen() ==  match self.generations.get(e.get_id() as usize) {
            Some(g) if !g.is_alive() && self.raised.contains(e.get_id()) => g.raised(),
            Some(g) => *g,
            None => Generation(1),
        }
    }

    /// Attempt to move the `start_from` value
    fn update_start_from(&self, start_from: usize) {
        loop {
            let current = self.start_from.load(Ordering::Relaxed);

            // if the current value is bigger then ours, we bail
            if current >= start_from {
                return;
            }

            if start_from == self.start_from.compare_and_swap(current, start_from, Ordering::Relaxed) {
                return;
            }
        }
    }

    /// Allocate a new entity
    fn allocate_atomic(&self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.alive.contains(i as Index) && !self.raised.add_atomic(i as Index) {
                self.update_start_from(i+1);

                let gen = self.generations.get(idx as usize)
                    .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
                    .unwrap_or(Generation(1));

                return Entity(i as Index, gen);
            }
        }
        panic!("No entities left to allocate")
    }

    /// Allocate a new entity
    fn allocate(&mut self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.raised.contains(i as Index) && !self.alive.add(i as Index) {
                // this is safe since we have mutable access to everything!
                self.start_from.store(i+1, Ordering::Relaxed);

                while self.generations.len() <= i as usize {
                    self.generations.push(Generation(0));
                }
                self.generations[i as usize] = self.generations[i as usize].raised();

                return Entity(i as Index, self.generations[i as usize]);
            }
        }
        panic!("No entities left to allocate")
    }

    fn merge(&mut self) -> Vec<Entity> {
        let mut deleted = vec![];

        for i in (&self.raised).iter() {
            while self.generations.len() <= i as usize {
                self.generations.push(Generation(0));
            }
            self.generations[i as usize] = self.generations[i as usize].raised();
            self.alive.add(i);
        }
        self.raised.clear();

        if let Some(lowest) = (&self.killed).iter().next() {
            if lowest < self.start_from.load(Ordering::Relaxed) as Index {
                self.start_from.store(lowest as usize, Ordering::Relaxed);
            }
        }

        for i in (&self.killed).iter() {
            self.alive.remove(i);
            self.generations[i as usize].die();
            deleted.push(Entity(i, self.generations[i as usize]))
        }
        self.killed.clear();

        deleted
    }
}

/// Entity creation iterator. Will yield new empty entities infinitely.
/// Useful for bulk entity construction, since the locks are only happening once.
pub struct CreateEntities<'a> {
    allocate: RwLockWriteGuard<'a, Allocator>,
}

impl<'a> Iterator for CreateEntities<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        Some(self.allocate.allocate())
    }
}

trait StorageLock: Any + Send + Sync {
    fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<T: Component> StorageLock for RwLock<MaskedStorage<T>> {
    fn del_slice(&self, entities: &[Entity]) {
        let mut guard = self.write().unwrap();
        for &e in entities.iter() {
            guard.remove(e.get_id());
        }
    }
}

trait ResourceLock: Any + Send + Sync {}

mopafy!(ResourceLock);

impl<T:Any+Send+Sync> ResourceLock for RwLock<T> {}

/// The `World` struct contains all the data, which is entities and their components.
/// All methods are supposed to be valid for any context they are available in.
pub struct World {
    allocator: RwLock<Allocator>,
    components: HashMap<TypeId, Box<StorageLock>>,
    resources: HashMap<TypeId, Box<ResourceLock>>,
}

impl World {
    /// Creates a new empty `World`.
    pub fn new() -> World {
        World {
            components: HashMap::new(),
            allocator: RwLock::new(Allocator::new()),
            resources: HashMap::new()
        }
    }
    /// Registers a new component type.
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(MaskedStorage::<T>::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    /// Unregisters a component type.
    pub fn unregister<T: Component>(&mut self) -> Option<MaskedStorage<T>> {
        self.components.remove(&TypeId::of::<T>()).map(|boxed|
            match boxed.downcast::<RwLock<MaskedStorage<T>>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock<T: Component>(&self) -> &RwLock<MaskedStorage<T>> {
        let boxed = self.components.get(&TypeId::of::<T>())
            .expect("Tried to perform an operation on type that was not registered");
        boxed.downcast_ref().unwrap()
    }
    /// Locks a component's storage for reading.
    pub fn read<T: Component>(&self) -> Storage<T, RwLockReadGuard<Allocator>, RwLockReadGuard<MaskedStorage<T>>> {
        let data = self.lock::<T>().read().unwrap();
        Storage::new(self.allocator.read().unwrap(), data)
    }
    /// Locks a component's storage for writing.
    pub fn write<T: Component>(&self) -> Storage<T, RwLockReadGuard<Allocator>, RwLockWriteGuard<MaskedStorage<T>>> {
        let data = self.lock::<T>().write().unwrap();
        Storage::new(self.allocator.read().unwrap(), data)
    }
    /// Returns the entity iterator.
    pub fn entities(&self) -> Entities {
        Entities {
            guard: self.allocator.read().unwrap(),
        }
    }
    /// Returns the entity creation iterator. Can be used to create many
    /// empty entities at once without paying the locking overhead.
    pub fn create_iter(&mut self) -> CreateEntities {
        CreateEntities {
            allocate: self.allocator.write().unwrap(),
        }
    }
    /// Creates a new entity instantly, locking the generations data.
    pub fn create_now(&mut self) -> EntityBuilder {
        let id = self.allocator.write().unwrap().allocate();
        EntityBuilder(id, self)
    }
    /// Deletes a new entity instantly, locking the generations data.
    pub fn delete_now(&mut self, entity: Entity) {
        for comp in self.components.values() {
            comp.del_slice(&[entity]);
        }
        let mut gens = self.allocator.write().unwrap();
        gens.alive.remove(entity.get_id());
        gens.raised.remove(entity.get_id());
        let id = entity.get_id() as usize;
        gens.generations[id].die();
        if id < gens.start_from.load(Ordering::Relaxed) {
            gens.start_from.store(id, Ordering::Relaxed);
        }
    }
    /// Creates a new entity dynamically.
    pub fn create_later(&self) -> Entity {
        let allocator = self.allocator.read().unwrap();
        allocator.allocate_atomic()
    }
    /// Deletes an entity dynamically.
    pub fn delete_later(&self, entity: Entity) {
        let allocator = self.allocator.read().unwrap();
        allocator.kill(entity);
    }
    /// Returns `true` if the given `Entity` is alive.
    pub fn is_alive(&self, entity: Entity) -> bool {
        debug_assert!(entity.get_gen().is_alive());
        let gens = self.allocator.read().unwrap();
        gens.generations.get(entity.get_id() as usize).map(|&x| x == entity.get_gen()).unwrap_or(false)
    }
    /// Merges in the appendix, recording all the dynamically created
    /// and deleted entities into the persistent generations vector.
    /// Also removes all the abandoned components.
    pub fn maintain(&mut self) {
        let mut allocator = self.allocator.write().unwrap();

        let temp_list = allocator.merge();
        for comp in self.components.values() {
            comp.del_slice(&temp_list);
        }
    }
    /// add a new resource to the world
    pub fn add_resource<T: Any+Send+Sync>(&mut self, resource: T) {
        let resource = Box::new(RwLock::new(resource));
        self.resources.insert(TypeId::of::<T>(), resource);
    }
    /// check to see if a resource is present
    pub fn has_resource<T: Any+Send+Sync>(&self) -> bool {
        self.resources.get(&TypeId::of::<T>()).is_some()
    }
    /// get read-only access to an resource
    pub fn read_resource<T: Any+Send+Sync>(&self) -> RwLockReadGuard<T> {
        self.resources.get(&TypeId::of::<T>())
            .expect("Resource was not registered")
            .downcast_ref::<RwLock<T>>()
            .unwrap()
            .read()
            .unwrap()
    }
    /// get read-write access to a resource
    pub fn write_resource<T: Any+Send+Sync>(&self) -> RwLockWriteGuard<T> {
        self.resources.get(&TypeId::of::<T>())
            .expect("Resource was not registered")
            .downcast_ref::<RwLock<T>>()
            .unwrap()
            .write()
            .unwrap()
    }
}
<commit_msg>Added simple support for dynamic components. Not tested yet.<commit_after>use std::any::TypeId;
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::sync::atomic::{AtomicUsize, Ordering};
use mopa::Any;
use bitset::{AtomicBitSet, BitSet, BitSetLike, BitSetOr};
use join::Join;
use storage::{Storage, MaskedStorage, UnprotectedStorage};
use {Index, Generation, Entity};

/// Abstract component type. Doesn't have to be Copy or even Clone.
pub trait Component: Any + Sized {
    /// Associated storage type for this component.
    type Storage: UnprotectedStorage<Self> + Any + Send + Sync;
}

/// A custom entity guard used to hide the the fact that Generations
/// is lazily created and updated. For this to be useful it _must_
/// be joined with a component. This is because the Generation table
/// includes every possible Generation of Entities even if they
/// have never been
pub struct Entities<'a> {
    guard: RwLockReadGuard<'a, Allocator>,
}

impl<'a> Join for &'a Entities<'a> {
    type Type = Entity;
    type Value = Self;
    type Mask = BitSetOr<&'a BitSet, &'a AtomicBitSet>;
    fn open(self) -> (Self::Mask, Self) {
        (BitSetOr(&self.guard.alive, &self.guard.raised), self)
    }
    unsafe fn get(v: &mut Self, idx: Index) -> Entity {
        let gen = v.guard.generations.get(idx as usize)
            .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
            .unwrap_or(Generation(1));
        Entity(idx, gen)
    }
}

/// Helper builder for entities.
pub struct EntityBuilder<'a, C = ()>(Entity, &'a World<C>)
    where C: 'a + PartialEq + Eq + Hash;

impl<'a, C> EntityBuilder<'a, C>
    where C: 'a + PartialEq + Eq + Hash
{
    /// Adds a `Component` value to the new `Entity`.
    pub fn with_w_comp_id<T: Component>(self, value: T, comp_id: C) -> EntityBuilder<'a, C> {
        self.1.write_w_comp_id::<T>(comp_id).insert(self.0, value);
        self
    }
    /// Finishes entity construction.
    pub fn build(self) -> Entity {
        self.0
    }
}

impl <'a> EntityBuilder<'a, ()> {
    /// Adds a `Component` value to the new `Entity`.
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.write::<T>().insert(self.0, value);
        self
    }
}

/// Internally used structure for `Entity` allocation.
pub struct Allocator {
    #[doc(hidden)]
    pub generations: Vec<Generation>,
    alive: BitSet,
    raised: AtomicBitSet,
    killed: AtomicBitSet,
    start_from: AtomicUsize
}

impl Allocator {
    #[doc(hidden)]
    pub fn new() -> Allocator {
        Allocator {
            generations: vec![],
            alive: BitSet::new(),
            raised: AtomicBitSet::new(),
            killed: AtomicBitSet::new(),
            start_from: AtomicUsize::new(0)
        }
    }

    fn kill(&self, e: Entity) {
        self.killed.add_atomic(e.get_id());
    }

    /// Return `true` if the entity is alive.
    pub fn is_alive(&self, e: Entity) -> bool {
        e.get_gen() ==  match self.generations.get(e.get_id() as usize) {
            Some(g) if !g.is_alive() && self.raised.contains(e.get_id()) => g.raised(),
            Some(g) => *g,
            None => Generation(1),
        }
    }

    /// Attempt to move the `start_from` value
    fn update_start_from(&self, start_from: usize) {
        loop {
            let current = self.start_from.load(Ordering::Relaxed);

            // if the current value is bigger then ours, we bail
            if current >= start_from {
                return;
            }

            if start_from == self.start_from.compare_and_swap(current, start_from, Ordering::Relaxed) {
                return;
            }
        }
    }

    /// Allocate a new entity
    fn allocate_atomic(&self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.alive.contains(i as Index) && !self.raised.add_atomic(i as Index) {
                self.update_start_from(i+1);

                let gen = self.generations.get(idx as usize)
                    .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
                    .unwrap_or(Generation(1));

                return Entity(i as Index, gen);
            }
        }
        panic!("No entities left to allocate")
    }

    /// Allocate a new entity
    fn allocate(&mut self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.raised.contains(i as Index) && !self.alive.add(i as Index) {
                // this is safe since we have mutable access to everything!
                self.start_from.store(i+1, Ordering::Relaxed);

                while self.generations.len() <= i as usize {
                    self.generations.push(Generation(0));
                }
                self.generations[i as usize] = self.generations[i as usize].raised();

                return Entity(i as Index, self.generations[i as usize]);
            }
        }
        panic!("No entities left to allocate")
    }

    fn merge(&mut self) -> Vec<Entity> {
        let mut deleted = vec![];

        for i in (&self.raised).iter() {
            while self.generations.len() <= i as usize {
                self.generations.push(Generation(0));
            }
            self.generations[i as usize] = self.generations[i as usize].raised();
            self.alive.add(i);
        }
        self.raised.clear();

        if let Some(lowest) = (&self.killed).iter().next() {
            if lowest < self.start_from.load(Ordering::Relaxed) as Index {
                self.start_from.store(lowest as usize, Ordering::Relaxed);
            }
        }

        for i in (&self.killed).iter() {
            self.alive.remove(i);
            self.generations[i as usize].die();
            deleted.push(Entity(i, self.generations[i as usize]))
        }
        self.killed.clear();

        deleted
    }
}

/// Entity creation iterator. Will yield new empty entities infinitely.
/// Useful for bulk entity construction, since the locks are only happening once.
pub struct CreateEntities<'a> {
    allocate: RwLockWriteGuard<'a, Allocator>,
}

impl<'a> Iterator for CreateEntities<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        Some(self.allocate.allocate())
    }
}

trait StorageLock: Any + Send + Sync {
    fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<T: Component> StorageLock for RwLock<MaskedStorage<T>> {
    fn del_slice(&self, entities: &[Entity]) {
        let mut guard = self.write().unwrap();
        for &e in entities.iter() {
            guard.remove(e.get_id());
        }
    }
}

trait ResourceLock: Any + Send + Sync {}

mopafy!(ResourceLock);

impl<T:Any+Send+Sync> ResourceLock for RwLock<T> {}

/// The `World` struct contains all the data, which is entities and their components.
/// All methods are supposed to be valid for any context they are available in.
/// The type parameter C is for component identification in addition of their types.
pub struct World<C = ()>
    where C: PartialEq + Eq + Hash
{
    allocator: RwLock<Allocator>,
    components: HashMap<(C, TypeId), Box<StorageLock>>,
    resources: HashMap<TypeId, Box<ResourceLock>>,
}

impl<C> World<C>
    where C: PartialEq + Eq + Hash
{
    /// Creates a new empty `World` with the associated component id.
    pub fn new_w_comp_id() -> World<C> {
        World {
            components: HashMap::new(),
            allocator: RwLock::new(Allocator::new()),
            resources: HashMap::new()
        }
    }
    /// Registers a new component type and id pair.
    pub fn register_w_comp_id<T: Component>(&mut self, comp_id: C) {
        let any = RwLock::new(MaskedStorage::<T>::new());
        self.components.insert((comp_id, TypeId::of::<T>()), Box::new(any));
    }
    /// Unregisters a component type and id pair.
    pub fn unregister_w_comp_id<T: Component>(&mut self, comp_id: C) -> Option<MaskedStorage<T>> {
        self.components.remove(&(comp_id, TypeId::of::<T>())).map(|boxed|
            match boxed.downcast::<RwLock<MaskedStorage<T>>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock_w_comp_id<T: Component>(&self, comp_id: C) -> &RwLock<MaskedStorage<T>> {
        let boxed = self.components.get(&(comp_id, TypeId::of::<T>()))
            .expect("Tried to perform an operation on component type that was not registered");
        boxed.downcast_ref().unwrap()
    }
    /// Locks a component's storage for reading.
    pub fn read_w_comp_id<T: Component>(&self, comp_id: C) -> Storage<T, RwLockReadGuard<Allocator>, RwLockReadGuard<MaskedStorage<T>>> {
        let data = self.lock_w_comp_id::<T>(comp_id).read().unwrap();
        Storage::new(self.allocator.read().unwrap(), data)
    }
    /// Locks a component's storage for writing.
    pub fn write_w_comp_id<T: Component>(&self, comp_id: C) ->
        Storage<T, RwLockReadGuard<Allocator>, RwLockWriteGuard<MaskedStorage<T>>>
    {
        let data = self.lock_w_comp_id::<T>(comp_id).write().unwrap();
        Storage::new(self.allocator.read().unwrap(), data)
    }
    /// Returns the entity iterator.
    pub fn entities(&self) -> Entities {
        Entities {
            guard: self.allocator.read().unwrap(),
        }
    }
    /// Returns the entity creation iterator. Can be used to create many
    /// empty entities at once without paying the locking overhead.
    pub fn create_iter(&mut self) -> CreateEntities {
        CreateEntities {
            allocate: self.allocator.write().unwrap(),
        }
    }
    /// Creates a new entity instantly, locking the generations data.
    pub fn create_now(&mut self) -> EntityBuilder<C> {
        let id = self.allocator.write().unwrap().allocate();
        EntityBuilder(id, self)
    }
    /// Deletes a new entity instantly, locking the generations data.
    pub fn delete_now(&mut self, entity: Entity) {
        for comp in self.components.values() {
            comp.del_slice(&[entity]);
        }
        let mut gens = self.allocator.write().unwrap();
        gens.alive.remove(entity.get_id());
        gens.raised.remove(entity.get_id());
        let id = entity.get_id() as usize;
        gens.generations[id].die();
        if id < gens.start_from.load(Ordering::Relaxed) {
            gens.start_from.store(id, Ordering::Relaxed);
        }
    }
    /// Creates a new entity dynamically.
    pub fn create_later(&self) -> Entity {
        let allocator = self.allocator.read().unwrap();
        allocator.allocate_atomic()
    }
    /// Deletes an entity dynamically.
    pub fn delete_later(&self, entity: Entity) {
        let allocator = self.allocator.read().unwrap();
        allocator.kill(entity);
    }
    /// Returns `true` if the given `Entity` is alive.
    pub fn is_alive(&self, entity: Entity) -> bool {
        debug_assert!(entity.get_gen().is_alive());
        let gens = self.allocator.read().unwrap();
        gens.generations.get(entity.get_id() as usize).map(|&x| x == entity.get_gen()).unwrap_or(false)
    }
    /// Merges in the appendix, recording all the dynamically created
    /// and deleted entities into the persistent generations vector.
    /// Also removes all the abandoned components.
    pub fn maintain(&mut self) {
        let mut allocator = self.allocator.write().unwrap();

        let temp_list = allocator.merge();
        for comp in self.components.values() {
            comp.del_slice(&temp_list);
        }
    }
    /// add a new resource to the world
    pub fn add_resource<T: Any+Send+Sync>(&mut self, resource: T) {
        let resource = Box::new(RwLock::new(resource));
        self.resources.insert(TypeId::of::<T>(), resource);
    }
    /// check to see if a resource is present
    pub fn has_resource<T: Any+Send+Sync>(&self) -> bool {
        self.resources.get(&TypeId::of::<T>()).is_some()
    }
    /// get read-only access to an resource
    pub fn read_resource<T: Any+Send+Sync>(&self) -> RwLockReadGuard<T> {
        self.resources.get(&TypeId::of::<T>())
            .expect("Resource was not registered")
            .downcast_ref::<RwLock<T>>()
            .unwrap()
            .read()
            .unwrap()
    }
    /// get read-write access to a resource
    pub fn write_resource<T: Any+Send+Sync>(&self) -> RwLockWriteGuard<T> {
        self.resources.get(&TypeId::of::<T>())
            .expect("Resource was not registered")
            .downcast_ref::<RwLock<T>>()
            .unwrap()
            .write()
            .unwrap()
    }
}

impl World<()> {
    /// Creates a new empty `World`.
    pub fn new() -> World<()> {
        World {
            components: HashMap::new(),
            allocator: RwLock::new(Allocator::new()),
            resources: HashMap::new()
        }
    }

    /// Registers a new component type.
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(MaskedStorage::<T>::new());
        self.components.insert(((), TypeId::of::<T>()), Box::new(any));
    }
    /// Unregisters a component type.
    pub fn unregister<T: Component>(&mut self) -> Option<MaskedStorage<T>> {
        self.components.remove(&((), TypeId::of::<T>())).map(|boxed|
            match boxed.downcast::<RwLock<MaskedStorage<T>>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock<T: Component>(&self) -> &RwLock<MaskedStorage<T>> {
        let boxed = self.components.get(&((), TypeId::of::<T>()))
            .expect("Tried to perform an operation on type that was not registered");
        boxed.downcast_ref().unwrap()
    }
    /// Locks a component's storage for reading.
    pub fn read<T: Component>(&self) -> Storage<T, RwLockReadGuard<Allocator>, RwLockReadGuard<MaskedStorage<T>>> {
        let data = self.lock::<T>().read().unwrap();
        Storage::new(self.allocator.read().unwrap(), data)
    }
    /// Locks a component's storage for writing.
    pub fn write<T: Component>(&self) -> Storage<T, RwLockReadGuard<Allocator>, RwLockWriteGuard<MaskedStorage<T>>> {
        let data = self.lock::<T>().write().unwrap();
        Storage::new(self.allocator.read().unwrap(), data)
    }
}
<|endoftext|>


<commit_before>//! An order-preserving immutable set constructed at compile time.
use core::borrow::Borrow;
use core::iter::IntoIterator;
use core::fmt;
use ordered_map;
use {PhfHash, OrderedMap};

/// An order-preserving immutable set constructed at compile time.
///
/// Unlike a `Set`, iteration order is guaranteed to match the definition
/// order.
///
/// ## Note
///
/// The fields of this struct are public so that they may be initialized by the
/// `phf_ordered_set!` macro and code generation. They are subject to change at
/// any time and should never be accessed directly.
pub struct OrderedSet<T: 'static> {
    #[doc(hidden)]
    pub map: OrderedMap<T, ()>,
}

impl<T> fmt::Debug for OrderedSet<T> where T: fmt::Debug {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_set().entries(self).finish()
    }
}

impl<T> OrderedSet<T> {
    /// Returns the number of elements in the `OrderedSet`.
    pub fn len(&self) -> usize {
        self.map.len()
    }

    /// Returns true if the `OrderedSet` contains no elements.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns a reference to the set's internal static instance of the given
    /// key.
    ///
    /// This can be useful for interning schemes.
    pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T>
        where U: Eq + PhfHash,
              T: Borrow<U>
    {
        self.map.get_key(key)
    }

    /// Returns the index of the key within the list used to initialize
    /// the ordered set.
    pub fn get_index<U: ?Sized>(&self, key: &U) -> Option<usize>
        where U: Eq + PhfHash,
              T: Borrow<U>
    {
        self.map.get_index(key)
    }

    /// Returns references to both the key and values at an index
    /// within the list used to initialize the ordered map. See `.get_index(key)`.
    pub fn index(&self, index: usize) -> Option<&T> {
        self.map.index(index).map(|(k, &())| k)
    }

    /// Returns true if `value` is in the `Set`.
    pub fn contains<U: ?Sized>(&self, value: &U) -> bool
        where U: Eq + PhfHash,
              T: Borrow<U>
    {
        self.map.contains_key(value)
    }

    /// Returns an iterator over the values in the set.
    ///
    /// Values are returned in the same order in which they were defined.
    pub fn iter<'a>(&'a self) -> Iter<'a, T> {
        Iter { iter: self.map.keys() }
    }
}

impl<T> OrderedSet<T> where T: Eq + PhfHash {
    /// Returns true if `other` shares no elements with `self`.
    #[inline]
    pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool {
        !self.iter().any(|value| other.contains(value))
    }

    /// Returns true if `other` contains all values in `self`.
    #[inline]
    pub fn is_subset(&self, other: &OrderedSet<T>) -> bool {
        self.iter().all(|value| other.contains(value))
    }

    /// Returns true if `self` contains all values in `other`.
    #[inline]
    pub fn is_superset(&self, other: &OrderedSet<T>) -> bool {
        other.is_subset(self)
    }
}

impl<'a, T> IntoIterator for &'a OrderedSet<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

/// An iterator over the values in a `OrderedSet`.
pub struct Iter<'a, T: 'a> {
    iter: ordered_map::Keys<'a, T, ()>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    #[inline]
    fn next(&mut self) -> Option<&'a T> {
        self.iter.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
    #[inline]
    fn next_back(&mut self) -> Option<&'a T> {
        self.iter.next_back()
    }
}

impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
<commit_msg>Fix ordered set `index` documentation<commit_after>//! An order-preserving immutable set constructed at compile time.
use core::borrow::Borrow;
use core::iter::IntoIterator;
use core::fmt;
use ordered_map;
use {PhfHash, OrderedMap};

/// An order-preserving immutable set constructed at compile time.
///
/// Unlike a `Set`, iteration order is guaranteed to match the definition
/// order.
///
/// ## Note
///
/// The fields of this struct are public so that they may be initialized by the
/// `phf_ordered_set!` macro and code generation. They are subject to change at
/// any time and should never be accessed directly.
pub struct OrderedSet<T: 'static> {
    #[doc(hidden)]
    pub map: OrderedMap<T, ()>,
}

impl<T> fmt::Debug for OrderedSet<T> where T: fmt::Debug {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_set().entries(self).finish()
    }
}

impl<T> OrderedSet<T> {
    /// Returns the number of elements in the `OrderedSet`.
    pub fn len(&self) -> usize {
        self.map.len()
    }

    /// Returns true if the `OrderedSet` contains no elements.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns a reference to the set's internal static instance of the given
    /// key.
    ///
    /// This can be useful for interning schemes.
    pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T>
        where U: Eq + PhfHash,
              T: Borrow<U>
    {
        self.map.get_key(key)
    }

    /// Returns the index of the key within the list used to initialize
    /// the ordered set.
    pub fn get_index<U: ?Sized>(&self, key: &U) -> Option<usize>
        where U: Eq + PhfHash,
              T: Borrow<U>
    {
        self.map.get_index(key)
    }

    /// Returns a reference to the key at an index
    /// within the list used to initialize the ordered set. See `.get_index(key)`.
    pub fn index(&self, index: usize) -> Option<&T> {
        self.map.index(index).map(|(k, &())| k)
    }

    /// Returns true if `value` is in the `Set`.
    pub fn contains<U: ?Sized>(&self, value: &U) -> bool
        where U: Eq + PhfHash,
              T: Borrow<U>
    {
        self.map.contains_key(value)
    }

    /// Returns an iterator over the values in the set.
    ///
    /// Values are returned in the same order in which they were defined.
    pub fn iter<'a>(&'a self) -> Iter<'a, T> {
        Iter { iter: self.map.keys() }
    }
}

impl<T> OrderedSet<T> where T: Eq + PhfHash {
    /// Returns true if `other` shares no elements with `self`.
    #[inline]
    pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool {
        !self.iter().any(|value| other.contains(value))
    }

    /// Returns true if `other` contains all values in `self`.
    #[inline]
    pub fn is_subset(&self, other: &OrderedSet<T>) -> bool {
        self.iter().all(|value| other.contains(value))
    }

    /// Returns true if `self` contains all values in `other`.
    #[inline]
    pub fn is_superset(&self, other: &OrderedSet<T>) -> bool {
        other.is_subset(self)
    }
}

impl<'a, T> IntoIterator for &'a OrderedSet<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

/// An iterator over the values in a `OrderedSet`.
pub struct Iter<'a, T: 'a> {
    iter: ordered_map::Keys<'a, T, ()>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    #[inline]
    fn next(&mut self) -> Option<&'a T> {
        self.iter.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
    #[inline]
    fn next_back(&mut self) -> Option<&'a T> {
        self.iter.next_back()
    }
}

impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
<|endoftext|>


<commit_before>use crate::build_utils;
use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::geth_genesis_json;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use std::{env, fs::File};
use tempfile::TempDir;
use unused_port::unused_tcp_port;

const GETH_BRANCH: &str = "master";
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";

pub fn build_result(repo_dir: &Path) -> Output {
    Command::new("make")
        .arg("geth")
        .current_dir(&repo_dir)
        .output()
        .expect("failed to make geth")
}

pub fn build(execution_clients_dir: &Path) {
    let repo_dir = execution_clients_dir.join("go-ethereum");

    if !repo_dir.exists() {
        // Clone the repo
        build_utils::clone_repo(execution_clients_dir, GETH_REPO_URL).unwrap();
    }

    // Get the latest tag on the branch
    let last_release = build_utils::get_latest_release(&repo_dir, GETH_BRANCH).unwrap();
    build_utils::checkout(&repo_dir, dbg!(&last_release)).unwrap();

    // Build geth
    build_utils::check_command_output(build_result(&repo_dir), || {
        format!("geth make failed using release {last_release}")
    });
}

/*
 * Geth-specific Implementation for GenericExecutionEngine
 */

#[derive(Clone)]
pub struct GethEngine;

impl GethEngine {
    fn binary_path() -> PathBuf {
        let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
        manifest_dir
            .join("execution_clients")
            .join("go-ethereum")
            .join("build")
            .join("bin")
            .join("geth")
    }
}

impl GenericExecutionEngine for GethEngine {
    fn init_datadir() -> TempDir {
        let datadir = TempDir::new().unwrap();

        let genesis_json_path = datadir.path().join("genesis.json");
        let mut file = File::create(&genesis_json_path).unwrap();
        let json = geth_genesis_json();
        serde_json::to_writer(&mut file, &json).unwrap();

        let output = Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("init")
            .arg(genesis_json_path.to_str().unwrap())
            .output()
            .expect("failed to init geth");

        build_utils::check_command_output(output, || "geth init failed".into());

        datadir
    }

    fn start_client(
        datadir: &TempDir,
        http_port: u16,
        http_auth_port: u16,
        jwt_secret_path: PathBuf,
    ) -> Child {
        let network_port = unused_tcp_port().unwrap();

        Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("--http")
            .arg("--http.api")
            .arg("engine,eth,personal")
            .arg("--http.port")
            .arg(http_port.to_string())
            .arg("--authrpc.port")
            .arg(http_auth_port.to_string())
            .arg("--port")
            .arg(network_port.to_string())
            .arg("--allow-insecure-unlock")
            .arg("--authrpc.jwtsecret")
            .arg(jwt_secret_path.as_path().to_str().unwrap())
            .stdout(build_utils::build_stdio())
            .stderr(build_utils::build_stdio())
            .spawn()
            .expect("failed to start geth")
    }
}
<commit_msg>Downgrade Geth to v1.10.20 in EE integration tests (#3382)<commit_after>use crate::build_utils;
use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::geth_genesis_json;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use std::{env, fs::File};
use tempfile::TempDir;
use unused_port::unused_tcp_port;

// const GETH_BRANCH: &str = "master";
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";

pub fn build_result(repo_dir: &Path) -> Output {
    Command::new("make")
        .arg("geth")
        .current_dir(&repo_dir)
        .output()
        .expect("failed to make geth")
}

pub fn build(execution_clients_dir: &Path) {
    let repo_dir = execution_clients_dir.join("go-ethereum");

    if !repo_dir.exists() {
        // Clone the repo
        build_utils::clone_repo(execution_clients_dir, GETH_REPO_URL).unwrap();
    }

    // TODO: this should be set back to the latest release once the following issue is resolved:
    //
    // - https://github.com/ethereum/go-ethereum/issues/25427
    //
    // Get the latest tag on the branch
    // let last_release = build_utils::get_latest_release(&repo_dir, GETH_BRANCH).unwrap();
    let last_release = "v1.10.20";
    build_utils::checkout(&repo_dir, dbg!(&last_release)).unwrap();

    // Build geth
    build_utils::check_command_output(build_result(&repo_dir), || {
        format!("geth make failed using release {last_release}")
    });
}

/*
 * Geth-specific Implementation for GenericExecutionEngine
 */

#[derive(Clone)]
pub struct GethEngine;

impl GethEngine {
    fn binary_path() -> PathBuf {
        let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
        manifest_dir
            .join("execution_clients")
            .join("go-ethereum")
            .join("build")
            .join("bin")
            .join("geth")
    }
}

impl GenericExecutionEngine for GethEngine {
    fn init_datadir() -> TempDir {
        let datadir = TempDir::new().unwrap();

        let genesis_json_path = datadir.path().join("genesis.json");
        let mut file = File::create(&genesis_json_path).unwrap();
        let json = geth_genesis_json();
        serde_json::to_writer(&mut file, &json).unwrap();

        let output = Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("init")
            .arg(genesis_json_path.to_str().unwrap())
            .output()
            .expect("failed to init geth");

        build_utils::check_command_output(output, || "geth init failed".into());

        datadir
    }

    fn start_client(
        datadir: &TempDir,
        http_port: u16,
        http_auth_port: u16,
        jwt_secret_path: PathBuf,
    ) -> Child {
        let network_port = unused_tcp_port().unwrap();

        Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("--http")
            .arg("--http.api")
            .arg("engine,eth,personal")
            .arg("--http.port")
            .arg(http_port.to_string())
            .arg("--authrpc.port")
            .arg(http_auth_port.to_string())
            .arg("--port")
            .arg(network_port.to_string())
            .arg("--allow-insecure-unlock")
            .arg("--authrpc.jwtsecret")
            .arg(jwt_secret_path.as_path().to_str().unwrap())
            .stdout(build_utils::build_stdio())
            .stderr(build_utils::build_stdio())
            .spawn()
            .expect("failed to start geth")
    }
}
<|endoftext|>


<commit_before>//! Types and traits related to serializing values for the database

use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::ops::{Deref, DerefMut};
use std::result;

use backend::Backend;
use sql_types::TypeMetadata;

#[cfg(feature = "postgres")]
pub use pg::serialize::*;

/// A specialized result type representing the result of serializing
/// a value for the database.
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    /// No data was written, as this type is null
    Yes,
    /// The value is not null
    ///
    /// This does not necessarily mean that any data was written to the buffer.
    /// For example, an empty string has no data to be sent over the wire, but
    /// also is not null.
    No,
}

/// Wraps a buffer to be written by `ToSql` with additional backend specific
/// utilities.
#[derive(Clone, Copy)]
pub struct Output<'a, T, DB>
where
    DB: TypeMetadata,
    DB::MetadataLookup: 'a,
{
    out: T,
    metadata_lookup: &'a DB::MetadataLookup,
}

impl<'a, T, DB: TypeMetadata> Output<'a, T, DB> {
    /// Construct a new `Output`
    pub fn new(out: T, metadata_lookup: &'a DB::MetadataLookup) -> Self {
        Output {
            out,
            metadata_lookup,
        }
    }

    /// Create a new `Output` with the given buffer
    pub fn with_buffer<U>(&self, new_out: U) -> Output<'a, U, DB> {
        Output {
            out: new_out,
            metadata_lookup: self.metadata_lookup,
        }
    }

    /// Return the raw buffer this type is wrapping
    pub fn into_inner(self) -> T {
        self.out
    }

    /// Returns the backend's mechanism for dynamically looking up type
    /// metadata at runtime, if relevant for the given backend.
    pub fn metadata_lookup(&self) -> &'a DB::MetadataLookup {
        self.metadata_lookup
    }
}

#[cfg(test)]
impl<DB: TypeMetadata> Output<'static, Vec<u8>, DB> {
    /// Returns a `Output` suitable for testing `ToSql` implementations.
    /// Unsafe to use for testing types which perform dynamic metadata lookup.
    pub fn test() -> Self {
        use std::mem;
        // Allowing `deprecated` here because we are ok with using `mem::uninitialized`
        // here. (Yes it's UB, but that won't be fixed by using `mem::MaybeUninit`
        // but hey it's only for test code …)
        #[allow(clippy::invalid_ref, deprecated)]
        Self::new(Vec::new(), unsafe { mem::uninitialized() })
    }
}

impl<'a, T: Write, DB: TypeMetadata> Write for Output<'a, T, DB> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.out.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.out.flush()
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.out.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.out.write_fmt(fmt)
    }
}

impl<'a, T, DB: TypeMetadata> Deref for Output<'a, T, DB> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.out
    }
}

impl<'a, T, DB: TypeMetadata> DerefMut for Output<'a, T, DB> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.out
    }
}

impl<'a, T, U, DB> PartialEq<U> for Output<'a, T, DB>
where
    DB: TypeMetadata,
    T: PartialEq<U>,
{
    fn eq(&self, rhs: &U) -> bool {
        self.out == *rhs
    }
}

impl<'a, T, DB> fmt::Debug for Output<'a, T, DB>
where
    T: fmt::Debug,
    DB: TypeMetadata,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.out.fmt(f)
    }
}

/// Serializes a single value to be sent to the database.
///
/// The output is sent as a bind parameter, and the data must be written in the
/// expected format for the given backend.
///
/// When possible, implementations of this trait should prefer using an existing
/// implementation, rather than writing to `out` directly. (For example, if you
/// are implementing this for an enum, which is represented as an integer in the
/// database, you should use `i32::to_sql(x, out)` instead of writing to `out`
/// yourself.
///
/// Any types which implement this trait should also `#[derive(AsExpression)]`.
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, all implementations should be written in terms of an existing
///   `ToSql` implementation.
/// - For MySQL, the expected bytes will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
///
/// ### Examples
///
/// Most implementations of this trait will be defined in terms of an existing
/// implementation.
///
/// ```rust
/// # use diesel::backend::Backend;
/// # use diesel::sql_types::*;
/// # use diesel::serialize::{self, ToSql, Output};
/// # use std::io::Write;
/// #
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy)]
/// pub enum MyEnum {
///     A = 1,
///     B = 2,
/// }
///
/// impl<DB> ToSql<Integer, DB> for MyEnum
/// where
///     DB: Backend,
///     i32: ToSql<Integer, DB>,
/// {
///     fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
///         (*self as i32).to_sql(out)
///     }
/// }
/// ```
pub trait ToSql<A, DB: Backend>: fmt::Debug {
    /// See the trait documentation.
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
    DB: Backend,
    T: ToSql<A, DB> + ?Sized,
{
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result {
        (*self).to_sql(out)
    }
}
<commit_msg>Remove `mem::uninitialized` from testcase to fix ci<commit_after>//! Types and traits related to serializing values for the database

use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::ops::{Deref, DerefMut};
use std::result;

use backend::Backend;
use sql_types::TypeMetadata;

#[cfg(feature = "postgres")]
pub use pg::serialize::*;

/// A specialized result type representing the result of serializing
/// a value for the database.
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    /// No data was written, as this type is null
    Yes,
    /// The value is not null
    ///
    /// This does not necessarily mean that any data was written to the buffer.
    /// For example, an empty string has no data to be sent over the wire, but
    /// also is not null.
    No,
}

/// Wraps a buffer to be written by `ToSql` with additional backend specific
/// utilities.
#[derive(Clone, Copy)]
pub struct Output<'a, T, DB>
where
    DB: TypeMetadata,
    DB::MetadataLookup: 'a,
{
    out: T,
    metadata_lookup: Option<&'a DB::MetadataLookup>,
}

impl<'a, T, DB: TypeMetadata> Output<'a, T, DB> {
    /// Construct a new `Output`
    pub fn new(out: T, metadata_lookup: &'a DB::MetadataLookup) -> Self {
        Output {
            out,
            metadata_lookup: Some(metadata_lookup),
        }
    }

    /// Create a new `Output` with the given buffer
    pub fn with_buffer<U>(&self, new_out: U) -> Output<'a, U, DB> {
        Output {
            out: new_out,
            metadata_lookup: self.metadata_lookup,
        }
    }

    /// Return the raw buffer this type is wrapping
    pub fn into_inner(self) -> T {
        self.out
    }

    /// Returns the backend's mechanism for dynamically looking up type
    /// metadata at runtime, if relevant for the given backend.
    pub fn metadata_lookup(&self) -> &'a DB::MetadataLookup {
        self.metadata_lookup.expect("Lookup is there")
    }
}

#[cfg(test)]
impl<DB: TypeMetadata> Output<'static, Vec<u8>, DB> {
    /// Returns a `Output` suitable for testing `ToSql` implementations.
    /// Unsafe to use for testing types which perform dynamic metadata lookup.
    pub fn test() -> Self {
        Self {
            out: Vec::new(),
            metadata_lookup: None,
        }
    }
}

impl<'a, T: Write, DB: TypeMetadata> Write for Output<'a, T, DB> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.out.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.out.flush()
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.out.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.out.write_fmt(fmt)
    }
}

impl<'a, T, DB: TypeMetadata> Deref for Output<'a, T, DB> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.out
    }
}

impl<'a, T, DB: TypeMetadata> DerefMut for Output<'a, T, DB> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.out
    }
}

impl<'a, T, U, DB> PartialEq<U> for Output<'a, T, DB>
where
    DB: TypeMetadata,
    T: PartialEq<U>,
{
    fn eq(&self, rhs: &U) -> bool {
        self.out == *rhs
    }
}

impl<'a, T, DB> fmt::Debug for Output<'a, T, DB>
where
    T: fmt::Debug,
    DB: TypeMetadata,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.out.fmt(f)
    }
}

/// Serializes a single value to be sent to the database.
///
/// The output is sent as a bind parameter, and the data must be written in the
/// expected format for the given backend.
///
/// When possible, implementations of this trait should prefer using an existing
/// implementation, rather than writing to `out` directly. (For example, if you
/// are implementing this for an enum, which is represented as an integer in the
/// database, you should use `i32::to_sql(x, out)` instead of writing to `out`
/// yourself.
///
/// Any types which implement this trait should also `#[derive(AsExpression)]`.
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, all implementations should be written in terms of an existing
///   `ToSql` implementation.
/// - For MySQL, the expected bytes will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
///
/// ### Examples
///
/// Most implementations of this trait will be defined in terms of an existing
/// implementation.
///
/// ```rust
/// # use diesel::backend::Backend;
/// # use diesel::sql_types::*;
/// # use diesel::serialize::{self, ToSql, Output};
/// # use std::io::Write;
/// #
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy)]
/// pub enum MyEnum {
///     A = 1,
///     B = 2,
/// }
///
/// impl<DB> ToSql<Integer, DB> for MyEnum
/// where
///     DB: Backend,
///     i32: ToSql<Integer, DB>,
/// {
///     fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
///         (*self as i32).to_sql(out)
///     }
/// }
/// ```
pub trait ToSql<A, DB: Backend>: fmt::Debug {
    /// See the trait documentation.
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
    DB: Backend,
    T: ToSql<A, DB> + ?Sized,
{
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result {
        (*self).to_sql(out)
    }
}
<|endoftext|>