<commit_before>use acyclic_network::{Network, NodeType, NodeIndex};
use weight::{Weight, WeightRange, WeightPerturbanceMethod};
use prob::Prob;
use rand::Rng;

/// Genome representing a feed-forward (acyclic) network with node type `NT`.
#[derive(Clone, Debug)]
pub struct Genome<NT: NodeType> {
    /// Represents the acyclic feed forward network, with `NT` as node type and `Weight` for the edge weights.
    /// Other than that, nodes and edges do not have any further associated information (`()`).
    network: Network<NT, Weight, ()>,

    /// The genome can contain some nodes which cannot be modified or removed. These are the first
    /// `protected_nodes` in `network`.
    protected_nodes: usize,
}

impl<NT: NodeType> Genome<NT> {
    pub fn new() -> Self {
        Genome {
            network: Network::new(),
            protected_nodes: 0,
        }
    }

    pub fn protect_nodes(&mut self) {
        self.protected_nodes = self.network.node_count();
    }

    /// Returns a reference to the feed forward network.

    pub fn network(&self) -> &Network<NT, Weight, ()> {
        &self.network
    }

    /// Connects two previously unconnected nodes by adding a link between `source_node` and `target_node` using `weight`.
    ///
    /// Does not check for cycles. Test for cycles before using this method!
    ///
    /// # Panics
    ///
    /// If one of `source_node` or `target_node` does not exist.
    ///
    /// If a connection between these nodes already exists!
    ///
    /// # Complexity
    ///
    /// O(1) because we use `add_link_unorderd`.

    pub fn add_link(&mut self, source_node: NodeIndex, target_node: NodeIndex, weight: Weight) {
        debug_assert!(!self.network.link_would_cycle(source_node, target_node));
        debug_assert!(self.network.valid_link(source_node, target_node).is_ok());

        let _link_index = self.network.add_link_unordered(source_node, target_node, weight, ());
    }

    pub fn add_node(&mut self, node_type: NT) -> NodeIndex {
        self.network.add_node(node_type, ())
    }

    pub fn node_count(&self) -> usize {
        self.network.node_count()
    }

    fn random_node<R>(&self, tournament_k: usize, rng: &mut R) -> Option<NodeIndex>
        where R: Rng
    {
        assert!(tournament_k > 0);

        let n = self.network.node_count();
        if self.protected_nodes >= n {
            return None;
        }

        let mut min_node = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
        let mut min_degree = self.network.node(min_node).degree();
        for _ in 1..tournament_k {
            let node_idx = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
            let degree = self.network.node(node_idx).degree();
            if degree < min_degree {
                min_node = node_idx;
                min_degree = degree;
            }
        }

        Some(min_node)
    }

    /// Structural Mutation `AddNode`.
    ///
    /// Choose a random link and split it into two by inserting a new node in the middle.
    ///
    /// Note that the new `node_type` should allow incoming and outgoing links! Otherwise
    /// this panics!

    pub fn mutate_add_node<R>(&mut self,
                              node_type: NT,
                              second_link_weight: Option<Weight>,
                              rng: &mut R)
                              -> bool
        where R: Rng
    {
        let link_index = match self.network.random_link_index(rng) {
            Some(idx) => idx,
            None => return false,
        };

        let (orig_source_node, orig_target_node, orig_weight) = {
            let link = self.network.link(link_index);
            (link.source_node_index(),
             link.target_node_index(),
             link.weight())
        };

        // remove original link
        self.network.remove_link_at(link_index);

        // Add new "middle" node
        let middle_node = self.network.add_node(node_type, ());

        // Add two new links connecting the three nodes. This cannot add a cycle!
        //
        // The first link reuses the same weight as the original link.
        // The second link uses `second_link_weight` as weight (or if `None`, `orig_weight`).
        // Ideally this is of full strength as we want to make the modification
        // to the network (CPPN) as little as possible.

        self.add_link(orig_source_node, middle_node, orig_weight);
        self.add_link(middle_node,
                      orig_target_node,
                      second_link_weight.unwrap_or(orig_weight));

        return true;
    }

    /// Structural Mutation `DropNode`.
    ///
    /// Choose a random node and remove it. All in and outgoing links to and from that node
    /// are removed as well. Note that the first `protected_nodes` cannot be removed!
    ///
    /// We choose `tournament_k` random nodes and remove the one with the smallest degree.

    pub fn mutate_drop_node<R>(&mut self, tournament_k: usize, rng: &mut R) -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.remove_node(node_idx);
                true
            }
        }
    }

    /// Structural Mutation `ModifyNode`.
    ///
    /// Choose a random node and change it's type to `new_node_type`.
    /// Note that protected nodes are not modified.
    ///
    /// We choose from `tournament_k` nodes the one with the smallest degree.

    pub fn mutate_modify_node<R>(&mut self,
                                 new_node_type: NT,
                                 tournament_k: usize,
                                 rng: &mut R)
                                 -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.node_mut(node_idx).set_node_type(new_node_type);
                true
            }
        }
    }

    /// Structural Mutation `Connect`.
    ///
    /// Mutate the genome by adding a random valid link which does not introduce a cycle.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_connect<R>(&mut self, link_weight: Weight, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.find_random_unconnected_link_no_cycle(rng) {
            Some((source_node, target_node)) => {
                // Add new link to the genome
                self.add_link(source_node, target_node, link_weight);
                return true;
            }
            None => {
                return false;
            }
        }
    }

    /// Structural Mutation `Disconnect`.
    ///
    /// Mutate the genome by removing a random link.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_disconnect<R>(&mut self, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.random_link_index(rng) {
            Some(idx) => {
                self.network.remove_link_at(idx);
                true
            }
            None => false,
        }
    }

    /// Uniformly modify the weight of links, each with a probability of `mutate_element_prob`. It
    /// the genome contains at least one link, it is guaranteed that this method makes a modification.
    ///
    /// Returns the number of modifications (if negative, indicates that we used a random link).

    pub fn mutate_weights<R>(&mut self,
                             mutate_element_prob: Prob,
                             weight_perturbance: &WeightPerturbanceMethod,
                             link_weight_range: &WeightRange,
                             rng: &mut R)
                             -> isize
        where R: Rng
    {
        let mut modifications = 0;

        self.network.each_link_mut(|link| {
            if mutate_element_prob.flip(rng) {
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications += 1;
            }
        });

        if modifications == 0 {
            // Make at least one change to a randomly selected link.
            if let Some(link_idx) = self.network.random_link_index(rng) {
                let link = self.network.link_mut(link_idx);
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications -= 1;
            }
        }

        return modifications;
    }

    pub fn crossover_weights<R>(&mut self, _partner: &Self, _rng: &mut R) -> isize
        where R: Rng
    {
        unimplemented!()
    }
}
<commit_msg>ModifyNode: Check if we really modify the node or not<commit_after>use acyclic_network::{Network, NodeType, NodeIndex};
use weight::{Weight, WeightRange, WeightPerturbanceMethod};
use prob::Prob;
use rand::Rng;

/// Genome representing a feed-forward (acyclic) network with node type `NT`.
#[derive(Clone, Debug)]
pub struct Genome<NT: NodeType> {
    /// Represents the acyclic feed forward network, with `NT` as node type and `Weight` for the edge weights.
    /// Other than that, nodes and edges do not have any further associated information (`()`).
    network: Network<NT, Weight, ()>,

    /// The genome can contain some nodes which cannot be modified or removed. These are the first
    /// `protected_nodes` in `network`.
    protected_nodes: usize,
}

impl<NT: NodeType> Genome<NT> {
    pub fn new() -> Self {
        Genome {
            network: Network::new(),
            protected_nodes: 0,
        }
    }

    pub fn protect_nodes(&mut self) {
        self.protected_nodes = self.network.node_count();
    }

    /// Returns a reference to the feed forward network.

    pub fn network(&self) -> &Network<NT, Weight, ()> {
        &self.network
    }

    /// Connects two previously unconnected nodes by adding a link between `source_node` and `target_node` using `weight`.
    ///
    /// Does not check for cycles. Test for cycles before using this method!
    ///
    /// # Panics
    ///
    /// If one of `source_node` or `target_node` does not exist.
    ///
    /// If a connection between these nodes already exists!
    ///
    /// # Complexity
    ///
    /// O(1) because we use `add_link_unorderd`.

    pub fn add_link(&mut self, source_node: NodeIndex, target_node: NodeIndex, weight: Weight) {
        debug_assert!(!self.network.link_would_cycle(source_node, target_node));
        debug_assert!(self.network.valid_link(source_node, target_node).is_ok());

        let _link_index = self.network.add_link_unordered(source_node, target_node, weight, ());
    }

    pub fn add_node(&mut self, node_type: NT) -> NodeIndex {
        self.network.add_node(node_type, ())
    }

    pub fn node_count(&self) -> usize {
        self.network.node_count()
    }

    fn random_node<R>(&self, tournament_k: usize, rng: &mut R) -> Option<NodeIndex>
        where R: Rng
    {
        assert!(tournament_k > 0);

        let n = self.network.node_count();
        if self.protected_nodes >= n {
            return None;
        }

        let mut min_node = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
        let mut min_degree = self.network.node(min_node).degree();
        for _ in 1..tournament_k {
            let node_idx = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
            let degree = self.network.node(node_idx).degree();
            if degree < min_degree {
                min_node = node_idx;
                min_degree = degree;
            }
        }

        Some(min_node)
    }

    /// Structural Mutation `AddNode`.
    ///
    /// Choose a random link and split it into two by inserting a new node in the middle.
    ///
    /// Note that the new `node_type` should allow incoming and outgoing links! Otherwise
    /// this panics!

    pub fn mutate_add_node<R>(&mut self,
                              node_type: NT,
                              second_link_weight: Option<Weight>,
                              rng: &mut R)
                              -> bool
        where R: Rng
    {
        let link_index = match self.network.random_link_index(rng) {
            Some(idx) => idx,
            None => return false,
        };

        let (orig_source_node, orig_target_node, orig_weight) = {
            let link = self.network.link(link_index);
            (link.source_node_index(),
             link.target_node_index(),
             link.weight())
        };

        // remove original link
        self.network.remove_link_at(link_index);

        // Add new "middle" node
        let middle_node = self.network.add_node(node_type, ());

        // Add two new links connecting the three nodes. This cannot add a cycle!
        //
        // The first link reuses the same weight as the original link.
        // The second link uses `second_link_weight` as weight (or if `None`, `orig_weight`).
        // Ideally this is of full strength as we want to make the modification
        // to the network (CPPN) as little as possible.

        self.add_link(orig_source_node, middle_node, orig_weight);
        self.add_link(middle_node,
                      orig_target_node,
                      second_link_weight.unwrap_or(orig_weight));

        return true;
    }

    /// Structural Mutation `DropNode`.
    ///
    /// Choose a random node and remove it. All in and outgoing links to and from that node
    /// are removed as well. Note that the first `protected_nodes` cannot be removed!
    ///
    /// We choose `tournament_k` random nodes and remove the one with the smallest degree.

    pub fn mutate_drop_node<R>(&mut self, tournament_k: usize, rng: &mut R) -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.remove_node(node_idx);
                true
            }
        }
    }

    /// Structural Mutation `ModifyNode`.
    ///
    /// Choose a random node and change it's type to `new_node_type`.
    /// Note that protected nodes are not modified.
    ///
    /// We choose from `tournament_k` nodes the one with the smallest degree.

    pub fn mutate_modify_node<R>(&mut self,
                                 new_node_type: NT,
                                 tournament_k: usize,
                                 rng: &mut R)
                                 -> bool
        where R: Rng
    {
        if let Some(node_idx) = self.random_node(tournament_k, rng) {
           if self.network.node(node_idx).node_type() != &new_node_type {
               self.network.node_mut(node_idx).set_node_type(new_node_type);
               return true;
           }
        }
        return false;
    }

    /// Structural Mutation `Connect`.
    ///
    /// Mutate the genome by adding a random valid link which does not introduce a cycle.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_connect<R>(&mut self, link_weight: Weight, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.find_random_unconnected_link_no_cycle(rng) {
            Some((source_node, target_node)) => {
                // Add new link to the genome
                self.add_link(source_node, target_node, link_weight);
                return true;
            }
            None => {
                return false;
            }
        }
    }

    /// Structural Mutation `Disconnect`.
    ///
    /// Mutate the genome by removing a random link.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_disconnect<R>(&mut self, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.random_link_index(rng) {
            Some(idx) => {
                self.network.remove_link_at(idx);
                true
            }
            None => false,
        }
    }

    /// Uniformly modify the weight of links, each with a probability of `mutate_element_prob`. It
    /// the genome contains at least one link, it is guaranteed that this method makes a modification.
    ///
    /// Returns the number of modifications (if negative, indicates that we used a random link).

    pub fn mutate_weights<R>(&mut self,
                             mutate_element_prob: Prob,
                             weight_perturbance: &WeightPerturbanceMethod,
                             link_weight_range: &WeightRange,
                             rng: &mut R)
                             -> isize
        where R: Rng
    {
        let mut modifications = 0;

        self.network.each_link_mut(|link| {
            if mutate_element_prob.flip(rng) {
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications += 1;
            }
        });

        if modifications == 0 {
            // Make at least one change to a randomly selected link.
            if let Some(link_idx) = self.network.random_link_index(rng) {
                let link = self.network.link_mut(link_idx);
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications -= 1;
            }
        }

        return modifications;
    }

    pub fn crossover_weights<R>(&mut self, _partner: &Self, _rng: &mut R) -> isize
        where R: Rng
    {
        unimplemented!()
    }
}
<|endoftext|>


<commit_before>use std::iter::FromIterator;

use serde::{
    Deserialize,
    Serialize,
};

use thiserror::Error;

use rnc_core::{
    urs,
    urs_taxid,
};

use crate::normalize::utils;

use crate::normalize::ds::{
    accession::{
        AccessionVec,
        CrossReference,
        RawAccession,
        ReferenceVec,
    },
    basic::Basic,
    crs::{
        Crs,
        CrsVec,
    },
    feedback::{
        Feedback,
        FeedbackVec,
    },
    go_annotation::GoAnnotation,
    interacting_protein::InteractingProtein,
    interacting_rna::InteractingRna,
    precompute::{
        Precompute,
        PrecomputeSummary,
    },
    qa_status::QaStatus,
    r2dt::R2dt,
    rfam_hit::{
        RfamHit,
        RfamHitVec,
    },
    so_tree,
};

#[derive(Error, Debug)]
pub enum NormalizationError {
    #[error("Could not ungroup {0}")]
    CountError(#[from] utils::Error),

    #[error("Could not parse {0}")]
    UrsParsingError(#[from] urs::Error),

    #[error("Could not parse {0}")]
    UrsTaxidParsingError(#[from] urs_taxid::Error),
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Raw {
    pub id: usize,
    pub base: Basic,
    pub crs: Vec<Crs>,
    pub feedback: Vec<Feedback>,
    pub go_annotations: Vec<GoAnnotation>,
    pub interacting_proteins: Vec<InteractingProtein>,
    pub interacting_rnas: Vec<InteractingRna>,
    pub precompute: Precompute,
    pub qa_status: QaStatus,
    pub r2dt: Option<R2dt>,
    pub rfam_hits: Vec<RfamHit>,
    pub so_tree: so_tree::SoTree,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Normalized {
    urs: String,
    taxid: usize,
    urs_taxid: String,
    short_urs: String,
    deleted: String,

    so_rna_type_tree: so_tree::SoTree,

    #[serde(flatten)]
    pre_summary: PrecomputeSummary,

    #[serde(flatten)]
    basic: Basic,

    // #[serde(flatten)]
    // dates: Dates,
    qa_status: QaStatus,

    secondary: Option<R2dt>,

    #[serde(flatten)]
    accessions: AccessionVec,
    cross_references: Vec<CrossReference>,
    crs: CrsVec,
    overlaps: FeedbackVec,
    go_annotations: Vec<GoAnnotation>,

    interacting_proteins: Vec<InteractingProtein>,

    interacting_rnas: Vec<InteractingRna>,

    #[serde(flatten)]
    references: ReferenceVec,

    #[serde(flatten)]
    rfam_hits: RfamHitVec,
}

impl Raw {
    pub fn urs_taxid(&self) -> String {
        return self.base.urs_taxid.to_owned();
    }

    pub fn urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.to_string())
    }

    pub fn taxid(&self) -> Result<u64, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.taxid())
    }

    pub fn short_urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.short_urs())
    }

    pub fn short_urs_taxid(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.short())
    }
}

impl Normalized {
    pub fn new(raw: Raw, accessions: Vec<RawAccession>) -> Result<Self, NormalizationError> {
        let pre_summary = PrecomputeSummary::from(raw.precompute);
        let base = raw.base.clone();

        let urs_taxid = base.urs_taxid.to_owned();
        assert!(urs_taxid == accessions[0].urs_taxid);
        let parts: Vec<&str> = urs_taxid.split("_").collect();
        let urs = parts[0].to_owned();
        let taxid = parts[1].parse::<usize>().unwrap();
        let parsed: urs_taxid::UrsTaxid = urs_taxid.parse()?;
        let references = ReferenceVec::from_iter(accessions.clone());

        Ok(Self {
            urs_taxid,
            urs,
            taxid,
            short_urs: parsed.short(),
            deleted: String::from("N"),

            so_rna_type_tree: raw.so_tree,

            pre_summary,
            basic: base,
            qa_status: raw.qa_status,
            secondary: raw.r2dt,

            accessions: AccessionVec::from_iter(accessions.clone()),
            cross_references: accessions.into_iter().map(CrossReference::from).collect(),
            crs: CrsVec::from_iter(raw.crs.clone()),
            overlaps: FeedbackVec::from_iter(raw.feedback.clone()),
            go_annotations: raw.go_annotations.clone(),
            interacting_proteins: raw.interacting_proteins,
            interacting_rnas: raw.interacting_rnas,
            references,
            rfam_hits: RfamHitVec::from_iter(raw.rfam_hits.clone()),
        })
    }
}
<commit_msg>Improve error message<commit_after>use std::iter::FromIterator;

use serde::{
    Deserialize,
    Serialize,
};

use thiserror::Error;

use rnc_core::{
    urs,
    urs_taxid,
};

use crate::normalize::utils;

use crate::normalize::ds::{
    accession::{
        AccessionVec,
        CrossReference,
        RawAccession,
        ReferenceVec,
    },
    basic::Basic,
    crs::{
        Crs,
        CrsVec,
    },
    feedback::{
        Feedback,
        FeedbackVec,
    },
    go_annotation::GoAnnotation,
    interacting_protein::InteractingProtein,
    interacting_rna::InteractingRna,
    precompute::{
        Precompute,
        PrecomputeSummary,
    },
    qa_status::QaStatus,
    r2dt::R2dt,
    rfam_hit::{
        RfamHit,
        RfamHitVec,
    },
    so_tree,
};

#[derive(Error, Debug)]
pub enum NormalizationError {
    #[error("Could not ungroup {0}")]
    CountError(#[from] utils::Error),

    #[error("Could not parse {0}")]
    UrsParsingError(#[from] urs::Error),

    #[error("Could not parse {0}")]
    UrsTaxidParsingError(#[from] urs_taxid::Error),
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Raw {
    pub id: usize,
    pub base: Basic,
    pub crs: Vec<Crs>,
    pub feedback: Vec<Feedback>,
    pub go_annotations: Vec<GoAnnotation>,
    pub interacting_proteins: Vec<InteractingProtein>,
    pub interacting_rnas: Vec<InteractingRna>,
    pub precompute: Precompute,
    pub qa_status: QaStatus,
    pub r2dt: Option<R2dt>,
    pub rfam_hits: Vec<RfamHit>,
    pub so_tree: so_tree::SoTree,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Normalized {
    urs: String,
    taxid: usize,
    urs_taxid: String,
    short_urs: String,
    deleted: String,

    so_rna_type_tree: so_tree::SoTree,

    #[serde(flatten)]
    pre_summary: PrecomputeSummary,

    #[serde(flatten)]
    basic: Basic,

    // #[serde(flatten)]
    // dates: Dates,
    qa_status: QaStatus,

    secondary: Option<R2dt>,

    #[serde(flatten)]
    accessions: AccessionVec,
    cross_references: Vec<CrossReference>,
    crs: CrsVec,
    overlaps: FeedbackVec,
    go_annotations: Vec<GoAnnotation>,

    interacting_proteins: Vec<InteractingProtein>,

    interacting_rnas: Vec<InteractingRna>,

    #[serde(flatten)]
    references: ReferenceVec,

    #[serde(flatten)]
    rfam_hits: RfamHitVec,
}

impl Raw {
    pub fn urs_taxid(&self) -> String {
        return self.base.urs_taxid.to_owned();
    }

    pub fn urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.to_string())
    }

    pub fn taxid(&self) -> Result<u64, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.taxid())
    }

    pub fn short_urs(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        let urs: urs::Urs = ut.into();
        Ok(urs.short_urs())
    }

    pub fn short_urs_taxid(&self) -> Result<String, urs_taxid::Error> {
        let ut: urs_taxid::UrsTaxid = self.urs_taxid().parse()?;
        Ok(ut.short())
    }
}

impl Normalized {
    pub fn new(raw: Raw, accessions: Vec<RawAccession>) -> Result<Self, NormalizationError> {
        let pre_summary = PrecomputeSummary::from(raw.precompute);
        let base = raw.base.clone();

        let urs_taxid = base.urs_taxid.to_owned();
        assert!(
            urs_taxid == accessions[0].urs_taxid,
            "Accession urs {} and base urs {} disagree for id {}",
            accessions[0].urs_taxid,
            urs_taxid,
            base.id
        );
        let parts: Vec<&str> = urs_taxid.split("_").collect();
        let urs = parts[0].to_owned();
        let taxid = parts[1].parse::<usize>().unwrap();
        let parsed: urs_taxid::UrsTaxid = urs_taxid.parse()?;
        let references = ReferenceVec::from_iter(accessions.clone());

        Ok(Self {
            urs_taxid,
            urs,
            taxid,
            short_urs: parsed.short(),
            deleted: String::from("N"),

            so_rna_type_tree: raw.so_tree,

            pre_summary,
            basic: base,
            qa_status: raw.qa_status,
            secondary: raw.r2dt,

            accessions: AccessionVec::from_iter(accessions.clone()),
            cross_references: accessions.into_iter().map(CrossReference::from).collect(),
            crs: CrsVec::from_iter(raw.crs.clone()),
            overlaps: FeedbackVec::from_iter(raw.feedback.clone()),
            go_annotations: raw.go_annotations.clone(),
            interacting_proteins: raw.interacting_proteins,
            interacting_rnas: raw.interacting_rnas,
            references,
            rfam_hits: RfamHitVec::from_iter(raw.rfam_hits.clone()),
        })
    }
}
<|endoftext|>


<commit_before>// vim: tw=80
//! A struct with a constructor method
#![deny(warnings)]

use mockall::*;

pub struct A {}

#[automock]
impl A {
    pub fn new() -> Self {
        unimplemented!()
    }
}

#[test]
fn returning() {
    let ctx = MockA::new_context();
    ctx.expect().returning(MockA::default);
    let _a: MockA = MockA::new();
}
<commit_msg>Fix a Clippy lint on the latest nightly<commit_after>// vim: tw=80
//! A struct with a constructor method
#![deny(warnings)]

use mockall::*;

pub struct A {}

#[automock]
#[allow(clippy::new_without_default)]
impl A {
    pub fn new() -> Self {
        unimplemented!()
    }
}

#[test]
fn returning() {
    let ctx = MockA::new_context();
    ctx.expect().returning(MockA::default);
    let _a: MockA = MockA::new();
}
<|endoftext|>


<commit_before>//! This module contains types and functions to support formatting specific line ranges.

use itertools::Itertools;
use std::collections::HashMap;
use std::path::PathBuf;
use std::{cmp, fmt, iter, str};

use rustc_data_structures::sync::Lrc;
use rustc_span::{self, SourceFile};
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
use serde_json as json;
use thiserror::Error;

/// A range of lines in a file, inclusive of both ends.
pub struct LineRange {
    pub file: Lrc<SourceFile>,
    pub lo: usize,
    pub hi: usize,
}

/// Defines the name of an input - either a file or stdin.
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum FileName {
    Real(PathBuf),
    Stdin,
}

impl From<rustc_span::FileName> for FileName {
    fn from(name: rustc_span::FileName) -> FileName {
        match name {
            rustc_span::FileName::Real(p) => FileName::Real(p.into_local_path()),
            rustc_span::FileName::Custom(ref f) if f == "stdin" => FileName::Stdin,
            _ => unreachable!(),
        }
    }
}

impl fmt::Display for FileName {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FileName::Real(p) => write!(f, "{}", p.to_str().unwrap()),
            FileName::Stdin => write!(f, "stdin"),
        }
    }
}

impl<'de> Deserialize<'de> for FileName {
    fn deserialize<D>(deserializer: D) -> Result<FileName, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        if s == "stdin" {
            Ok(FileName::Stdin)
        } else {
            Ok(FileName::Real(s.into()))
        }
    }
}

impl Serialize for FileName {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let s = match self {
            FileName::Stdin => Ok("stdin"),
            FileName::Real(path) => path
                .to_str()
                .ok_or_else(|| ser::Error::custom("path can't be serialized as UTF-8 string")),
        };

        s.and_then(|s| serializer.serialize_str(s))
    }
}

impl LineRange {
    pub fn file_name(&self) -> FileName {
        self.file.name.clone().into()
    }
}

/// A range that is inclusive of both ends.
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, Deserialize)]
pub struct Range {
    lo: usize,
    hi: usize,
}

impl<'a> From<&'a LineRange> for Range {
    fn from(range: &'a LineRange) -> Range {
        Range::new(range.lo, range.hi)
    }
}

impl fmt::Display for Range {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}..{}", self.lo, self.hi)
    }
}

impl Range {
    pub fn new(lo: usize, hi: usize) -> Range {
        Range { lo, hi }
    }

    fn is_empty(self) -> bool {
        self.lo > self.hi
    }

    #[allow(dead_code)]
    fn contains(self, other: Range) -> bool {
        if other.is_empty() {
            true
        } else {
            !self.is_empty() && self.lo <= other.lo && self.hi >= other.hi
        }
    }

    fn intersects(self, other: Range) -> bool {
        if self.is_empty() || other.is_empty() {
            false
        } else {
            (self.lo <= other.hi && other.hi <= self.hi)
                || (other.lo <= self.hi && self.hi <= other.hi)
        }
    }

    fn adjacent_to(self, other: Range) -> bool {
        if self.is_empty() || other.is_empty() {
            false
        } else {
            self.hi + 1 == other.lo || other.hi + 1 == self.lo
        }
    }

    /// Returns a new `Range` with lines from `self` and `other` if they were adjacent or
    /// intersect; returns `None` otherwise.
    fn merge(self, other: Range) -> Option<Range> {
        if self.adjacent_to(other) || self.intersects(other) {
            Some(Range::new(
                cmp::min(self.lo, other.lo),
                cmp::max(self.hi, other.hi),
            ))
        } else {
            None
        }
    }
}

/// A set of lines in files.
///
/// It is represented as a multimap keyed on file names, with values a collection of
/// non-overlapping ranges sorted by their start point. An inner `None` is interpreted to mean all
/// lines in all files.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FileLines(Option<HashMap<FileName, Vec<Range>>>);

impl fmt::Display for FileLines {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self.0 {
            None => write!(f, "None")?,
            Some(map) => {
                for (file_name, ranges) in map.iter() {
                    write!(f, "{}: ", file_name)?;
                    write!(f, "{}\n", ranges.iter().format(", "))?;
                }
            }
        };
        Ok(())
    }
}

/// Normalizes the ranges so that the invariants for `FileLines` hold: ranges are non-overlapping,
/// and ordered by their start point.
fn normalize_ranges(ranges: &mut HashMap<FileName, Vec<Range>>) {
    for ranges in ranges.values_mut() {
        ranges.sort();
        let mut result = vec![];
        let mut iter = ranges.iter_mut().peekable();
        while let Some(next) = iter.next() {
            let mut next = *next;
            while let Some(&&mut peek) = iter.peek() {
                if let Some(merged) = next.merge(peek) {
                    iter.next().unwrap();
                    next = merged;
                } else {
                    break;
                }
            }
            result.push(next)
        }
        *ranges = result;
    }
}

impl FileLines {
    /// Creates a `FileLines` that contains all lines in all files.
    pub(crate) fn all() -> FileLines {
        FileLines(None)
    }

    /// Returns `true` if this `FileLines` contains all lines in all files.
    pub(crate) fn is_all(&self) -> bool {
        self.0.is_none()
    }

    pub fn from_ranges(mut ranges: HashMap<FileName, Vec<Range>>) -> FileLines {
        normalize_ranges(&mut ranges);
        FileLines(Some(ranges))
    }

    /// Returns an iterator over the files contained in `self`.
    pub fn files(&self) -> Files<'_> {
        Files(self.0.as_ref().map(HashMap::keys))
    }

    /// Returns JSON representation as accepted by the `--file-lines JSON` arg.
    pub fn to_json_spans(&self) -> Vec<JsonSpan> {
        match &self.0 {
            None => vec![],
            Some(file_ranges) => file_ranges
                .iter()
                .flat_map(|(file, ranges)| ranges.iter().map(move |r| (file, r)))
                .map(|(file, range)| JsonSpan {
                    file: file.to_owned(),
                    range: (range.lo, range.hi),
                })
                .collect(),
        }
    }

    /// Returns `true` if `self` includes all lines in all files. Otherwise runs `f` on all ranges
    /// in the designated file (if any) and returns true if `f` ever does.
    fn file_range_matches<F>(&self, file_name: &FileName, f: F) -> bool
    where
        F: FnMut(&Range) -> bool,
    {
        let map = match self.0 {
            // `None` means "all lines in all files".
            None => return true,
            Some(ref map) => map,
        };

        match canonicalize_path_string(file_name).and_then(|file| map.get(&file)) {
            Some(ranges) => ranges.iter().any(f),
            None => false,
        }
    }

    /// Returns `true` if `range` is fully contained in `self`.
    #[allow(dead_code)]
    pub(crate) fn contains(&self, range: &LineRange) -> bool {
        self.file_range_matches(&range.file_name(), |r| r.contains(Range::from(range)))
    }

    /// Returns `true` if any lines in `range` are in `self`.
    pub(crate) fn intersects(&self, range: &LineRange) -> bool {
        self.file_range_matches(&range.file_name(), |r| r.intersects(Range::from(range)))
    }

    /// Returns `true` if `line` from `file_name` is in `self`.
    pub(crate) fn contains_line(&self, file_name: &FileName, line: usize) -> bool {
        self.file_range_matches(file_name, |r| r.lo <= line && r.hi >= line)
    }

    /// Returns `true` if all the lines between `lo` and `hi` from `file_name` are in `self`.
    pub(crate) fn contains_range(&self, file_name: &FileName, lo: usize, hi: usize) -> bool {
        self.file_range_matches(file_name, |r| r.contains(Range::new(lo, hi)))
    }
}

/// `FileLines` files iterator.
pub struct Files<'a>(Option<::std::collections::hash_map::Keys<'a, FileName, Vec<Range>>>);

impl<'a> iter::Iterator for Files<'a> {
    type Item = &'a FileName;

    fn next(&mut self) -> Option<&'a FileName> {
        self.0.as_mut().and_then(Iterator::next)
    }
}

fn canonicalize_path_string(file: &FileName) -> Option<FileName> {
    match *file {
        FileName::Real(ref path) => path.canonicalize().ok().map(FileName::Real),
        _ => Some(file.clone()),
    }
}

#[derive(Error, Debug)]
pub enum FileLinesError {
    #[error("{0}")]
    Json(json::Error),
    #[error("Can't canonicalize {0}")]
    CannotCanonicalize(FileName),
}

// This impl is needed for `Config::override_value` to work for use in tests.
impl str::FromStr for FileLines {
    type Err = FileLinesError;

    fn from_str(s: &str) -> Result<FileLines, Self::Err> {
        let v: Vec<JsonSpan> = json::from_str(s).map_err(FileLinesError::Json)?;
        let mut m = HashMap::new();
        for js in v {
            let (s, r) = JsonSpan::into_tuple(js)?;
            m.entry(s).or_insert_with(|| vec![]).push(r);
        }
        Ok(FileLines::from_ranges(m))
    }
}

// For JSON decoding.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)]
pub struct JsonSpan {
    file: FileName,
    range: (usize, usize),
}

impl JsonSpan {
    fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> {
        let (lo, hi) = self.range;
        let canonical = canonicalize_path_string(&self.file)
            .ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?;
        Ok((canonical, Range::new(lo, hi)))
    }
}

// This impl is needed for inclusion in the `Config` struct. We don't have a toml representation
// for `FileLines`, so it will just panic instead.
impl<'de> ::serde::de::Deserialize<'de> for FileLines {
    fn deserialize<D>(_: D) -> Result<Self, D::Error>
    where
        D: ::serde::de::Deserializer<'de>,
    {
        panic!(
            "FileLines cannot be deserialized from a project rustfmt.toml file: please \
             specify it via the `--file-lines` option instead"
        );
    }
}

// We also want to avoid attempting to serialize a FileLines to toml. The
// `Config` struct should ensure this impl is never reached.
impl ::serde::ser::Serialize for FileLines {
    fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
    where
        S: ::serde::ser::Serializer,
    {
        unreachable!("FileLines cannot be serialized. This is a rustfmt bug.");
    }
}

#[cfg(test)]
mod test {
    use super::Range;

    #[test]
    fn test_range_intersects() {
        assert!(Range::new(1, 2).intersects(Range::new(1, 1)));
        assert!(Range::new(1, 2).intersects(Range::new(2, 2)));
        assert!(!Range::new(1, 2).intersects(Range::new(0, 0)));
        assert!(!Range::new(1, 2).intersects(Range::new(3, 10)));
        assert!(!Range::new(1, 3).intersects(Range::new(5, 5)));
    }

    #[test]
    fn test_range_adjacent_to() {
        assert!(!Range::new(1, 2).adjacent_to(Range::new(1, 1)));
        assert!(!Range::new(1, 2).adjacent_to(Range::new(2, 2)));
        assert!(Range::new(1, 2).adjacent_to(Range::new(0, 0)));
        assert!(Range::new(1, 2).adjacent_to(Range::new(3, 10)));
        assert!(!Range::new(1, 3).adjacent_to(Range::new(5, 5)));
    }

    #[test]
    fn test_range_contains() {
        assert!(Range::new(1, 2).contains(Range::new(1, 1)));
        assert!(Range::new(1, 2).contains(Range::new(2, 2)));
        assert!(!Range::new(1, 2).contains(Range::new(0, 0)));
        assert!(!Range::new(1, 2).contains(Range::new(3, 10)));
    }

    #[test]
    fn test_range_merge() {
        assert_eq!(None, Range::new(1, 3).merge(Range::new(5, 5)));
        assert_eq!(None, Range::new(4, 7).merge(Range::new(0, 1)));
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 5).merge(Range::new(4, 7))
        );
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 5).merge(Range::new(5, 7))
        );
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 5).merge(Range::new(6, 7))
        );
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 7).merge(Range::new(4, 5))
        );
    }

    use super::json::{self, json};
    use super::{FileLines, FileName};
    use std::{collections::HashMap, path::PathBuf};

    #[test]
    fn file_lines_to_json() {
        let ranges: HashMap<FileName, Vec<Range>> = [
            (
                FileName::Real(PathBuf::from("src/main.rs")),
                vec![Range::new(1, 3), Range::new(5, 7)],
            ),
            (
                FileName::Real(PathBuf::from("src/lib.rs")),
                vec![Range::new(1, 7)],
            ),
        ]
        .iter()
        .cloned()
        .collect();

        let file_lines = FileLines::from_ranges(ranges);
        let mut spans = file_lines.to_json_spans();
        spans.sort();
        let json = json::to_value(&spans).unwrap();
        assert_eq!(
            json,
            json! {[
                {"file": "src/lib.rs",  "range": [1, 7]},
                {"file": "src/main.rs", "range": [1, 3]},
                {"file": "src/main.rs", "range": [5, 7]},
            ]}
        );
    }
}
<commit_msg>Only deal with LocalPath in conversion<commit_after>//! This module contains types and functions to support formatting specific line ranges.

use itertools::Itertools;
use std::collections::HashMap;
use std::path::PathBuf;
use std::{cmp, fmt, iter, str};

use rustc_data_structures::sync::Lrc;
use rustc_span::{self, SourceFile};
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
use serde_json as json;
use thiserror::Error;

/// A range of lines in a file, inclusive of both ends.
pub struct LineRange {
    pub file: Lrc<SourceFile>,
    pub lo: usize,
    pub hi: usize,
}

/// Defines the name of an input - either a file or stdin.
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum FileName {
    Real(PathBuf),
    Stdin,
}

impl From<rustc_span::FileName> for FileName {
    fn from(name: rustc_span::FileName) -> FileName {
        match name {
            rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(p)) => FileName::Real(p),
            rustc_span::FileName::Custom(ref f) if f == "stdin" => FileName::Stdin,
            _ => unreachable!(),
        }
    }
}

impl fmt::Display for FileName {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FileName::Real(p) => write!(f, "{}", p.to_str().unwrap()),
            FileName::Stdin => write!(f, "stdin"),
        }
    }
}

impl<'de> Deserialize<'de> for FileName {
    fn deserialize<D>(deserializer: D) -> Result<FileName, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        if s == "stdin" {
            Ok(FileName::Stdin)
        } else {
            Ok(FileName::Real(s.into()))
        }
    }
}

impl Serialize for FileName {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let s = match self {
            FileName::Stdin => Ok("stdin"),
            FileName::Real(path) => path
                .to_str()
                .ok_or_else(|| ser::Error::custom("path can't be serialized as UTF-8 string")),
        };

        s.and_then(|s| serializer.serialize_str(s))
    }
}

impl LineRange {
    pub fn file_name(&self) -> FileName {
        self.file.name.clone().into()
    }
}

/// A range that is inclusive of both ends.
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, Deserialize)]
pub struct Range {
    lo: usize,
    hi: usize,
}

impl<'a> From<&'a LineRange> for Range {
    fn from(range: &'a LineRange) -> Range {
        Range::new(range.lo, range.hi)
    }
}

impl fmt::Display for Range {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}..{}", self.lo, self.hi)
    }
}

impl Range {
    pub fn new(lo: usize, hi: usize) -> Range {
        Range { lo, hi }
    }

    fn is_empty(self) -> bool {
        self.lo > self.hi
    }

    #[allow(dead_code)]
    fn contains(self, other: Range) -> bool {
        if other.is_empty() {
            true
        } else {
            !self.is_empty() && self.lo <= other.lo && self.hi >= other.hi
        }
    }

    fn intersects(self, other: Range) -> bool {
        if self.is_empty() || other.is_empty() {
            false
        } else {
            (self.lo <= other.hi && other.hi <= self.hi)
                || (other.lo <= self.hi && self.hi <= other.hi)
        }
    }

    fn adjacent_to(self, other: Range) -> bool {
        if self.is_empty() || other.is_empty() {
            false
        } else {
            self.hi + 1 == other.lo || other.hi + 1 == self.lo
        }
    }

    /// Returns a new `Range` with lines from `self` and `other` if they were adjacent or
    /// intersect; returns `None` otherwise.
    fn merge(self, other: Range) -> Option<Range> {
        if self.adjacent_to(other) || self.intersects(other) {
            Some(Range::new(
                cmp::min(self.lo, other.lo),
                cmp::max(self.hi, other.hi),
            ))
        } else {
            None
        }
    }
}

/// A set of lines in files.
///
/// It is represented as a multimap keyed on file names, with values a collection of
/// non-overlapping ranges sorted by their start point. An inner `None` is interpreted to mean all
/// lines in all files.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FileLines(Option<HashMap<FileName, Vec<Range>>>);

impl fmt::Display for FileLines {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self.0 {
            None => write!(f, "None")?,
            Some(map) => {
                for (file_name, ranges) in map.iter() {
                    write!(f, "{}: ", file_name)?;
                    write!(f, "{}\n", ranges.iter().format(", "))?;
                }
            }
        };
        Ok(())
    }
}

/// Normalizes the ranges so that the invariants for `FileLines` hold: ranges are non-overlapping,
/// and ordered by their start point.
fn normalize_ranges(ranges: &mut HashMap<FileName, Vec<Range>>) {
    for ranges in ranges.values_mut() {
        ranges.sort();
        let mut result = vec![];
        let mut iter = ranges.iter_mut().peekable();
        while let Some(next) = iter.next() {
            let mut next = *next;
            while let Some(&&mut peek) = iter.peek() {
                if let Some(merged) = next.merge(peek) {
                    iter.next().unwrap();
                    next = merged;
                } else {
                    break;
                }
            }
            result.push(next)
        }
        *ranges = result;
    }
}

impl FileLines {
    /// Creates a `FileLines` that contains all lines in all files.
    pub(crate) fn all() -> FileLines {
        FileLines(None)
    }

    /// Returns `true` if this `FileLines` contains all lines in all files.
    pub(crate) fn is_all(&self) -> bool {
        self.0.is_none()
    }

    pub fn from_ranges(mut ranges: HashMap<FileName, Vec<Range>>) -> FileLines {
        normalize_ranges(&mut ranges);
        FileLines(Some(ranges))
    }

    /// Returns an iterator over the files contained in `self`.
    pub fn files(&self) -> Files<'_> {
        Files(self.0.as_ref().map(HashMap::keys))
    }

    /// Returns JSON representation as accepted by the `--file-lines JSON` arg.
    pub fn to_json_spans(&self) -> Vec<JsonSpan> {
        match &self.0 {
            None => vec![],
            Some(file_ranges) => file_ranges
                .iter()
                .flat_map(|(file, ranges)| ranges.iter().map(move |r| (file, r)))
                .map(|(file, range)| JsonSpan {
                    file: file.to_owned(),
                    range: (range.lo, range.hi),
                })
                .collect(),
        }
    }

    /// Returns `true` if `self` includes all lines in all files. Otherwise runs `f` on all ranges
    /// in the designated file (if any) and returns true if `f` ever does.
    fn file_range_matches<F>(&self, file_name: &FileName, f: F) -> bool
    where
        F: FnMut(&Range) -> bool,
    {
        let map = match self.0 {
            // `None` means "all lines in all files".
            None => return true,
            Some(ref map) => map,
        };

        match canonicalize_path_string(file_name).and_then(|file| map.get(&file)) {
            Some(ranges) => ranges.iter().any(f),
            None => false,
        }
    }

    /// Returns `true` if `range` is fully contained in `self`.
    #[allow(dead_code)]
    pub(crate) fn contains(&self, range: &LineRange) -> bool {
        self.file_range_matches(&range.file_name(), |r| r.contains(Range::from(range)))
    }

    /// Returns `true` if any lines in `range` are in `self`.
    pub(crate) fn intersects(&self, range: &LineRange) -> bool {
        self.file_range_matches(&range.file_name(), |r| r.intersects(Range::from(range)))
    }

    /// Returns `true` if `line` from `file_name` is in `self`.
    pub(crate) fn contains_line(&self, file_name: &FileName, line: usize) -> bool {
        self.file_range_matches(file_name, |r| r.lo <= line && r.hi >= line)
    }

    /// Returns `true` if all the lines between `lo` and `hi` from `file_name` are in `self`.
    pub(crate) fn contains_range(&self, file_name: &FileName, lo: usize, hi: usize) -> bool {
        self.file_range_matches(file_name, |r| r.contains(Range::new(lo, hi)))
    }
}

/// `FileLines` files iterator.
pub struct Files<'a>(Option<::std::collections::hash_map::Keys<'a, FileName, Vec<Range>>>);

impl<'a> iter::Iterator for Files<'a> {
    type Item = &'a FileName;

    fn next(&mut self) -> Option<&'a FileName> {
        self.0.as_mut().and_then(Iterator::next)
    }
}

fn canonicalize_path_string(file: &FileName) -> Option<FileName> {
    match *file {
        FileName::Real(ref path) => path.canonicalize().ok().map(FileName::Real),
        _ => Some(file.clone()),
    }
}

#[derive(Error, Debug)]
pub enum FileLinesError {
    #[error("{0}")]
    Json(json::Error),
    #[error("Can't canonicalize {0}")]
    CannotCanonicalize(FileName),
}

// This impl is needed for `Config::override_value` to work for use in tests.
impl str::FromStr for FileLines {
    type Err = FileLinesError;

    fn from_str(s: &str) -> Result<FileLines, Self::Err> {
        let v: Vec<JsonSpan> = json::from_str(s).map_err(FileLinesError::Json)?;
        let mut m = HashMap::new();
        for js in v {
            let (s, r) = JsonSpan::into_tuple(js)?;
            m.entry(s).or_insert_with(|| vec![]).push(r);
        }
        Ok(FileLines::from_ranges(m))
    }
}

// For JSON decoding.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)]
pub struct JsonSpan {
    file: FileName,
    range: (usize, usize),
}

impl JsonSpan {
    fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> {
        let (lo, hi) = self.range;
        let canonical = canonicalize_path_string(&self.file)
            .ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?;
        Ok((canonical, Range::new(lo, hi)))
    }
}

// This impl is needed for inclusion in the `Config` struct. We don't have a toml representation
// for `FileLines`, so it will just panic instead.
impl<'de> ::serde::de::Deserialize<'de> for FileLines {
    fn deserialize<D>(_: D) -> Result<Self, D::Error>
    where
        D: ::serde::de::Deserializer<'de>,
    {
        panic!(
            "FileLines cannot be deserialized from a project rustfmt.toml file: please \
             specify it via the `--file-lines` option instead"
        );
    }
}

// We also want to avoid attempting to serialize a FileLines to toml. The
// `Config` struct should ensure this impl is never reached.
impl ::serde::ser::Serialize for FileLines {
    fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
    where
        S: ::serde::ser::Serializer,
    {
        unreachable!("FileLines cannot be serialized. This is a rustfmt bug.");
    }
}

#[cfg(test)]
mod test {
    use super::Range;

    #[test]
    fn test_range_intersects() {
        assert!(Range::new(1, 2).intersects(Range::new(1, 1)));
        assert!(Range::new(1, 2).intersects(Range::new(2, 2)));
        assert!(!Range::new(1, 2).intersects(Range::new(0, 0)));
        assert!(!Range::new(1, 2).intersects(Range::new(3, 10)));
        assert!(!Range::new(1, 3).intersects(Range::new(5, 5)));
    }

    #[test]
    fn test_range_adjacent_to() {
        assert!(!Range::new(1, 2).adjacent_to(Range::new(1, 1)));
        assert!(!Range::new(1, 2).adjacent_to(Range::new(2, 2)));
        assert!(Range::new(1, 2).adjacent_to(Range::new(0, 0)));
        assert!(Range::new(1, 2).adjacent_to(Range::new(3, 10)));
        assert!(!Range::new(1, 3).adjacent_to(Range::new(5, 5)));
    }

    #[test]
    fn test_range_contains() {
        assert!(Range::new(1, 2).contains(Range::new(1, 1)));
        assert!(Range::new(1, 2).contains(Range::new(2, 2)));
        assert!(!Range::new(1, 2).contains(Range::new(0, 0)));
        assert!(!Range::new(1, 2).contains(Range::new(3, 10)));
    }

    #[test]
    fn test_range_merge() {
        assert_eq!(None, Range::new(1, 3).merge(Range::new(5, 5)));
        assert_eq!(None, Range::new(4, 7).merge(Range::new(0, 1)));
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 5).merge(Range::new(4, 7))
        );
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 5).merge(Range::new(5, 7))
        );
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 5).merge(Range::new(6, 7))
        );
        assert_eq!(
            Some(Range::new(3, 7)),
            Range::new(3, 7).merge(Range::new(4, 5))
        );
    }

    use super::json::{self, json};
    use super::{FileLines, FileName};
    use std::{collections::HashMap, path::PathBuf};

    #[test]
    fn file_lines_to_json() {
        let ranges: HashMap<FileName, Vec<Range>> = [
            (
                FileName::Real(PathBuf::from("src/main.rs")),
                vec![Range::new(1, 3), Range::new(5, 7)],
            ),
            (
                FileName::Real(PathBuf::from("src/lib.rs")),
                vec![Range::new(1, 7)],
            ),
        ]
        .iter()
        .cloned()
        .collect();

        let file_lines = FileLines::from_ranges(ranges);
        let mut spans = file_lines.to_json_spans();
        spans.sort();
        let json = json::to_value(&spans).unwrap();
        assert_eq!(
            json,
            json! {[
                {"file": "src/lib.rs",  "range": [1, 7]},
                {"file": "src/main.rs", "range": [1, 3]},
                {"file": "src/main.rs", "range": [5, 7]},
            ]}
        );
    }
}
<|endoftext|>


<commit_before>use bytes::BytesMut;
use fallible_iterator::FallibleIterator;
use std::collections::HashMap;

use super::*;
use crate::IsNull;

#[test]
fn bool() {
    let mut buf = BytesMut::new();
    bool_to_sql(true, &mut buf);
    assert_eq!(bool_from_sql(&buf).unwrap(), true);

    let mut buf = BytesMut::new();
    bool_to_sql(false, &mut buf);
    assert_eq!(bool_from_sql(&buf).unwrap(), false);
}

#[test]
fn int2() {
    let mut buf = BytesMut::new();
    int2_to_sql(0x0102, &mut buf);
    assert_eq!(int2_from_sql(&buf).unwrap(), 0x0102);
}

#[test]
fn int4() {
    let mut buf = BytesMut::new();
    int4_to_sql(0x0102_0304, &mut buf);
    assert_eq!(int4_from_sql(&buf).unwrap(), 0x0102_0304);
}

#[test]
fn int8() {
    let mut buf = BytesMut::new();
    int8_to_sql(0x0102_0304_0506_0708, &mut buf);
    assert_eq!(int8_from_sql(&buf).unwrap(), 0x0102_0304_0506_0708);
}

#[test]
#[allow(clippy::float_cmp)]
fn float4() {
    let mut buf = BytesMut::new();
    float4_to_sql(10343.95, &mut buf);
    assert_eq!(float4_from_sql(&buf).unwrap(), 10343.95);
}

#[test]
#[allow(clippy::float_cmp)]
fn float8() {
    let mut buf = BytesMut::new();
    float8_to_sql(10343.95, &mut buf);
    assert_eq!(float8_from_sql(&buf).unwrap(), 10343.95);
}

#[test]
fn hstore() {
    let mut map = HashMap::new();
    map.insert("hello", Some("world"));
    map.insert("hola", None);

    let mut buf = BytesMut::new();
    hstore_to_sql(map.iter().map(|(&k, &v)| (k, v)), &mut buf).unwrap();
    assert_eq!(
        hstore_from_sql(&buf)
            .unwrap()
            .collect::<HashMap<_, _>>()
            .unwrap(),
        map
    );
}

#[test]
fn varbit() {
    let len = 12;
    let bits = [0b0010_1011, 0b0000_1111];

    let mut buf = BytesMut::new();
    varbit_to_sql(len, bits.iter().cloned(), &mut buf).unwrap();
    let out = varbit_from_sql(&buf).unwrap();
    assert_eq!(out.len(), len);
    assert_eq!(out.bytes(), bits);
}

#[test]
fn array() {
    let dimensions = [
        ArrayDimension {
            len: 1,
            lower_bound: 10,
        },
        ArrayDimension {
            len: 2,
            lower_bound: 0,
        },
    ];
    let values = [None, Some(&b"hello"[..])];

    let mut buf = BytesMut::new();
    array_to_sql(
        dimensions.iter().cloned(),
        10,
        values.iter().cloned(),
        |v, buf| match v {
            Some(v) => {
                buf.extend_from_slice(v);
                Ok(IsNull::No)
            }
            None => Ok(IsNull::Yes),
        },
        &mut buf,
    )
    .unwrap();

    let array = array_from_sql(&buf).unwrap();
    assert_eq!(array.has_nulls(), true);
    assert_eq!(array.element_type(), 10);
    assert_eq!(array.dimensions().collect::<Vec<_>>().unwrap(), dimensions);
    assert_eq!(array.values().collect::<Vec<_>>().unwrap(), values);
}

#[test]
fn non_null_array() {
    let dimensions = [
        ArrayDimension {
            len: 1,
            lower_bound: 10,
        },
        ArrayDimension {
            len: 2,
            lower_bound: 0,
        },
    ];
    let values = [Some(&b"hola"[..]), Some(&b"hello"[..])];

    let mut buf = BytesMut::new();
    array_to_sql(
        dimensions.iter().cloned(),
        10,
        values.iter().cloned(),
        |v, buf| match v {
            Some(v) => {
                buf.extend_from_slice(v);
                Ok(IsNull::No)
            }
            None => Ok(IsNull::Yes),
        },
        &mut buf,
    )
    .unwrap();

    let array = array_from_sql(&buf).unwrap();
    assert_eq!(array.has_nulls(), false);
    assert_eq!(array.element_type(), 10);
    assert_eq!(array.dimensions().collect::<Vec<_>>().unwrap(), dimensions);
    assert_eq!(array.values().collect::<Vec<_>>().unwrap(), values);
}
<commit_msg>fix clippy<commit_after>use bytes::BytesMut;
use fallible_iterator::FallibleIterator;
use std::collections::HashMap;

use super::*;
use crate::IsNull;

#[test]
#[allow(clippy::bool_assert_comparison)]
fn bool() {
    let mut buf = BytesMut::new();
    bool_to_sql(true, &mut buf);
    assert_eq!(bool_from_sql(&buf).unwrap(), true);

    let mut buf = BytesMut::new();
    bool_to_sql(false, &mut buf);
    assert_eq!(bool_from_sql(&buf).unwrap(), false);
}

#[test]
fn int2() {
    let mut buf = BytesMut::new();
    int2_to_sql(0x0102, &mut buf);
    assert_eq!(int2_from_sql(&buf).unwrap(), 0x0102);
}

#[test]
fn int4() {
    let mut buf = BytesMut::new();
    int4_to_sql(0x0102_0304, &mut buf);
    assert_eq!(int4_from_sql(&buf).unwrap(), 0x0102_0304);
}

#[test]
fn int8() {
    let mut buf = BytesMut::new();
    int8_to_sql(0x0102_0304_0506_0708, &mut buf);
    assert_eq!(int8_from_sql(&buf).unwrap(), 0x0102_0304_0506_0708);
}

#[test]
#[allow(clippy::float_cmp)]
fn float4() {
    let mut buf = BytesMut::new();
    float4_to_sql(10343.95, &mut buf);
    assert_eq!(float4_from_sql(&buf).unwrap(), 10343.95);
}

#[test]
#[allow(clippy::float_cmp)]
fn float8() {
    let mut buf = BytesMut::new();
    float8_to_sql(10343.95, &mut buf);
    assert_eq!(float8_from_sql(&buf).unwrap(), 10343.95);
}

#[test]
fn hstore() {
    let mut map = HashMap::new();
    map.insert("hello", Some("world"));
    map.insert("hola", None);

    let mut buf = BytesMut::new();
    hstore_to_sql(map.iter().map(|(&k, &v)| (k, v)), &mut buf).unwrap();
    assert_eq!(
        hstore_from_sql(&buf)
            .unwrap()
            .collect::<HashMap<_, _>>()
            .unwrap(),
        map
    );
}

#[test]
fn varbit() {
    let len = 12;
    let bits = [0b0010_1011, 0b0000_1111];

    let mut buf = BytesMut::new();
    varbit_to_sql(len, bits.iter().cloned(), &mut buf).unwrap();
    let out = varbit_from_sql(&buf).unwrap();
    assert_eq!(out.len(), len);
    assert_eq!(out.bytes(), bits);
}

#[test]
fn array() {
    let dimensions = [
        ArrayDimension {
            len: 1,
            lower_bound: 10,
        },
        ArrayDimension {
            len: 2,
            lower_bound: 0,
        },
    ];
    let values = [None, Some(&b"hello"[..])];

    let mut buf = BytesMut::new();
    array_to_sql(
        dimensions.iter().cloned(),
        10,
        values.iter().cloned(),
        |v, buf| match v {
            Some(v) => {
                buf.extend_from_slice(v);
                Ok(IsNull::No)
            }
            None => Ok(IsNull::Yes),
        },
        &mut buf,
    )
    .unwrap();

    let array = array_from_sql(&buf).unwrap();
    assert!(array.has_nulls());
    assert_eq!(array.element_type(), 10);
    assert_eq!(array.dimensions().collect::<Vec<_>>().unwrap(), dimensions);
    assert_eq!(array.values().collect::<Vec<_>>().unwrap(), values);
}

#[test]
fn non_null_array() {
    let dimensions = [
        ArrayDimension {
            len: 1,
            lower_bound: 10,
        },
        ArrayDimension {
            len: 2,
            lower_bound: 0,
        },
    ];
    let values = [Some(&b"hola"[..]), Some(&b"hello"[..])];

    let mut buf = BytesMut::new();
    array_to_sql(
        dimensions.iter().cloned(),
        10,
        values.iter().cloned(),
        |v, buf| match v {
            Some(v) => {
                buf.extend_from_slice(v);
                Ok(IsNull::No)
            }
            None => Ok(IsNull::Yes),
        },
        &mut buf,
    )
    .unwrap();

    let array = array_from_sql(&buf).unwrap();
    assert!(array.has_nulls());
    assert_eq!(array.element_type(), 10);
    assert_eq!(array.dimensions().collect::<Vec<_>>().unwrap(), dimensions);
    assert_eq!(array.values().collect::<Vec<_>>().unwrap(), values);
}
<|endoftext|>


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

//! A graph module for use in dataflow, region resolution, and elsewhere.
//!
//! # Interface details
//!
//! You customize the graph by specifying a "node data" type `N` and an
//! "edge data" type `E`. You can then later gain access (mutable or
//! immutable) to these "user-data" bits. Currently, you can only add
//! nodes or edges to the graph. You cannot remove or modify them once
//! added. This could be changed if we have a need.
//!
//! # Implementation details
//!
//! The main tricky thing about this code is the way that edges are
//! stored. The edges are stored in a central array, but they are also
//! threaded onto two linked lists for each node, one for incoming edges
//! and one for outgoing edges. Note that every edge is a member of some
//! incoming list and some outgoing list.  Basically you can load the
//! first index of the linked list from the node data structures (the
//! field `first_edge`) and then, for each edge, load the next index from
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).

use bitvec::BitVector;
use std::fmt::Debug;
use std::usize;
use snapshot_vec::{SnapshotVec, SnapshotVecDelegate};

#[cfg(test)]
mod tests;

pub struct Graph<N, E> {
    nodes: SnapshotVec<Node<N>>,
    edges: SnapshotVec<Edge<E>>,
}

pub struct Node<N> {
    first_edge: [EdgeIndex; 2], // see module comment
    pub data: N,
}

#[derive(Debug)]
pub struct Edge<E> {
    next_edge: [EdgeIndex; 2], // see module comment
    source: NodeIndex,
    target: NodeIndex,
    pub data: E,
}

impl<N> SnapshotVecDelegate for Node<N> {
    type Value = Node<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Node<N>>, _: ()) {}
}

impl<N> SnapshotVecDelegate for Edge<N> {
    type Value = Edge<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Edge<N>>, _: ()) {}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct NodeIndex(pub usize);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct EdgeIndex(pub usize);

pub const INVALID_EDGE_INDEX: EdgeIndex = EdgeIndex(usize::MAX);

// Use a private field here to guarantee no more instances are created:
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Direction {
    repr: usize,
}

pub const OUTGOING: Direction = Direction { repr: 0 };

pub const INCOMING: Direction = Direction { repr: 1 };

impl NodeIndex {
    /// Returns unique id (unique with respect to the graph holding associated node).
    pub fn node_id(&self) -> usize {
        self.0
    }
}

impl<N: Debug, E: Debug> Graph<N, E> {
    pub fn new() -> Graph<N, E> {
        Graph {
            nodes: SnapshotVec::new(),
            edges: SnapshotVec::new(),
        }
    }

    pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
        Graph {
            nodes: SnapshotVec::with_capacity(nodes),
            edges: SnapshotVec::with_capacity(edges),
        }
    }

    // # Simple accessors

    #[inline]
    pub fn all_nodes(&self) -> &[Node<N>] {
        &self.nodes
    }

    #[inline]
    pub fn len_nodes(&self) -> usize {
        self.nodes.len()
    }

    #[inline]
    pub fn all_edges(&self) -> &[Edge<E>] {
        &self.edges
    }

    #[inline]
    pub fn len_edges(&self) -> usize {
        self.edges.len()
    }

    // # Node construction

    pub fn next_node_index(&self) -> NodeIndex {
        NodeIndex(self.nodes.len())
    }

    pub fn add_node(&mut self, data: N) -> NodeIndex {
        let idx = self.next_node_index();
        self.nodes.push(Node {
            first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
            data,
        });
        idx
    }

    pub fn mut_node_data(&mut self, idx: NodeIndex) -> &mut N {
        &mut self.nodes[idx.0].data
    }

    pub fn node_data(&self, idx: NodeIndex) -> &N {
        &self.nodes[idx.0].data
    }

    pub fn node(&self, idx: NodeIndex) -> &Node<N> {
        &self.nodes[idx.0]
    }

    // # Edge construction and queries

    pub fn next_edge_index(&self) -> EdgeIndex {
        EdgeIndex(self.edges.len())
    }

    pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex, data: E) -> EdgeIndex {
        debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);

        let idx = self.next_edge_index();

        // read current first of the list of edges from each node
        let source_first = self.nodes[source.0].first_edge[OUTGOING.repr];
        let target_first = self.nodes[target.0].first_edge[INCOMING.repr];

        // create the new edge, with the previous firsts from each node
        // as the next pointers
        self.edges.push(Edge {
            next_edge: [source_first, target_first],
            source,
            target,
            data,
        });

        // adjust the firsts for each node target be the next object.
        self.nodes[source.0].first_edge[OUTGOING.repr] = idx;
        self.nodes[target.0].first_edge[INCOMING.repr] = idx;

        return idx;
    }

    pub fn edge(&self, idx: EdgeIndex) -> &Edge<E> {
        &self.edges[idx.0]
    }

    // # Iterating over nodes, edges

    pub fn enumerated_nodes(&self) -> impl Iterator<Item = (NodeIndex, &Node<N>)> {
        self.nodes
            .iter()
            .enumerate()
            .map(|(idx, n)| (NodeIndex(idx), n))
    }

    pub fn enumerated_edges(&self) -> impl Iterator<Item = (EdgeIndex, &Edge<E>)> {
        self.edges
            .iter()
            .enumerate()
            .map(|(idx, e)| (EdgeIndex(idx), e))
    }

    pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node<N>) -> bool) -> bool
    {
        //! Iterates over all edges defined in the graph.
        self.enumerated_nodes().all(|(node_idx, node)| f(node_idx, node))
    }

    pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge<E>) -> bool) -> bool
    {
        //! Iterates over all edges defined in the graph
        self.enumerated_edges().all(|(edge_idx, edge)| f(edge_idx, edge))
    }

    pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, OUTGOING)
    }

    pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, INCOMING)
    }

    pub fn adjacent_edges(&self, source: NodeIndex, direction: Direction) -> AdjacentEdges<N, E> {
        let first_edge = self.node(source).first_edge[direction.repr];
        AdjacentEdges {
            graph: self,
            direction,
            next: first_edge,
        }
    }

    pub fn successor_nodes<'a>(
        &'a self,
        source: NodeIndex,
    ) -> impl Iterator<Item = NodeIndex> + 'a {
        self.outgoing_edges(source).targets()
    }

    pub fn predecessor_nodes<'a>(
        &'a self,
        target: NodeIndex,
    ) -> impl Iterator<Item = NodeIndex> + 'a {
        self.incoming_edges(target).sources()
    }

    pub fn depth_traverse<'a>(&'a self,
                              start: NodeIndex,
                              direction: Direction)
                              -> DepthFirstTraversal<'a, N, E> {
        DepthFirstTraversal::with_start_node(self, start, direction)
    }

    pub fn nodes_in_postorder<'a>(&'a self,
                                  direction: Direction,
                                  entry_node: NodeIndex)
                                  -> Vec<NodeIndex>
    {
        let mut visited = BitVector::new(self.len_nodes());
        let mut stack = vec![];
        let mut result = Vec::with_capacity(self.len_nodes());
        let mut push_node = |stack: &mut Vec<_>, node: NodeIndex| {
            if visited.insert(node.0) {
                stack.push((node, self.adjacent_edges(node, direction)));
            }
        };

        for node in Some(entry_node).into_iter()
            .chain(self.enumerated_nodes().map(|(node, _)| node))
        {
            push_node(&mut stack, node);
            while let Some((node, mut iter)) = stack.pop() {
                if let Some((_, child)) = iter.next() {
                    let target = child.source_or_target(direction);
                    // the current node needs more processing, so
                    // add it back to the stack
                    stack.push((node, iter));
                    // and then push the new node
                    push_node(&mut stack, target);
                } else {
                    result.push(node);
                }
            }
        }

        assert_eq!(result.len(), self.len_nodes());
        result
    }
}

// # Iterators

pub struct AdjacentEdges<'g, N, E>
    where N: 'g,
          E: 'g
{
    graph: &'g Graph<N, E>,
    direction: Direction,
    next: EdgeIndex,
}

impl<'g, N: Debug, E: Debug> AdjacentEdges<'g, N, E> {
    fn targets(self) -> impl Iterator<Item = NodeIndex> + 'g {
        self.into_iter().map(|(_, edge)| edge.target)
    }

    fn sources(self) -> impl Iterator<Item = NodeIndex> + 'g {
        self.into_iter().map(|(_, edge)| edge.source)
    }
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
    type Item = (EdgeIndex, &'g Edge<E>);

    fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<E>)> {
        let edge_index = self.next;
        if edge_index == INVALID_EDGE_INDEX {
            return None;
        }

        let edge = self.graph.edge(edge_index);
        self.next = edge.next_edge[self.direction.repr];
        Some((edge_index, edge))
    }
}

pub struct DepthFirstTraversal<'g, N, E>
    where N: 'g,
          E: 'g
{
    graph: &'g Graph<N, E>,
    stack: Vec<NodeIndex>,
    visited: BitVector,
    direction: Direction,
}

impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
    pub fn with_start_node(graph: &'g Graph<N, E>,
                           start_node: NodeIndex,
                           direction: Direction)
                           -> Self {
        let mut visited = BitVector::new(graph.len_nodes());
        visited.insert(start_node.node_id());
        DepthFirstTraversal {
            graph,
            stack: vec![start_node],
            visited,
            direction,
        }
    }

    fn visit(&mut self, node: NodeIndex) {
        if self.visited.insert(node.node_id()) {
            self.stack.push(node);
        }
    }
}

impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        let next = self.stack.pop();
        if let Some(idx) = next {
            for (_, edge) in self.graph.adjacent_edges(idx, self.direction) {
                let target = edge.source_or_target(self.direction);
                self.visit(target);
            }
        }
        next
    }
}

impl<E> Edge<E> {
    pub fn source(&self) -> NodeIndex {
        self.source
    }

    pub fn target(&self) -> NodeIndex {
        self.target
    }

    pub fn source_or_target(&self, direction: Direction) -> NodeIndex {
        if direction == OUTGOING {
            self.target
        } else {
            self.source
        }
    }
}
<commit_msg>Run rustfmt on `src/librustc_data_structures/graph/mod.rs`.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A graph module for use in dataflow, region resolution, and elsewhere.
//!
//! # Interface details
//!
//! You customize the graph by specifying a "node data" type `N` and an
//! "edge data" type `E`. You can then later gain access (mutable or
//! immutable) to these "user-data" bits. Currently, you can only add
//! nodes or edges to the graph. You cannot remove or modify them once
//! added. This could be changed if we have a need.
//!
//! # Implementation details
//!
//! The main tricky thing about this code is the way that edges are
//! stored. The edges are stored in a central array, but they are also
//! threaded onto two linked lists for each node, one for incoming edges
//! and one for outgoing edges. Note that every edge is a member of some
//! incoming list and some outgoing list.  Basically you can load the
//! first index of the linked list from the node data structures (the
//! field `first_edge`) and then, for each edge, load the next index from
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).

use bitvec::BitVector;
use std::fmt::Debug;
use std::usize;
use snapshot_vec::{SnapshotVec, SnapshotVecDelegate};

#[cfg(test)]
mod tests;

pub struct Graph<N, E> {
    nodes: SnapshotVec<Node<N>>,
    edges: SnapshotVec<Edge<E>>,
}

pub struct Node<N> {
    first_edge: [EdgeIndex; 2], // see module comment
    pub data: N,
}

#[derive(Debug)]
pub struct Edge<E> {
    next_edge: [EdgeIndex; 2], // see module comment
    source: NodeIndex,
    target: NodeIndex,
    pub data: E,
}

impl<N> SnapshotVecDelegate for Node<N> {
    type Value = Node<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Node<N>>, _: ()) {}
}

impl<N> SnapshotVecDelegate for Edge<N> {
    type Value = Edge<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Edge<N>>, _: ()) {}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct NodeIndex(pub usize);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct EdgeIndex(pub usize);

pub const INVALID_EDGE_INDEX: EdgeIndex = EdgeIndex(usize::MAX);

// Use a private field here to guarantee no more instances are created:
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Direction {
    repr: usize,
}

pub const OUTGOING: Direction = Direction { repr: 0 };

pub const INCOMING: Direction = Direction { repr: 1 };

impl NodeIndex {
    /// Returns unique id (unique with respect to the graph holding associated node).
    pub fn node_id(&self) -> usize {
        self.0
    }
}

impl<N: Debug, E: Debug> Graph<N, E> {
    pub fn new() -> Graph<N, E> {
        Graph {
            nodes: SnapshotVec::new(),
            edges: SnapshotVec::new(),
        }
    }

    pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
        Graph {
            nodes: SnapshotVec::with_capacity(nodes),
            edges: SnapshotVec::with_capacity(edges),
        }
    }

    // # Simple accessors

    #[inline]
    pub fn all_nodes(&self) -> &[Node<N>] {
        &self.nodes
    }

    #[inline]
    pub fn len_nodes(&self) -> usize {
        self.nodes.len()
    }

    #[inline]
    pub fn all_edges(&self) -> &[Edge<E>] {
        &self.edges
    }

    #[inline]
    pub fn len_edges(&self) -> usize {
        self.edges.len()
    }

    // # Node construction

    pub fn next_node_index(&self) -> NodeIndex {
        NodeIndex(self.nodes.len())
    }

    pub fn add_node(&mut self, data: N) -> NodeIndex {
        let idx = self.next_node_index();
        self.nodes.push(Node {
            first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
            data,
        });
        idx
    }

    pub fn mut_node_data(&mut self, idx: NodeIndex) -> &mut N {
        &mut self.nodes[idx.0].data
    }

    pub fn node_data(&self, idx: NodeIndex) -> &N {
        &self.nodes[idx.0].data
    }

    pub fn node(&self, idx: NodeIndex) -> &Node<N> {
        &self.nodes[idx.0]
    }

    // # Edge construction and queries

    pub fn next_edge_index(&self) -> EdgeIndex {
        EdgeIndex(self.edges.len())
    }

    pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex, data: E) -> EdgeIndex {
        debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);

        let idx = self.next_edge_index();

        // read current first of the list of edges from each node
        let source_first = self.nodes[source.0].first_edge[OUTGOING.repr];
        let target_first = self.nodes[target.0].first_edge[INCOMING.repr];

        // create the new edge, with the previous firsts from each node
        // as the next pointers
        self.edges.push(Edge {
            next_edge: [source_first, target_first],
            source,
            target,
            data,
        });

        // adjust the firsts for each node target be the next object.
        self.nodes[source.0].first_edge[OUTGOING.repr] = idx;
        self.nodes[target.0].first_edge[INCOMING.repr] = idx;

        return idx;
    }

    pub fn edge(&self, idx: EdgeIndex) -> &Edge<E> {
        &self.edges[idx.0]
    }

    // # Iterating over nodes, edges

    pub fn enumerated_nodes(&self) -> impl Iterator<Item = (NodeIndex, &Node<N>)> {
        self.nodes
            .iter()
            .enumerate()
            .map(|(idx, n)| (NodeIndex(idx), n))
    }

    pub fn enumerated_edges(&self) -> impl Iterator<Item = (EdgeIndex, &Edge<E>)> {
        self.edges
            .iter()
            .enumerate()
            .map(|(idx, e)| (EdgeIndex(idx), e))
    }

    pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node<N>) -> bool) -> bool {
        //! Iterates over all edges defined in the graph.
        self.enumerated_nodes()
            .all(|(node_idx, node)| f(node_idx, node))
    }

    pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge<E>) -> bool) -> bool {
        //! Iterates over all edges defined in the graph
        self.enumerated_edges()
            .all(|(edge_idx, edge)| f(edge_idx, edge))
    }

    pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, OUTGOING)
    }

    pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, INCOMING)
    }

    pub fn adjacent_edges(&self, source: NodeIndex, direction: Direction) -> AdjacentEdges<N, E> {
        let first_edge = self.node(source).first_edge[direction.repr];
        AdjacentEdges {
            graph: self,
            direction,
            next: first_edge,
        }
    }

    pub fn successor_nodes<'a>(
        &'a self,
        source: NodeIndex,
    ) -> impl Iterator<Item = NodeIndex> + 'a {
        self.outgoing_edges(source).targets()
    }

    pub fn predecessor_nodes<'a>(
        &'a self,
        target: NodeIndex,
    ) -> impl Iterator<Item = NodeIndex> + 'a {
        self.incoming_edges(target).sources()
    }

    pub fn depth_traverse<'a>(
        &'a self,
        start: NodeIndex,
        direction: Direction,
    ) -> DepthFirstTraversal<'a, N, E> {
        DepthFirstTraversal::with_start_node(self, start, direction)
    }

    pub fn nodes_in_postorder<'a>(
        &'a self,
        direction: Direction,
        entry_node: NodeIndex,
    ) -> Vec<NodeIndex> {
        let mut visited = BitVector::new(self.len_nodes());
        let mut stack = vec![];
        let mut result = Vec::with_capacity(self.len_nodes());
        let mut push_node = |stack: &mut Vec<_>, node: NodeIndex| {
            if visited.insert(node.0) {
                stack.push((node, self.adjacent_edges(node, direction)));
            }
        };

        for node in Some(entry_node)
            .into_iter()
            .chain(self.enumerated_nodes().map(|(node, _)| node))
        {
            push_node(&mut stack, node);
            while let Some((node, mut iter)) = stack.pop() {
                if let Some((_, child)) = iter.next() {
                    let target = child.source_or_target(direction);
                    // the current node needs more processing, so
                    // add it back to the stack
                    stack.push((node, iter));
                    // and then push the new node
                    push_node(&mut stack, target);
                } else {
                    result.push(node);
                }
            }
        }

        assert_eq!(result.len(), self.len_nodes());
        result
    }
}

// # Iterators

pub struct AdjacentEdges<'g, N, E>
where
    N: 'g,
    E: 'g,
{
    graph: &'g Graph<N, E>,
    direction: Direction,
    next: EdgeIndex,
}

impl<'g, N: Debug, E: Debug> AdjacentEdges<'g, N, E> {
    fn targets(self) -> impl Iterator<Item = NodeIndex> + 'g {
        self.into_iter().map(|(_, edge)| edge.target)
    }

    fn sources(self) -> impl Iterator<Item = NodeIndex> + 'g {
        self.into_iter().map(|(_, edge)| edge.source)
    }
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
    type Item = (EdgeIndex, &'g Edge<E>);

    fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<E>)> {
        let edge_index = self.next;
        if edge_index == INVALID_EDGE_INDEX {
            return None;
        }

        let edge = self.graph.edge(edge_index);
        self.next = edge.next_edge[self.direction.repr];
        Some((edge_index, edge))
    }
}

pub struct DepthFirstTraversal<'g, N, E>
where
    N: 'g,
    E: 'g,
{
    graph: &'g Graph<N, E>,
    stack: Vec<NodeIndex>,
    visited: BitVector,
    direction: Direction,
}

impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
    pub fn with_start_node(
        graph: &'g Graph<N, E>,
        start_node: NodeIndex,
        direction: Direction,
    ) -> Self {
        let mut visited = BitVector::new(graph.len_nodes());
        visited.insert(start_node.node_id());
        DepthFirstTraversal {
            graph,
            stack: vec![start_node],
            visited,
            direction,
        }
    }

    fn visit(&mut self, node: NodeIndex) {
        if self.visited.insert(node.node_id()) {
            self.stack.push(node);
        }
    }
}

impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        let next = self.stack.pop();
        if let Some(idx) = next {
            for (_, edge) in self.graph.adjacent_edges(idx, self.direction) {
                let target = edge.source_or_target(self.direction);
                self.visit(target);
            }
        }
        next
    }
}

impl<E> Edge<E> {
    pub fn source(&self) -> NodeIndex {
        self.source
    }

    pub fn target(&self) -> NodeIndex {
        self.target
    }

    pub fn source_or_target(&self, direction: Direction) -> NodeIndex {
        if direction == OUTGOING {
            self.target
        } else {
            self.source
        }
    }
}
<|endoftext|>


<commit_before>#[feature(globs)];
#[feature(macro_rules)];

extern mod wx;

use std::libc::*;
use std::rt::start_on_main_thread;
use std::vec;

use wx::defs::*;
use wx::native::*;
use wx::wrapper::*;

mod macros;

static nullptr: *mut c_void = 0 as *mut c_void;

wxApp!(wx_main)

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

struct MyButton(@wxButton);
impl MyButton {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton::clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
    #[fixed_stack_segment]
    #[inline(never)]
    fn clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
        println("hello!");
        let parent = wxWindow::from(data);
        let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", 0);
        msgDlg.showModal();
    }
}
<commit_msg>Specifya link_args for linking libwxc into test crate to fix master build.<commit_after>#[feature(globs)];
#[feature(macro_rules)];

#[link_args="-lwxc"];

extern mod wx;

use std::libc::*;
use std::rt::start_on_main_thread;
use std::vec;

use wx::defs::*;
use wx::native::*;
use wx::wrapper::*;

mod macros;

static nullptr: *mut c_void = 0 as *mut c_void;

wxApp!(wx_main)

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

struct MyButton(@wxButton);
impl MyButton {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton::clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
    #[fixed_stack_segment]
    #[inline(never)]
    fn clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
        println("hello!");
        let parent = wxWindow::from(data);
        let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", 0);
        msgDlg.showModal();
    }
}
<|endoftext|>