<commit_before>//! A simple library for parsing an XML file into an in-memory tree structure
//!
//! Not recommended for large XML files, as it will load the entire file into memory.
//!
//! # Example
//!
//! ```no_run
//! use xmltree::Element;
//! use std::fs::File;
//!
//! let data: &'static str = r##"
//! <?xml version="1.0" encoding="utf-8" standalone="yes"?>
//! <names>
//!     <name first="bob" last="jones" />
//!     <name first="elizabeth" last="smith" />
//! </names>
//! "##;
//!
//! let mut names_element = Element::parse(data.as_bytes()).unwrap();
//!
//! println!("{:#?}", names_element);
//! {
//!     // get first `name` element
//!     let name = names_element.get_mut_child("name").expect("Can't find name element");
//!     name.attributes.insert("suffix".to_owned(), "mr".to_owned());
//! }
//! names_element.write(File::create("result.xml").unwrap());
//!
//!
//! ```
extern crate xml;

use std::collections::HashMap;
use std::io::{Read, Write};
use std::borrow::Cow;
use std::fmt;

use xml::reader::{EventReader, XmlEvent};
pub use xml::namespace::Namespace;

/// Represents an XML element.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Element {
    /// This elements prefix, if any
    pub prefix: Option<String>,

    /// This elements namespace, if any
    pub namespace: Option<String>,

    /// The full list of namespaces, if any
    ///
    /// The `Namespace` type is exported from the `xml-rs` crate.
    pub namespaces: Option<Namespace>,

    /// The name of the Element.  Does not include any namespace info
    pub name: String,

    /// The Element attributes
    pub attributes: HashMap<String, String>,

    /// Children
    pub children: Vec<Element>,

    /// The text data for this element
    pub text: Option<String>,
}

/// Errors that can occur parsing XML
#[derive(Debug)]
pub enum ParseError {
    /// The XML is invalid
    MalformedXml(xml::reader::Error),
    /// This library is unable to process this XML. This can occur if, for
    /// example, the XML contains processing instructions.
    CannotParse,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ParseError::MalformedXml(ref e) => write!(f, "Malformed XML. {}", e),
            &ParseError::CannotParse => write!(f, "Cannot parse"),
        }
    }
}

impl std::error::Error for ParseError {
    fn description(&self) -> &str {
        match self {
            &ParseError::MalformedXml(..) => "Malformed XML",
            &ParseError::CannotParse => "Cannot parse",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &ParseError::MalformedXml(ref e) => Some(e),
            &ParseError::CannotParse => None,
        }
    }
}

fn build<B: Read>(reader: &mut EventReader<B>, mut elem: Element) -> Result<Element, ParseError> {
    loop {
        match reader.next() {
            Ok(XmlEvent::EndElement { ref name }) => {
                if name.local_name == elem.name {
                    return Ok(elem);
                } else {
                    return Err(ParseError::CannotParse);
                }
            }
            Ok(XmlEvent::StartElement { name, attributes, namespace }) => {
                let mut attr_map = HashMap::new();
                for attr in attributes {
                    attr_map.insert(attr.name.local_name, attr.value);
                }

                let new_elem = Element {
                    prefix: name.prefix,
                    namespace: name.namespace,
                    namespaces: if namespace.is_essentially_empty() {
                        None
                    } else {
                        Some(namespace)
                    },
                    name: name.local_name,
                    attributes: attr_map,
                    children: Vec::new(),
                    text: None,
                };
                elem.children.push(try!(build(reader, new_elem)));
            }
            Ok(XmlEvent::Characters(s)) => {
                elem.text = Some(s);
            }
            Ok(XmlEvent::Whitespace(..)) => (),
            Ok(XmlEvent::CData(s)) => elem.text = Some(s),
            Ok(XmlEvent::Comment(..)) => (),
            Ok(XmlEvent::StartDocument { .. }) |
            Ok(XmlEvent::EndDocument) |
            Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
            Err(e) => return Err(ParseError::MalformedXml(e)),
        }
    }

}

impl Element {
    /// Create a new empty element with given name
    ///
    /// All other fields are empty
    pub fn new(name: &str) -> Element {
        Element {
            name: String::from(name),
            prefix: None,
            namespace: None,
            namespaces: None,
            attributes: HashMap::new(),
            children: Vec::new(),
            text: None,
        }
    }

    /// Parses some data into an Element
    pub fn parse<R: Read>(r: R) -> Result<Element, ParseError> {
        let mut reader = EventReader::new(r);
        loop {
            match reader.next() {
                Ok(XmlEvent::StartElement { name, attributes, namespace }) => {
                    let mut attr_map = HashMap::new();
                    for attr in attributes {
                        attr_map.insert(attr.name.local_name, attr.value);
                    }

                    let root = Element {
                        prefix: name.prefix,
                        namespace: name.namespace,
                        namespaces: if namespace.is_essentially_empty() {
                            None
                        } else {
                            Some(namespace)
                        },
                        name: name.local_name,
                        attributes: attr_map,
                        children: Vec::new(),
                        text: None,
                    };
                    return build(&mut reader, root);
                }
                Ok(XmlEvent::Comment(..)) |
                Ok(XmlEvent::Whitespace(..)) |
                Ok(XmlEvent::StartDocument { .. }) => continue,
                Ok(XmlEvent::EndDocument) |
                Ok(XmlEvent::EndElement { .. }) |
                Ok(XmlEvent::Characters(..)) |
                Ok(XmlEvent::CData(..)) |
                Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
                Err(e) => return Err(ParseError::MalformedXml(e)),
            }
        }
    }

    fn _write<B: Write>(&self, emitter: &mut xml::writer::EventWriter<B>) {
        use xml::writer::events::XmlEvent;
        use xml::name::Name;
        use xml::namespace::Namespace;
        use xml::attribute::Attribute;

        let mut name = Name::local(&self.name);
        if let Some(ref ns) = self.namespace {
            name.namespace = Some(ns);
        }
        if let Some(ref p) = self.prefix {
            name.prefix = Some(p);
        }

        let mut attributes = Vec::with_capacity(self.attributes.len());
        for (k, v) in self.attributes.iter() {
            attributes.push(Attribute {
                                name: Name::local(k),
                                value: v,
                            });
        }

        let empty_ns = Namespace::empty();
        let namespace = if let Some(ref ns) = self.namespaces {
            Cow::Borrowed(ns)
        } else {
            Cow::Borrowed(&empty_ns)
        };

        emitter.write(XmlEvent::StartElement {
                          name: name,
                          attributes: Cow::Owned(attributes),
                          namespace: namespace,
                      })
            .unwrap();
        if let Some(ref t) = self.text {
            emitter.write(XmlEvent::Characters(t)).unwrap();
        }
        for elem in &self.children {
            elem._write(emitter);
        }
        emitter.write(XmlEvent::EndElement { name: Some(name) }).unwrap();
    }

    /// Writes out this element as the root element in an new XML document
    pub fn write<W: Write>(&self, w: W) {
        use xml::writer::EventWriter;
        use xml::writer::events::XmlEvent;
        use xml::common::XmlVersion;

        let mut emitter = EventWriter::new(w);
        emitter.write(XmlEvent::StartDocument {
                          version: XmlVersion::Version10,
                          encoding: None,
                          standalone: None,
                      })
            .unwrap();
        self._write(&mut emitter);
    }

    /// Find a child element with the given name and return a reference to it.
    pub fn get_child<K>(&self, k: K) -> Option<&Element>
        where String: PartialEq<K>
    {
        self.children.iter().find(|e| e.name == k)
    }

    /// Find a child element with the given name and return a mutable reference to it.
    pub fn get_mut_child<'a, K>(&'a mut self, k: K) -> Option<&'a mut Element>
        where String: PartialEq<K>
    {
        self.children.iter_mut().find(|e| e.name == k)
    }

    /// Find a child element with the given name, remove and return it.
    pub fn take_child<'a, K>(&'a mut self, k: K) -> Option<Element>
        where String: PartialEq<K>
    {
        self.children
            .iter()
            .position(|e| e.name == k)
            .map(|i| self.children.remove(i))
    }
}
<commit_msg>Fixed a bunch of clippy warnings to get a clean slate<commit_after>//! A simple library for parsing an XML file into an in-memory tree structure
//!
//! Not recommended for large XML files, as it will load the entire file into memory.
//!
//! # Example
//!
//! ```no_run
//! use xmltree::Element;
//! use std::fs::File;
//!
//! let data: &'static str = r##"
//! <?xml version="1.0" encoding="utf-8" standalone="yes"?>
//! <names>
//!     <name first="bob" last="jones" />
//!     <name first="elizabeth" last="smith" />
//! </names>
//! "##;
//!
//! let mut names_element = Element::parse(data.as_bytes()).unwrap();
//!
//! println!("{:#?}", names_element);
//! {
//!     // get first `name` element
//!     let name = names_element.get_mut_child("name").expect("Can't find name element");
//!     name.attributes.insert("suffix".to_owned(), "mr".to_owned());
//! }
//! names_element.write(File::create("result.xml").unwrap());
//!
//!
//! ```
extern crate xml;

use std::collections::HashMap;
use std::io::{Read, Write};
use std::borrow::Cow;
use std::fmt;

use xml::reader::{EventReader, XmlEvent};
pub use xml::namespace::Namespace;

/// Represents an XML element.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Element {
    /// This elements prefix, if any
    pub prefix: Option<String>,

    /// This elements namespace, if any
    pub namespace: Option<String>,

    /// The full list of namespaces, if any
    ///
    /// The `Namespace` type is exported from the `xml-rs` crate.
    pub namespaces: Option<Namespace>,

    /// The name of the Element.  Does not include any namespace info
    pub name: String,

    /// The Element attributes
    pub attributes: HashMap<String, String>,

    /// Children
    pub children: Vec<Element>,

    /// The text data for this element
    pub text: Option<String>,
}

/// Errors that can occur parsing XML
#[derive(Debug)]
pub enum ParseError {
    /// The XML is invalid
    MalformedXml(xml::reader::Error),
    /// This library is unable to process this XML. This can occur if, for
    /// example, the XML contains processing instructions.
    CannotParse,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ParseError::MalformedXml(ref e) => write!(f, "Malformed XML. {}", e),
            ParseError::CannotParse => write!(f, "Cannot parse"),
        }
    }
}

impl std::error::Error for ParseError {
    fn description(&self) -> &str {
        match *self {
            ParseError::MalformedXml(..) => "Malformed XML",
            ParseError::CannotParse => "Cannot parse",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            ParseError::MalformedXml(ref e) => Some(e),
            ParseError::CannotParse => None,
        }
    }
}

fn build<B: Read>(reader: &mut EventReader<B>, mut elem: Element) -> Result<Element, ParseError> {
    loop {
        match reader.next() {
            Ok(XmlEvent::EndElement { ref name }) => {
                if name.local_name == elem.name {
                    return Ok(elem);
                } else {
                    return Err(ParseError::CannotParse);
                }
            }
            Ok(XmlEvent::StartElement { name, attributes, namespace }) => {
                let mut attr_map = HashMap::new();
                for attr in attributes {
                    attr_map.insert(attr.name.local_name, attr.value);
                }

                let new_elem = Element {
                    prefix: name.prefix,
                    namespace: name.namespace,
                    namespaces: if namespace.is_essentially_empty() {
                        None
                    } else {
                        Some(namespace)
                    },
                    name: name.local_name,
                    attributes: attr_map,
                    children: Vec::new(),
                    text: None,
                };
                elem.children.push(try!(build(reader, new_elem)));
            }
            Ok(XmlEvent::Characters(s)) => {
                elem.text = Some(s);
            }
            Ok(XmlEvent::Whitespace(..)) | Ok(XmlEvent::Comment(..))=> (),
            Ok(XmlEvent::CData(s)) => elem.text = Some(s),
            Ok(XmlEvent::StartDocument { .. }) |
            Ok(XmlEvent::EndDocument) |
            Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
            Err(e) => return Err(ParseError::MalformedXml(e)),
        }
    }

}

impl Element {
    /// Create a new empty element with given name
    ///
    /// All other fields are empty
    pub fn new(name: &str) -> Element {
        Element {
            name: String::from(name),
            prefix: None,
            namespace: None,
            namespaces: None,
            attributes: HashMap::new(),
            children: Vec::new(),
            text: None,
        }
    }

    /// Parses some data into an Element
    pub fn parse<R: Read>(r: R) -> Result<Element, ParseError> {
        let mut reader = EventReader::new(r);
        loop {
            match reader.next() {
                Ok(XmlEvent::StartElement { name, attributes, namespace }) => {
                    let mut attr_map = HashMap::new();
                    for attr in attributes {
                        attr_map.insert(attr.name.local_name, attr.value);
                    }

                    let root = Element {
                        prefix: name.prefix,
                        namespace: name.namespace,
                        namespaces: if namespace.is_essentially_empty() {
                            None
                        } else {
                            Some(namespace)
                        },
                        name: name.local_name,
                        attributes: attr_map,
                        children: Vec::new(),
                        text: None,
                    };
                    return build(&mut reader, root);
                }
                Ok(XmlEvent::Comment(..)) |
                Ok(XmlEvent::Whitespace(..)) |
                Ok(XmlEvent::StartDocument { .. }) => continue,
                Ok(XmlEvent::EndDocument) |
                Ok(XmlEvent::EndElement { .. }) |
                Ok(XmlEvent::Characters(..)) |
                Ok(XmlEvent::CData(..)) |
                Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
                Err(e) => return Err(ParseError::MalformedXml(e)),
            }
        }
    }

    fn _write<B: Write>(&self, emitter: &mut xml::writer::EventWriter<B>) {
        use xml::writer::events::XmlEvent;
        use xml::name::Name;
        use xml::namespace::Namespace;
        use xml::attribute::Attribute;

        let mut name = Name::local(&self.name);
        if let Some(ref ns) = self.namespace {
            name.namespace = Some(ns);
        }
        if let Some(ref p) = self.prefix {
            name.prefix = Some(p);
        }

        let mut attributes = Vec::with_capacity(self.attributes.len());
        for (k, v) in &self.attributes {
            attributes.push(Attribute {
                                name: Name::local(k),
                                value: v,
                            });
        }

        let empty_ns = Namespace::empty();
        let namespace = if let Some(ref ns) = self.namespaces {
            Cow::Borrowed(ns)
        } else {
            Cow::Borrowed(&empty_ns)
        };

        emitter.write(XmlEvent::StartElement {
                          name: name,
                          attributes: Cow::Owned(attributes),
                          namespace: namespace,
                      })
            .unwrap();
        if let Some(ref t) = self.text {
            emitter.write(XmlEvent::Characters(t)).unwrap();
        }
        for elem in &self.children {
            elem._write(emitter);
        }
        emitter.write(XmlEvent::EndElement { name: Some(name) }).unwrap();
    }

    /// Writes out this element as the root element in an new XML document
    pub fn write<W: Write>(&self, w: W) {
        use xml::writer::EventWriter;
        use xml::writer::events::XmlEvent;
        use xml::common::XmlVersion;

        let mut emitter = EventWriter::new(w);
        emitter.write(XmlEvent::StartDocument {
                          version: XmlVersion::Version10,
                          encoding: None,
                          standalone: None,
                      })
            .unwrap();
        self._write(&mut emitter);
    }

    /// Find a child element with the given name and return a reference to it.
    pub fn get_child<K>(&self, k: K) -> Option<&Element>
        where String: PartialEq<K>
    {
        self.children.iter().find(|e| e.name == k)
    }

    /// Find a child element with the given name and return a mutable reference to it.
    pub fn get_mut_child<K>(&mut self, k: K) -> Option<&mut Element>
        where String: PartialEq<K>
    {
        self.children.iter_mut().find(|e| e.name == k)
    }

    /// Find a child element with the given name, remove and return it.
    pub fn take_child<K>(&mut self, k: K) -> Option<Element>
        where String: PartialEq<K>
    {
        self.children
            .iter()
            .position(|e| e.name == k)
            .map(|i| self.children.remove(i))
    }
}
<|endoftext|>


<commit_before>//! The `ipnetwork` crate provides a set of APIs to work with IP CIDRs in
//! Rust. Implementation for IPv4 is more or less stable, IPv6 implementation
//! is still WIP.
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
#![crate_type = "lib"]
#![doc(html_root_url = "https://docs.rs/ipnetwork/0.15.1")]

use std::{fmt, net::IpAddr, str::FromStr};

mod common;
mod ipv4;
mod ipv6;

pub use crate::common::IpNetworkError;
use crate::ipv4::Ipv4NetworkIterator;
pub use crate::ipv4::{ipv4_mask_to_prefix, Ipv4Network};
use crate::ipv6::Ipv6NetworkIterator;
pub use crate::ipv6::{ipv6_mask_to_prefix, Ipv6Network};

/// Represents a generic network range. This type can have two variants:
/// the v4 and the v6 case.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum IpNetwork {
    V4(Ipv4Network),
    V6(Ipv6Network),
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for IpNetwork {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = <String>::deserialize(deserializer)?;
        IpNetwork::from_str(&s).map_err(serde::de::Error::custom)
    }
}

#[cfg(feature = "serde")]
impl serde::Serialize for IpNetwork {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

/// Represents a generic network size. For IPv4, the max size is a u32 and for IPv6, it is a u128
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum NetworkSize {
    V4(u32),
    V6(u128),
}

impl IpNetwork {
    /// Constructs a new `IpNetwork` from a given `IpAddr` and a prefix denoting the
    /// network size. If the prefix is larger than 32 (for IPv4) or 128 (for IPv6), this
    /// will raise an `IpNetworkError::InvalidPrefix` error. Support for IPv6 is not
    /// complete yet.
    pub fn new(ip: IpAddr, prefix: u8) -> Result<IpNetwork, IpNetworkError> {
        match ip {
            IpAddr::V4(a) => Ok(IpNetwork::V4(Ipv4Network::new(a, prefix)?)),
            IpAddr::V6(a) => Ok(IpNetwork::V6(Ipv6Network::new(a, prefix)?)),
        }
    }

    /// Constructs a new `IpNetwork` from a network address and a network mask.
    ///
    /// If the netmask is not valid this will return an `IpNetworkError::InvalidPrefix`.
    pub fn with_netmask(netaddr: IpAddr, netmask: IpAddr) -> Result<Self, IpNetworkError> {
        let prefix = ip_mask_to_prefix(netmask)?;
        Self::new(netaddr, prefix)
    }

    /// Returns the IP part of a given `IpNetwork`
    pub fn ip(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.ip()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.ip()),
        }
    }

    /// Returns the prefix of the given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.1".parse().unwrap()).prefix(), 32u8);
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).prefix(), 16u8);
    ///
    /// assert_eq!(IpNetwork::V6("ff01::0".parse().unwrap()).prefix(), 128u8);
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).prefix(), 32u8);
    /// ```
    pub fn prefix(&self) -> u8 {
        match *self {
            IpNetwork::V4(ref a) => a.prefix(),
            IpNetwork::V6(ref a) => a.prefix(),
        }
    }

    /// Returns the address of the network denoted by this `IpNetwork`.
    /// This means the lowest possible IP address inside of the network.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{Ipv4Addr, Ipv6Addr};
    /// use ipnetwork::IpNetwork;
    ///
    /// let net: IpNetwork = "10.1.9.32/16".parse().unwrap();
    /// assert_eq!(net.network(), Ipv4Addr::new(10, 1, 0, 0));
    /// let net: IpNetwork = "2001:db8::/96".parse().unwrap();
    /// assert_eq!(net.network(), Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0));
    /// ```
    pub fn network(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.network()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.network()),
        }
    }

    /// Returns the broadcasting address of this `IpNetwork`.
    /// This means the highest possible IP address inside of the network.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv4Addr;
    /// use ipnetwork::{IpNetwork, Ipv4Network};
    ///
    /// let net: Ipv4Network = "10.9.0.32/16".parse().unwrap();
    /// assert_eq!(net.broadcast(), Ipv4Addr::new(10, 9, 255, 255));
    /// ```
    pub fn broadcast(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.broadcast()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.broadcast()),
        }
    }

    /// Returns the mask for this `IpNetwork`.
    /// That means the `prefix` most significant bits will be 1 and the rest 0
    ///
    /// # Example
    ///
    /// ```
    /// use ipnetwork::IpNetwork;
    /// use std::net::{Ipv4Addr, Ipv6Addr};
    ///
    /// let v4_net: IpNetwork = "10.9.0.1".parse().unwrap();
    /// assert_eq!(v4_net.mask(), Ipv4Addr::new(255, 255, 255, 255));
    /// let v4_net: IpNetwork = "10.9.0.32/16".parse().unwrap();
    /// assert_eq!(v4_net.mask(), Ipv4Addr::new(255, 255, 0, 0));
    ///
    /// let v6_net: IpNetwork = "ff01::0".parse().unwrap();
    /// assert_eq!(v6_net.mask(), Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff));
    /// let v6_net: IpNetwork = "ff01::0/32".parse().unwrap();
    /// assert_eq!(v6_net.mask(), Ipv6Addr::new(0xffff, 0xffff, 0, 0, 0, 0, 0, 0));
    /// ```
    pub fn mask(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.mask()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.mask()),
        }
    }

    /// Returns true if the IP in this `IpNetwork` is a valid IPv4 address,
    /// false if it's a valid IPv6 address.
    ///
    /// # Example
    ///
    ///```
    /// use ipnetwork::IpNetwork;
    ///
    /// let v4: IpNetwork = IpNetwork::V4("10.9.0.32/16".parse().unwrap());
    /// assert_eq!(v4.is_ipv4(), true);
    /// assert_eq!(v4.is_ipv6(), false);
    ///```
    pub fn is_ipv4(&self) -> bool {
        match *self {
            IpNetwork::V4(_) => true,
            IpNetwork::V6(_) => false,
        }
    }

    /// Returns true if the IP in this `IpNetwork` is a valid IPv6 address,
    /// false if it's a valid IPv4 address.
    ///
    /// # Example
    ///
    ///```
    /// use ipnetwork::IpNetwork;
    ///
    /// let v6: IpNetwork = IpNetwork::V6("ff01::0/32".parse().unwrap());
    /// assert_eq!(v6.is_ipv6(), true);
    /// assert_eq!(v6.is_ipv4(), false);
    ///```
    pub fn is_ipv6(&self) -> bool {
        match *self {
            IpNetwork::V4(_) => false,
            IpNetwork::V6(_) => true,
        }
    }

    // TODO(abhishek) when TryFrom is stable, implement it for IpNetwork to
    // variant conversions. Then use that to implement a generic is_subnet_of
    // is_supernet_of, overlaps

    /// Checks if a given `IpAddr` is in this `IpNetwork`
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::IpAddr;
    /// use ipnetwork::IpNetwork;
    ///
    /// let net: IpNetwork = "127.0.0.0/24".parse().unwrap();
    /// let ip1: IpAddr = "127.0.0.1".parse().unwrap();
    /// let ip2: IpAddr = "172.0.0.1".parse().unwrap();
    /// let ip4: IpAddr = "::1".parse().unwrap();
    /// assert!(net.contains(ip1));
    /// assert!(!net.contains(ip2));
    /// assert!(!net.contains(ip4));
    /// ```
    pub fn contains(&self, ip: IpAddr) -> bool {
        match (*self, ip) {
            (IpNetwork::V4(net), IpAddr::V4(ip)) => net.contains(ip),
            (IpNetwork::V6(net), IpAddr::V6(ip)) => net.contains(ip),
            _ => false,
        }
    }

    /// Returns the number of possible host addresses in this `IpAddr`
    ///
    /// # Examples
    ///
    /// ```
    /// use ipnetwork::{IpNetwork, NetworkSize};
    ///
    ///
    /// let net: IpNetwork = "127.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.size(), NetworkSize::V4(256))
    /// ```
    pub fn size(&self) -> NetworkSize {
        match *self {
            IpNetwork::V4(ref ip) => NetworkSize::V4(ip.size()),
            IpNetwork::V6(ref ip) => NetworkSize::V6(ip.size()),
        }
    }

    /// Returns an iterator over the addresses contained in the network.
    ///
    /// This lists all the addresses in the network range, in ascending order.
    pub fn iter(&self) -> IpNetworkIterator {
        let inner = match self {
            IpNetwork::V4(ip) => IpNetworkIteratorInner::V4(ip.iter()),
            IpNetwork::V6(ip) => IpNetworkIteratorInner::V6(ip.iter()),
        };
        IpNetworkIterator { inner }
    }
}

/// Tries to parse the given string into a `IpNetwork`. Will first try to parse
/// it as an `Ipv4Network` and if that fails as an `Ipv6Network`. If both
/// fails it will return an `InvalidAddr` error.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::{IpNetwork, Ipv4Network};
///
/// let expected = IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(10, 1, 9, 32), 16).unwrap());
/// let from_cidr: IpNetwork = "10.1.9.32/16".parse().unwrap();
/// assert_eq!(expected, from_cidr);
/// ```
impl FromStr for IpNetwork {
    type Err = IpNetworkError;
    fn from_str(s: &str) -> Result<IpNetwork, IpNetworkError> {
        if let Ok(net) = Ipv4Network::from_str(s) {
            Ok(IpNetwork::V4(net))
        } else if let Ok(net) = Ipv6Network::from_str(s) {
            Ok(IpNetwork::V6(net))
        } else {
            Err(IpNetworkError::InvalidAddr(s.to_string()))
        }
    }
}

impl From<Ipv4Network> for IpNetwork {
    fn from(v4: Ipv4Network) -> IpNetwork {
        IpNetwork::V4(v4)
    }
}

impl From<Ipv6Network> for IpNetwork {
    fn from(v6: Ipv6Network) -> IpNetwork {
        IpNetwork::V6(v6)
    }
}

impl From<IpAddr> for IpNetwork {
    fn from(addr: IpAddr) -> IpNetwork {
        match addr {
            IpAddr::V4(a) => IpNetwork::V4(Ipv4Network::from(a)),
            IpAddr::V6(a) => IpNetwork::V6(Ipv6Network::from(a)),
        }
    }
}

impl fmt::Display for IpNetwork {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            IpNetwork::V4(net) => net.fmt(f),
            IpNetwork::V6(net) => net.fmt(f),
        }
    }
}

#[derive(Clone, Debug)]
enum IpNetworkIteratorInner {
    V4(Ipv4NetworkIterator),
    V6(Ipv6NetworkIterator),
}

pub struct IpNetworkIterator {
    inner: IpNetworkIteratorInner,
}

impl Iterator for IpNetworkIterator {
    type Item = IpAddr;
    fn next(&mut self) -> Option<IpAddr> {
        match &mut self.inner {
            IpNetworkIteratorInner::V4(iter) => iter.next().map(IpAddr::V4),
            IpNetworkIteratorInner::V6(iter) => iter.next().map(IpAddr::V6),
        }
    }
}

impl IntoIterator for &'_ IpNetwork {
    type IntoIter = IpNetworkIterator;
    type Item = IpAddr;
    fn into_iter(self) -> IpNetworkIterator {
        self.iter()
    }
}

/// Converts a `IpAddr` network mask into a prefix.
/// If the mask is invalid this will return an `IpNetworkError::InvalidPrefix`.
pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, IpNetworkError> {
    match mask {
        IpAddr::V4(mask) => ipv4_mask_to_prefix(mask),
        IpAddr::V6(mask) => ipv6_mask_to_prefix(mask),
    }
}

#[cfg(test)]
mod test {
    #[test]
    #[cfg(feature = "serde")]
    fn deserialize_from_serde_json_value() {
        use super::*;
        let network = IpNetwork::from_str("0.0.0.0/0").unwrap();
        let val: serde_json::value::Value =
            serde_json::from_str(&serde_json::to_string(&network).unwrap()).unwrap();
        let _deser: IpNetwork = serde_json::from_value(val)
            .expect("Fails to deserialize from json_value::value::Value");
    }
}
<commit_msg>Cleanup comment on IPv6 implementation<commit_after>//! The `ipnetwork` crate provides a set of APIs to work with IP CIDRs in
//! Rust.
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
#![crate_type = "lib"]
#![doc(html_root_url = "https://docs.rs/ipnetwork/0.15.1")]

use std::{fmt, net::IpAddr, str::FromStr};

mod common;
mod ipv4;
mod ipv6;

pub use crate::common::IpNetworkError;
use crate::ipv4::Ipv4NetworkIterator;
pub use crate::ipv4::{ipv4_mask_to_prefix, Ipv4Network};
use crate::ipv6::Ipv6NetworkIterator;
pub use crate::ipv6::{ipv6_mask_to_prefix, Ipv6Network};

/// Represents a generic network range. This type can have two variants:
/// the v4 and the v6 case.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum IpNetwork {
    V4(Ipv4Network),
    V6(Ipv6Network),
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for IpNetwork {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = <String>::deserialize(deserializer)?;
        IpNetwork::from_str(&s).map_err(serde::de::Error::custom)
    }
}

#[cfg(feature = "serde")]
impl serde::Serialize for IpNetwork {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

/// Represents a generic network size. For IPv4, the max size is a u32 and for IPv6, it is a u128
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum NetworkSize {
    V4(u32),
    V6(u128),
}

impl IpNetwork {
    /// Constructs a new `IpNetwork` from a given `IpAddr` and a prefix denoting the
    /// network size. If the prefix is larger than 32 (for IPv4) or 128 (for IPv6), this
    /// will raise an `IpNetworkError::InvalidPrefix` error. Support for IPv6 is not
    /// complete yet.
    pub fn new(ip: IpAddr, prefix: u8) -> Result<IpNetwork, IpNetworkError> {
        match ip {
            IpAddr::V4(a) => Ok(IpNetwork::V4(Ipv4Network::new(a, prefix)?)),
            IpAddr::V6(a) => Ok(IpNetwork::V6(Ipv6Network::new(a, prefix)?)),
        }
    }

    /// Constructs a new `IpNetwork` from a network address and a network mask.
    ///
    /// If the netmask is not valid this will return an `IpNetworkError::InvalidPrefix`.
    pub fn with_netmask(netaddr: IpAddr, netmask: IpAddr) -> Result<Self, IpNetworkError> {
        let prefix = ip_mask_to_prefix(netmask)?;
        Self::new(netaddr, prefix)
    }

    /// Returns the IP part of a given `IpNetwork`
    pub fn ip(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.ip()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.ip()),
        }
    }

    /// Returns the prefix of the given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.1".parse().unwrap()).prefix(), 32u8);
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).prefix(), 16u8);
    ///
    /// assert_eq!(IpNetwork::V6("ff01::0".parse().unwrap()).prefix(), 128u8);
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).prefix(), 32u8);
    /// ```
    pub fn prefix(&self) -> u8 {
        match *self {
            IpNetwork::V4(ref a) => a.prefix(),
            IpNetwork::V6(ref a) => a.prefix(),
        }
    }

    /// Returns the address of the network denoted by this `IpNetwork`.
    /// This means the lowest possible IP address inside of the network.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{Ipv4Addr, Ipv6Addr};
    /// use ipnetwork::IpNetwork;
    ///
    /// let net: IpNetwork = "10.1.9.32/16".parse().unwrap();
    /// assert_eq!(net.network(), Ipv4Addr::new(10, 1, 0, 0));
    /// let net: IpNetwork = "2001:db8::/96".parse().unwrap();
    /// assert_eq!(net.network(), Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0));
    /// ```
    pub fn network(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.network()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.network()),
        }
    }

    /// Returns the broadcasting address of this `IpNetwork`.
    /// This means the highest possible IP address inside of the network.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv4Addr;
    /// use ipnetwork::{IpNetwork, Ipv4Network};
    ///
    /// let net: Ipv4Network = "10.9.0.32/16".parse().unwrap();
    /// assert_eq!(net.broadcast(), Ipv4Addr::new(10, 9, 255, 255));
    /// ```
    pub fn broadcast(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.broadcast()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.broadcast()),
        }
    }

    /// Returns the mask for this `IpNetwork`.
    /// That means the `prefix` most significant bits will be 1 and the rest 0
    ///
    /// # Example
    ///
    /// ```
    /// use ipnetwork::IpNetwork;
    /// use std::net::{Ipv4Addr, Ipv6Addr};
    ///
    /// let v4_net: IpNetwork = "10.9.0.1".parse().unwrap();
    /// assert_eq!(v4_net.mask(), Ipv4Addr::new(255, 255, 255, 255));
    /// let v4_net: IpNetwork = "10.9.0.32/16".parse().unwrap();
    /// assert_eq!(v4_net.mask(), Ipv4Addr::new(255, 255, 0, 0));
    ///
    /// let v6_net: IpNetwork = "ff01::0".parse().unwrap();
    /// assert_eq!(v6_net.mask(), Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff));
    /// let v6_net: IpNetwork = "ff01::0/32".parse().unwrap();
    /// assert_eq!(v6_net.mask(), Ipv6Addr::new(0xffff, 0xffff, 0, 0, 0, 0, 0, 0));
    /// ```
    pub fn mask(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.mask()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.mask()),
        }
    }

    /// Returns true if the IP in this `IpNetwork` is a valid IPv4 address,
    /// false if it's a valid IPv6 address.
    ///
    /// # Example
    ///
    ///```
    /// use ipnetwork::IpNetwork;
    ///
    /// let v4: IpNetwork = IpNetwork::V4("10.9.0.32/16".parse().unwrap());
    /// assert_eq!(v4.is_ipv4(), true);
    /// assert_eq!(v4.is_ipv6(), false);
    ///```
    pub fn is_ipv4(&self) -> bool {
        match *self {
            IpNetwork::V4(_) => true,
            IpNetwork::V6(_) => false,
        }
    }

    /// Returns true if the IP in this `IpNetwork` is a valid IPv6 address,
    /// false if it's a valid IPv4 address.
    ///
    /// # Example
    ///
    ///```
    /// use ipnetwork::IpNetwork;
    ///
    /// let v6: IpNetwork = IpNetwork::V6("ff01::0/32".parse().unwrap());
    /// assert_eq!(v6.is_ipv6(), true);
    /// assert_eq!(v6.is_ipv4(), false);
    ///```
    pub fn is_ipv6(&self) -> bool {
        match *self {
            IpNetwork::V4(_) => false,
            IpNetwork::V6(_) => true,
        }
    }

    // TODO(abhishek) when TryFrom is stable, implement it for IpNetwork to
    // variant conversions. Then use that to implement a generic is_subnet_of
    // is_supernet_of, overlaps

    /// Checks if a given `IpAddr` is in this `IpNetwork`
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::IpAddr;
    /// use ipnetwork::IpNetwork;
    ///
    /// let net: IpNetwork = "127.0.0.0/24".parse().unwrap();
    /// let ip1: IpAddr = "127.0.0.1".parse().unwrap();
    /// let ip2: IpAddr = "172.0.0.1".parse().unwrap();
    /// let ip4: IpAddr = "::1".parse().unwrap();
    /// assert!(net.contains(ip1));
    /// assert!(!net.contains(ip2));
    /// assert!(!net.contains(ip4));
    /// ```
    pub fn contains(&self, ip: IpAddr) -> bool {
        match (*self, ip) {
            (IpNetwork::V4(net), IpAddr::V4(ip)) => net.contains(ip),
            (IpNetwork::V6(net), IpAddr::V6(ip)) => net.contains(ip),
            _ => false,
        }
    }

    /// Returns the number of possible host addresses in this `IpAddr`
    ///
    /// # Examples
    ///
    /// ```
    /// use ipnetwork::{IpNetwork, NetworkSize};
    ///
    ///
    /// let net: IpNetwork = "127.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.size(), NetworkSize::V4(256))
    /// ```
    pub fn size(&self) -> NetworkSize {
        match *self {
            IpNetwork::V4(ref ip) => NetworkSize::V4(ip.size()),
            IpNetwork::V6(ref ip) => NetworkSize::V6(ip.size()),
        }
    }

    /// Returns an iterator over the addresses contained in the network.
    ///
    /// This lists all the addresses in the network range, in ascending order.
    pub fn iter(&self) -> IpNetworkIterator {
        let inner = match self {
            IpNetwork::V4(ip) => IpNetworkIteratorInner::V4(ip.iter()),
            IpNetwork::V6(ip) => IpNetworkIteratorInner::V6(ip.iter()),
        };
        IpNetworkIterator { inner }
    }
}

/// Tries to parse the given string into a `IpNetwork`. Will first try to parse
/// it as an `Ipv4Network` and if that fails as an `Ipv6Network`. If both
/// fails it will return an `InvalidAddr` error.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::{IpNetwork, Ipv4Network};
///
/// let expected = IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(10, 1, 9, 32), 16).unwrap());
/// let from_cidr: IpNetwork = "10.1.9.32/16".parse().unwrap();
/// assert_eq!(expected, from_cidr);
/// ```
impl FromStr for IpNetwork {
    type Err = IpNetworkError;
    fn from_str(s: &str) -> Result<IpNetwork, IpNetworkError> {
        if let Ok(net) = Ipv4Network::from_str(s) {
            Ok(IpNetwork::V4(net))
        } else if let Ok(net) = Ipv6Network::from_str(s) {
            Ok(IpNetwork::V6(net))
        } else {
            Err(IpNetworkError::InvalidAddr(s.to_string()))
        }
    }
}

impl From<Ipv4Network> for IpNetwork {
    fn from(v4: Ipv4Network) -> IpNetwork {
        IpNetwork::V4(v4)
    }
}

impl From<Ipv6Network> for IpNetwork {
    fn from(v6: Ipv6Network) -> IpNetwork {
        IpNetwork::V6(v6)
    }
}

impl From<IpAddr> for IpNetwork {
    fn from(addr: IpAddr) -> IpNetwork {
        match addr {
            IpAddr::V4(a) => IpNetwork::V4(Ipv4Network::from(a)),
            IpAddr::V6(a) => IpNetwork::V6(Ipv6Network::from(a)),
        }
    }
}

impl fmt::Display for IpNetwork {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            IpNetwork::V4(net) => net.fmt(f),
            IpNetwork::V6(net) => net.fmt(f),
        }
    }
}

#[derive(Clone, Debug)]
enum IpNetworkIteratorInner {
    V4(Ipv4NetworkIterator),
    V6(Ipv6NetworkIterator),
}

pub struct IpNetworkIterator {
    inner: IpNetworkIteratorInner,
}

impl Iterator for IpNetworkIterator {
    type Item = IpAddr;
    fn next(&mut self) -> Option<IpAddr> {
        match &mut self.inner {
            IpNetworkIteratorInner::V4(iter) => iter.next().map(IpAddr::V4),
            IpNetworkIteratorInner::V6(iter) => iter.next().map(IpAddr::V6),
        }
    }
}

impl IntoIterator for &'_ IpNetwork {
    type IntoIter = IpNetworkIterator;
    type Item = IpAddr;
    fn into_iter(self) -> IpNetworkIterator {
        self.iter()
    }
}

/// Converts a `IpAddr` network mask into a prefix.
/// If the mask is invalid this will return an `IpNetworkError::InvalidPrefix`.
pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, IpNetworkError> {
    match mask {
        IpAddr::V4(mask) => ipv4_mask_to_prefix(mask),
        IpAddr::V6(mask) => ipv6_mask_to_prefix(mask),
    }
}

#[cfg(test)]
mod test {
    #[test]
    #[cfg(feature = "serde")]
    fn deserialize_from_serde_json_value() {
        use super::*;
        let network = IpNetwork::from_str("0.0.0.0/0").unwrap();
        let val: serde_json::value::Value =
            serde_json::from_str(&serde_json::to_string(&network).unwrap()).unwrap();
        let _deser: IpNetwork = serde_json::from_value(val)
            .expect("Fails to deserialize from json_value::value::Value");
    }
}
<|endoftext|>


<commit_before>#![feature(drain)]
#![feature(plugin)]
#![plugin(phf_macros)]

extern crate phf;
extern crate itertools;
extern crate unicode_segmentation;
extern crate unicode_normalization;
extern crate rustc_serialize;

mod utils;
mod suffix;
mod nickname;
mod title;
mod surname;
mod namecase;
mod namepart;

use itertools::Itertools;
use utils::*;
use namepart::{NamePart, Location};

#[derive(RustcDecodable, RustcEncodable)]
pub struct Name {
  pub given_name: Option<String>,
  pub surname: String,
  pub middle_names: Option<String>,
  pub first_initial: char,
  pub middle_initials: Option<String>,
}

// Strip suffixes and titles, and find the start of the surname.
// These tasks are intrinsically connected because commas may indicate
// either a sort-ordered surname ("Smith, John") or a suffix ("John Smith, esq")
//
// This is where the meat of the parsing takes place
fn name_words_and_surname_index(name: &str, mixed_case: bool) -> (Vec<NamePart>, usize) {
    let mut words: Vec<NamePart> = Vec::new();
    let mut postfixes: Vec<NamePart> = Vec::new();
    let mut surname_index = 0;
    let mut found_first_name_or_initial = false;

    // Separate comma-separated titles and suffixes, then flip remaining words
    // around remaining comma, if any
    for (i, part) in name.split(",").enumerate() {
        if i == 0 || words.is_empty() {
            // We're in the surname part (if the format is "Smith, John"),
            // or the only actual name part (if the format is "John Smith,
            // esq." or just "John Smith")
            words.extend(NamePart::all_from_text(part, mixed_case, Location::End));
            if words.is_empty() { continue }

            // Check for title as prefix (e.g. "Dr. John Smith" or "Right Hon.
            // John Smith"); finding a prefix title means the next word is a
            // first name or initial (we don't support "Dr. Smith, John")
            if words.len() > 1 {
                found_first_name_or_initial = title::strip_prefix_title(&mut words, true);
            }

            // Strip non-comma-separated titles & suffixes (e.g. "John Smith Jr.")
            let postfix_position = words.iter().skip(1).position( |word|
                suffix::is_suffix(&word) || title::is_postfix_title(&word)
            );
            if postfix_position.is_some() {
                let range = (postfix_position.unwrap() + 1)..words.len(); // Off-by-one since we skipped the first word
                postfixes.extend(words.drain(range));
            }

            if !found_first_name_or_initial {
                found_first_name_or_initial = surname::find_surname_index(&*words) > 0;
            }
        }
        else if found_first_name_or_initial {
            // We already found the full name, so this is a comma-separated
            // postfix title or suffix
            postfixes.extend(NamePart::all_from_text(part, mixed_case, Location::End));
        }
        else {
            // We already processed one comma-separated part, which may
            // have been the surname (if this is the given name), or the full
            // name (if this is a suffix or title)
            let mut given_middle_or_postfix_words: Vec<NamePart> =
                NamePart::all_from_text(part, mixed_case, Location::Start).collect();
            if given_middle_or_postfix_words.is_empty() { continue }

            // Check for (unusual) formats like "Smith, Dr. John M."
            if !found_first_name_or_initial && given_middle_or_postfix_words.len() > 1 {
                found_first_name_or_initial = title::strip_prefix_title(&mut given_middle_or_postfix_words, false);
            }

            // Check for (more common) formats like "Smith, John" or "Smith, J. M."
            if !found_first_name_or_initial {
                let word = given_middle_or_postfix_words.first().unwrap();
                if word.is_namelike() {
                    found_first_name_or_initial = true;
                } else if word.is_initials() {
                    // Handle a special case like "Ben Smith, III" or "John E Smith,
                    // M.D.", where we might have mistakenly classified the whole
                    // first comma-separated part as a surname (due to the "ben"
                    // prefix and "e" conjunction rules respectively)
                    found_first_name_or_initial = words.len() == 1 ||
                        given_middle_or_postfix_words.iter().any( |word|
                            !suffix::is_suffix(word) && !title::is_postfix_title(word)
                        );
                }
            }

            // Now we've decided: either this is the given name or first initial,
            // in which case we put it in front, or it's a suffix or title
            if found_first_name_or_initial {
                // Check for (unusual) formats like "Smith, Dr. John Jr." (but
                // only look for suffixes or abbreviations, anything title-like
                // that might be a name or initials is more likely the latter)
                let postfix_position = given_middle_or_postfix_words.iter().position( |word|
                    word.is_abbreviation() || suffix::is_suffix(&word)
                );

                if postfix_position.is_some() {
                    let range = postfix_position.unwrap()..given_middle_or_postfix_words.len();
                    postfixes.extend(given_middle_or_postfix_words.drain(range));
                }

                let surname_words = words;
                words = given_middle_or_postfix_words;
                surname_index = words.len();
                words.extend(surname_words);
            }
            else {
                postfixes.extend(given_middle_or_postfix_words);
            }
        }
    }

    // If there are two or fewer words, e.g. "JOHN MA", we treat
    // ambiguous strings like "MA" as surnames rather than titles
    // (not initials, which should only be at the end of the input
    // if they are comma-separated, and we already handled that case)
    if words.len() < 2 && !postfixes.is_empty() && postfixes[0].is_namelike() {
        words.push(postfixes.remove(0));
    }

    // Anything trailing that looks like initials is probably a stray suffix
    while !words.is_empty() && words.last().unwrap().is_initials() {
        words.pop();
    }

    if words.len() < 2 {
        // Failed parse
        return (words, 0);
    }

    if surname_index <= 0 || surname_index >= words.len() {
        // We didn't get the surname from the formatting (e.g. "Smith, John"),
        // so we have to guess it
        surname_index = surname::find_surname_index(&words[1..]) + 1;
    }

    (words, surname_index)
}

impl Name {
    pub fn parse(name: &str) -> Option<Name> {
        if !name.chars().any(char::is_alphabetic) {
            return None
        }

        let mixed_case = is_mixed_case(name);
        let name = nickname::strip_nickname(name);
        let (words, surname_index) = name_words_and_surname_index(&name, mixed_case);

        if words.len() < 2 {
            // We need at least a first and last name, or we can't tell which we have
            return None;
        }
        else if words[surname_index..].iter().all( |w| !w.is_namelike() ) {
            // Looks like a bad parse, since the surname doesn't make sense
            return None;
        }

        // Take the remaining words, and strip out the initials (if present;
        // only allow one block of initials) and the first name (if present),
        // and whatever's left are the middle names
        let mut given_name: Option<String> = None;
        let mut middle_names: Vec<&str> = Vec::new();
        let mut middle_initials = String::new();

        for (i, word) in words[0..surname_index].iter().enumerate() {
            if word.is_initials() {
                let start = if i == 0 { 1 } else { 0 };
                if word.chars > start {
                    middle_initials.extend(
                        word.word
                            .chars()
                            .filter( |c| c.is_alphabetic() )
                            .skip(start)
                            .filter_map( |w| w.to_uppercase().next() ));
                }
            } else if given_name.is_none() {
                given_name = Some(word.namecased.to_string());
            } else {
                middle_names.push(&*word.namecased);
                middle_initials.push(word.initial());
            }
        }

        let middle_names =
            if middle_names.is_empty() {
                None
            } else {
                Some(middle_names.join(" "))
            };

        let middle_initials =
            if middle_initials.is_empty() {
                None
            } else {
                Some(middle_initials)
            };

        let surname = words[surname_index..]
            .iter()
            .map( |w| &*w.namecased )
            .join(" ");

        Some(Name {
            first_initial: words[0].initial(),
            given_name: given_name,
            surname: surname,
            middle_names: middle_names,
            middle_initials: middle_initials,
        })
    }

    pub fn display(&self) -> String {
        match self.given_name {
            Some(ref name) => {
                format!("{} {}", name, self.surname)
            }
            None => {
                format!("{}. {}", self.first_initial, self.surname)
            }
        }
    }
}
<commit_msg>Factor out common postfix-stripping code<commit_after>#![feature(drain)]
#![feature(plugin)]
#![plugin(phf_macros)]

extern crate phf;
extern crate itertools;
extern crate unicode_segmentation;
extern crate unicode_normalization;
extern crate rustc_serialize;

mod utils;
mod suffix;
mod nickname;
mod title;
mod surname;
mod namecase;
mod namepart;

use itertools::Itertools;
use utils::*;
use namepart::{NamePart, Location};

#[derive(RustcDecodable, RustcEncodable)]
pub struct Name {
  pub given_name: Option<String>,
  pub surname: String,
  pub middle_names: Option<String>,
  pub first_initial: char,
  pub middle_initials: Option<String>,
}

fn strip_postfixes_and_find_suffix<'a>(words: &mut Vec<NamePart<'a>>, include_first_word: bool, postfixes: &mut Vec<NamePart<'a>>) { // -> Option<NamePart> {
    let postfix_position = words.iter().enumerate().position( |(i, word)|
        if i == 0 && !include_first_word {
            false
        }
        else {
            word.is_abbreviation() || suffix::is_suffix(&word)
        }
    );

    if postfix_position.is_some() {
        let range = postfix_position.unwrap()..words.len();
        postfixes.extend(words.drain(range));
    }
}

// Strip suffixes and titles, and find the start of the surname.
// These tasks are intrinsically connected because commas may indicate
// either a sort-ordered surname ("Smith, John") or a suffix ("John Smith, esq")
//
// This is where the meat of the parsing takes place
fn name_words_and_surname_index(name: &str, mixed_case: bool) -> (Vec<NamePart>, usize) {
    let mut words: Vec<NamePart> = Vec::new();
    let mut postfixes: Vec<NamePart> = Vec::new();
    let mut surname_index = 0;
    let mut found_first_name_or_initial = false;

    // Separate comma-separated titles and suffixes, then flip remaining words
    // around remaining comma, if any
    for (i, part) in name.split(",").enumerate() {
        if i == 0 || words.is_empty() {
            // We're in the surname part (if the format is "Smith, John"),
            // or the only actual name part (if the format is "John Smith,
            // esq." or just "John Smith")
            words.extend(NamePart::all_from_text(part, mixed_case, Location::End));
            if words.is_empty() { continue }

            // Check for title as prefix (e.g. "Dr. John Smith" or "Right Hon.
            // John Smith"); finding a prefix title means the next word is a
            // first name or initial (we don't support "Dr. Smith, John")
            if words.len() > 1 {
                let stripped_anything = title::strip_prefix_title(&mut words, true);
                found_first_name_or_initial = stripped_anything;
            }

            // Strip non-comma-separated titles & suffixes (e.g. "John Smith Jr.")
            strip_postfixes_and_find_suffix(&mut words, false, &mut postfixes);

            if !found_first_name_or_initial {
                found_first_name_or_initial = surname::find_surname_index(&*words) > 0;
            }
        }
        else if found_first_name_or_initial {
            // We already found the full name, so this is a comma-separated
            // postfix title or suffix
            postfixes.extend(NamePart::all_from_text(part, mixed_case, Location::End));
        }
        else {
            // We already processed one comma-separated part, which may
            // have been the surname (if this is the given name), or the full
            // name (if this is a suffix or title)
            let mut given_middle_or_postfix_words: Vec<NamePart> =
                NamePart::all_from_text(part, mixed_case, Location::Start).collect();
            if given_middle_or_postfix_words.is_empty() { continue }

            // Check for (unusual) formats like "Smith, Dr. John M."
            if !found_first_name_or_initial && given_middle_or_postfix_words.len() > 1 {
                let stripped_anything = title::strip_prefix_title(&mut given_middle_or_postfix_words, false);
                found_first_name_or_initial = stripped_anything;
            }

            // Check for (more common) formats like "Smith, John" or "Smith, J. M."
            if !found_first_name_or_initial {
                let word = given_middle_or_postfix_words.first().unwrap();
                if word.is_namelike() {
                    found_first_name_or_initial = true;
                } else if word.is_initials() {
                    // Handle a special case like "Ben Smith, III" or "John E Smith,
                    // M.D.", where we might have mistakenly classified the whole
                    // first comma-separated part as a surname (due to the "ben"
                    // prefix and "e" conjunction rules respectively)
                    found_first_name_or_initial = words.len() == 1 ||
                        given_middle_or_postfix_words.iter().any( |word|
                            !suffix::is_suffix(word) && !title::is_postfix_title(word)
                        );
                }
            }

            // Now we've decided: either this is the given name or first initial,
            // in which case we put it in front, or it's a suffix or title
            if found_first_name_or_initial {
                // Check for (unusual) formats like "Smith, John Jr."
                strip_postfixes_and_find_suffix(&mut given_middle_or_postfix_words, true, &mut postfixes);

                let surname_words = words;
                words = given_middle_or_postfix_words;
                surname_index = words.len();
                words.extend(surname_words);
            }
            else {
                postfixes.extend(given_middle_or_postfix_words);
            }
        }
    }

    // If there are two or fewer words, e.g. "JOHN MA", we treat
    // ambiguous strings like "MA" as surnames rather than titles
    // (not initials, which should only be at the end of the input
    // if they are comma-separated, and we already handled that case)
    if words.len() < 2 && !postfixes.is_empty() && postfixes[0].is_namelike() {
        words.push(postfixes.remove(0));
    }

    // Anything trailing that looks like initials is probably a stray suffix
    while !words.is_empty() && words.last().unwrap().is_initials() {
        words.pop();
    }

    if words.len() < 2 {
        // Failed parse
        return (words, 0);
    }

    if surname_index <= 0 || surname_index >= words.len() {
        // We didn't get the surname from the formatting (e.g. "Smith, John"),
        // so we have to guess it
        surname_index = surname::find_surname_index(&words[1..]) + 1;
    }

    (words, surname_index)
}

impl Name {
    pub fn parse(name: &str) -> Option<Name> {
        if !name.chars().any(char::is_alphabetic) {
            return None
        }

        let mixed_case = is_mixed_case(name);
        let name = nickname::strip_nickname(name);
        let (words, surname_index) = name_words_and_surname_index(&name, mixed_case);

        if words.len() < 2 {
            // We need at least a first and last name, or we can't tell which we have
            return None;
        }
        else if words[surname_index..].iter().all( |w| !w.is_namelike() ) {
            // Looks like a bad parse, since the surname doesn't make sense
            return None;
        }

        // Take the remaining words, and strip out the initials (if present;
        // only allow one block of initials) and the first name (if present),
        // and whatever's left are the middle names
        let mut given_name: Option<String> = None;
        let mut middle_names: Vec<&str> = Vec::new();
        let mut middle_initials = String::new();

        for (i, word) in words[0..surname_index].iter().enumerate() {
            if word.is_initials() {
                let start = if i == 0 { 1 } else { 0 };
                if word.chars > start {
                    middle_initials.extend(
                        word.word
                            .chars()
                            .filter( |c| c.is_alphabetic() )
                            .skip(start)
                            .filter_map( |w| w.to_uppercase().next() ));
                }
            } else if given_name.is_none() {
                given_name = Some(word.namecased.to_string());
            } else {
                middle_names.push(&*word.namecased);
                middle_initials.push(word.initial());
            }
        }

        let middle_names =
            if middle_names.is_empty() {
                None
            } else {
                Some(middle_names.join(" "))
            };

        let middle_initials =
            if middle_initials.is_empty() {
                None
            } else {
                Some(middle_initials)
            };

        let surname = words[surname_index..]
            .iter()
            .map( |w| &*w.namecased )
            .join(" ");

        Some(Name {
            first_initial: words[0].initial(),
            given_name: given_name,
            surname: surname,
            middle_names: middle_names,
            middle_initials: middle_initials,
        })
    }

    pub fn display(&self) -> String {
        match self.given_name {
            Some(ref name) => {
                format!("{} {}", name, self.surname)
            }
            None => {
                format!("{}. {}", self.first_initial, self.surname)
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(associated_consts)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(plugin)]

#![plugin(clippy)]

extern crate uuid;
extern crate jsrs_common;
extern crate js_types;

#[macro_use] extern crate matches;

pub mod alloc;
mod gc_error;
mod scope;
mod test_utils;

use std::cell::RefCell;
use std::mem;
use std::rc::Rc;

use jsrs_common::ast::Exp;
use js_types::js_var::{JsPtrEnum, JsVar};
use js_types::binding::Binding;

use alloc::AllocBox;
use gc_error::{GcError, Result};
use scope::{Scope, ScopeTag};

pub struct ScopeManager {
    globals: Scope,
    curr_scope: Scope,
    closures: Vec<Scope>,
    alloc_box: Rc<RefCell<AllocBox>>,
}

impl ScopeManager {
    fn new(alloc_box: Rc<RefCell<AllocBox>>) -> ScopeManager {
        ScopeManager {
            globals: Scope::new(ScopeTag::Call, &alloc_box),
            curr_scope: Scope::new(ScopeTag::Call, &alloc_box),
            closures: Vec::new(),
            alloc_box: alloc_box,
        }
    }

    pub fn push_scope(&mut self, exp: &Exp) {
        let tag = match *exp {
            Exp::Call(..) => ScopeTag::Call,
            _ => ScopeTag::Block,
        };
        let parent = mem::replace(&mut self.curr_scope, Scope::new(tag, &self.alloc_box));
        self.curr_scope.set_parent(parent);
    }

    pub fn pop_scope(&mut self, gc_yield: bool) -> Result<()> {
        let parent = try!(self.curr_scope.transfer_stack(&mut self.closures, gc_yield));
        if let Some(parent) = parent {
            mem::replace(&mut self.curr_scope, *parent);
            Ok(())
        } else {
            Err(GcError::Scope)
        }
    }

    pub fn alloc(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> Result<()> {
        self.curr_scope.push_var(var, ptr)
    }

    /// Try to load the variable behind a binding
    pub fn load(&self, bnd: &Binding) -> Result<(JsVar, Option<JsPtrEnum>)> {
        self.curr_scope.get_var_copy(bnd)
                       // Binding lookup failed locally, so check the root
                       // scope (globals)
                       .or(self.globals.get_var_copy(bnd))
                       .ok_or_else(|| GcError::Load(bnd.clone()))
    }

    pub fn store(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> Result<()> {
        let update = self.curr_scope.update_var(var, ptr);
        if let Err(GcError::Store(var, ptr)) = update{
            self.globals.update_var(var, ptr)
        } else {
            update
        }
    }
}

pub fn init_gc() -> ScopeManager {
    let alloc_box = Rc::new(RefCell::new(AllocBox::new()));
    ScopeManager::new(alloc_box)
}

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

    use jsrs_common::ast::Exp;
    use js_types::js_var::JsType;
    use js_types::binding::Binding;

    use gc_error::GcError;
    use test_utils;

    #[test]
    fn test_pop_scope() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        mgr.push_scope(&Exp::Undefined);
        assert!(mgr.curr_scope.parent.is_some());
        mgr.pop_scope(false).unwrap();
        assert!(mgr.curr_scope.parent.is_none());
    }

    #[test]
    fn test_pop_scope_fail() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        let res = mgr.pop_scope(false);
        assert!(res.is_err());
        assert!(matches!(res, Err(GcError::Scope)));
    }

    #[test]
    fn test_alloc() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        mgr.alloc(test_utils::make_num(1.), None).unwrap();
        mgr.push_scope(&Exp::Undefined);
        mgr.alloc(test_utils::make_num(2.), None).unwrap();
        assert!(mgr.alloc_box.borrow().is_empty());
    }

    #[test]
    fn test_load() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        let x = test_utils::make_num(1.);
        let x_bnd = x.binding.clone();
        mgr.alloc(x, None).unwrap();
        let load = mgr.load(&x_bnd);
        assert!(load.is_ok());
        let load = load.unwrap();
        match load.0.t {
            JsType::JsNum(n) => assert!(f64::abs(n - 1.) < 0.0001),
            _ => unreachable!(),
        }
        assert!(load.1.is_none());
    }

    #[test]
    fn test_load_fail() {
        let alloc_box = test_utils::make_alloc_box();
        let mgr = ScopeManager::new(alloc_box);
        let bnd = Binding::anon();
        let res = mgr.load(&bnd);
        assert!(res.is_err());
        assert!(matches!(res, Err(GcError::Load(_))));
        if let Err(GcError::Load(res_bnd)) = res {
            assert_eq!(bnd, res_bnd);
        }
    }

    #[test]
    fn test_store() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box,);
        mgr.push_scope(&Exp::Undefined);
        let x = test_utils::make_num(1.);
        let x_bnd = x.binding.clone();
        mgr.alloc(x, None).unwrap();

        let (mut var, _) = mgr.load(&x_bnd).unwrap();
        var.t = JsType::JsNum(2.);

        assert!(mgr.store(var, None).is_ok());
    }

}
<commit_msg>Correctly handle updating a variable that hasn't been declared<commit_after>#![feature(associated_consts)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(plugin)]

#![plugin(clippy)]

extern crate uuid;
extern crate jsrs_common;
extern crate js_types;

#[macro_use] extern crate matches;

pub mod alloc;
mod gc_error;
mod scope;
mod test_utils;

use std::cell::RefCell;
use std::mem;
use std::rc::Rc;

use jsrs_common::ast::Exp;
use js_types::js_var::{JsPtrEnum, JsVar};
use js_types::binding::Binding;

use alloc::AllocBox;
use gc_error::{GcError, Result};
use scope::{Scope, ScopeTag};

pub struct ScopeManager {
    globals: Scope,
    curr_scope: Scope,
    closures: Vec<Scope>,
    alloc_box: Rc<RefCell<AllocBox>>,
}

impl ScopeManager {
    fn new(alloc_box: Rc<RefCell<AllocBox>>) -> ScopeManager {
        ScopeManager {
            globals: Scope::new(ScopeTag::Call, &alloc_box),
            curr_scope: Scope::new(ScopeTag::Call, &alloc_box),
            closures: Vec::new(),
            alloc_box: alloc_box,
        }
    }

    pub fn push_scope(&mut self, exp: &Exp) {
        let tag = match *exp {
            Exp::Call(..) => ScopeTag::Call,
            _ => ScopeTag::Block,
        };
        let parent = mem::replace(&mut self.curr_scope, Scope::new(tag, &self.alloc_box));
        self.curr_scope.set_parent(parent);
    }

    pub fn pop_scope(&mut self, gc_yield: bool) -> Result<()> {
        let parent = try!(self.curr_scope.transfer_stack(&mut self.closures, gc_yield));
        if let Some(parent) = parent {
            mem::replace(&mut self.curr_scope, *parent);
            Ok(())
        } else {
            Err(GcError::Scope)
        }
    }

    pub fn alloc(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> Result<()> {
        self.curr_scope.push_var(var, ptr)
    }

    /// Try to load the variable behind a binding
    pub fn load(&self, bnd: &Binding) -> Result<(JsVar, Option<JsPtrEnum>)> {
        self.curr_scope.get_var_copy(bnd)
                       // Binding lookup failed locally, so check the root
                       // scope (globals)
                       .or(self.globals.get_var_copy(bnd))
                       .ok_or_else(|| GcError::Load(bnd.clone()))
    }

    pub fn store(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> Result<()> {
        let update = self.curr_scope.update_var(var, ptr);
        if let Err(GcError::Store(var, ptr)) = update {
            self.alloc(var, ptr)
        } else {
            update
        }
    }
}

pub fn init_gc() -> ScopeManager {
    let alloc_box = Rc::new(RefCell::new(AllocBox::new()));
    ScopeManager::new(alloc_box)
}

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

    use jsrs_common::ast::Exp;
    use js_types::js_var::JsType;
    use js_types::binding::Binding;

    use gc_error::GcError;
    use test_utils;

    #[test]
    fn test_pop_scope() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        mgr.push_scope(&Exp::Undefined);
        assert!(mgr.curr_scope.parent.is_some());
        mgr.pop_scope(false).unwrap();
        assert!(mgr.curr_scope.parent.is_none());
    }

    #[test]
    fn test_pop_scope_fail() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        let res = mgr.pop_scope(false);
        assert!(res.is_err());
        assert!(matches!(res, Err(GcError::Scope)));
    }

    #[test]
    fn test_alloc() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        mgr.alloc(test_utils::make_num(1.), None).unwrap();
        mgr.push_scope(&Exp::Undefined);
        mgr.alloc(test_utils::make_num(2.), None).unwrap();
        assert!(mgr.alloc_box.borrow().is_empty());
    }

    #[test]
    fn test_load() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box);
        let x = test_utils::make_num(1.);
        let x_bnd = x.binding.clone();
        mgr.alloc(x, None).unwrap();
        let load = mgr.load(&x_bnd);
        assert!(load.is_ok());
        let load = load.unwrap();
        match load.0.t {
            JsType::JsNum(n) => assert!(f64::abs(n - 1.) < 0.0001),
            _ => unreachable!(),
        }
        assert!(load.1.is_none());
    }

    #[test]
    fn test_load_fail() {
        let alloc_box = test_utils::make_alloc_box();
        let mgr = ScopeManager::new(alloc_box);
        let bnd = Binding::anon();
        let res = mgr.load(&bnd);
        assert!(res.is_err());
        assert!(matches!(res, Err(GcError::Load(_))));
        if let Err(GcError::Load(res_bnd)) = res {
            assert_eq!(bnd, res_bnd);
        }
    }

    #[test]
    fn test_store() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box,);
        mgr.push_scope(&Exp::Undefined);
        let x = test_utils::make_num(1.);
        let x_bnd = x.binding.clone();
        mgr.alloc(x, None).unwrap();

        let (mut var, _) = mgr.load(&x_bnd).unwrap();
        var.t = JsType::JsNum(2.);

        assert!(mgr.store(var, None).is_ok());
    }

    #[test]
    fn test_store_failed_store() {
        let alloc_box = test_utils::make_alloc_box();
        let mut mgr = ScopeManager::new(alloc_box,);
        let x = test_utils::make_num(1.);
        let x_bnd = x.binding.clone();
        assert!(mgr.store(x, None).is_ok());

        let load = mgr.load(&x_bnd);
        assert!(load.is_ok());
        let (var, ptr) = load.unwrap();

        assert!(matches!(var.t, JsType::JsNum(1.)));
        assert!(ptr.is_none());
    }

}
<|endoftext|>


<commit_before>//! ### rust-mysql-simple
//! Mysql client library implemented in rust nightly.
//!
//! #### Install
//! Just include another `[dependencies.*]` section into your Cargo.toml:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! ```
//!
//! rust-mysql-simple offer support of SSL via `ssl` cargo feature which is enabled by default. If you have no plans to use SSL, then you should disable that feature to not to depend on rust-openssl:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! default-features = false
//! ```
//!
//! #### Use
//! You should start by creating [`MyOpts`](conn/struct.MyOpts.html) struct.
//!
//! Then you can create [`MyPool`](conn/pool/struct.MyPool.html) which should be
//! enough to work with mysql server.
#![crate_name="mysql"]
#![crate_type="rlib"]
#![crate_type="dylib"]

#![feature(unsafe_destructor)]
#![feature(phase)]
#![feature(slicing_syntax)]
#![feature(associated_types)]

#![allow(dead_code)]
#![feature(macro_rules)]

#[cfg(test)]
extern crate test;

#[cfg(test)]
#[phase(plugin)]
extern crate stainless;

extern crate core;
extern crate time;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate regex;
#[phase(plugin)]
extern crate regex_macros;

#[phase(plugin)]
extern crate lazy_static;

mod scramble;
pub mod consts;
pub mod error;
mod packet;
mod io;
pub mod value;
pub mod conn;
<commit_msg>Update for rust nightly<commit_after>//! ### rust-mysql-simple
//! Mysql client library implemented in rust nightly.
//!
//! #### Install
//! Just include another `[dependencies.*]` section into your Cargo.toml:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! ```
//!
//! rust-mysql-simple offer support of SSL via `ssl` cargo feature which is enabled by default. If you have no plans to use SSL, then you should disable that feature to not to depend on rust-openssl:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! default-features = false
//! ```
//!
//! #### Use
//! You should start by creating [`MyOpts`](conn/struct.MyOpts.html) struct.
//!
//! Then you can create [`MyPool`](conn/pool/struct.MyPool.html) which should be
//! enough to work with mysql server.
#![crate_name="mysql"]
#![crate_type="rlib"]
#![crate_type="dylib"]

#![feature(unsafe_destructor)]
#![feature(phase)]
#![feature(slicing_syntax)]
#![feature(plugin)]

#![allow(dead_code)]

#[cfg(test)]
extern crate test;

#[cfg(test)]
#[plugin]
extern crate stainless;

extern crate core;
extern crate time;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate regex;
#[plugin] #[no_link]
extern crate regex_macros;
#[macro_use]
extern crate lazy_static;

mod scramble;
pub mod consts;
pub mod error;
mod packet;
mod io;
pub mod value;
pub mod conn;
<|endoftext|>


<commit_before>//! Z80 emulation library
extern crate libc;
mod z80e_core;
use libc::{ c_void, c_int };

/// An interface for a 16-bit addressed container of bytes.
pub trait Z80Memory {
    fn read_byte(&mut self, address: u16) -> u8;
    fn write_byte(&mut self, address: u16, value: u8);
}

impl Z80Memory for Vec<u8> {
    fn read_byte(&mut self, address: u16) -> u8 {
        self[address as usize]
    }
    fn write_byte(&mut self, address: u16, value: u8) {
        self[address as usize] = value;
    }
}

impl Z80Memory for [u8; 0x10000] {
    fn read_byte(&mut self, address: u16) -> u8 {
        self[address as usize]
    }
    fn write_byte(&mut self, address: u16, value: u8) {
        self[address as usize] = value;
    }
}

extern fn read_z80_memory<T: Z80Memory>(memory: *mut c_void, address: u16) -> u8 {
    let memory: &mut T = unsafe { &mut *(memory as *mut T) };
    memory.read_byte(address)
}

extern fn write_z80_memory<T: Z80Memory>(memory: *mut c_void, address: u16, value: u8) {
    let memory: &mut T = unsafe { &mut *(memory as *mut T) };
    memory.write_byte(address, value)
}

/// An interface for implementing one Z80 I/O port.
pub trait Z80IODevice {
    fn read_in(&mut self) -> u8;
    fn write_out(&mut self, value: u8);
}

extern fn read_z80_device<T: Z80IODevice>(device: *mut c_void) -> u8 {
    let device: &mut T = unsafe { &mut *(device as *mut T) };
    device.read_in()
}

extern fn write_z80_device<T: Z80IODevice>(device: *mut c_void, value: u8) {
    let device: &mut T = unsafe { &mut *(device as *mut T) };
    device.write_out(value)
}

/// Z80 CPU implementation.
pub struct Z80 {
    core: *mut z80e_core::z80e_cpu,
}

impl Z80 {
    /// Allocate a new Z80 core and install its memory.
    pub fn new<T: Z80Memory>(memory: &mut T) -> Self {
        unsafe {
            let cpu = Z80 {
                core: z80e_core::cpu_init(),
            };
            (*cpu.core).memory = (memory as *mut _) as *mut c_void;
            (*cpu.core).read_byte = read_z80_memory::<T>;
            (*cpu.core).write_byte = write_z80_memory::<T>;
            cpu
        }
    }
    /// Install a device on a Z80 I/O port.
    pub fn install_device<T: Z80IODevice>(&mut self, port: u8, device: &mut T) {
        let port: usize = port as usize;
        unsafe {
            (*self.core).devices[port].device = (device as *mut _) as *mut c_void;
            (*self.core).devices[port].read_in = read_z80_device::<T>;
            (*self.core).devices[port].write_out = write_z80_device::<T>;
        }
    }
    pub fn execute(&mut self, cycles: u32) -> u32 {
        unsafe {
            z80e_core::cpu_execute(self.core, cycles as c_int) as u32
        }
    }
}

#[test]
fn it_works() {
}
<commit_msg>impl Drop for Z80<commit_after>//! Z80 emulation library
extern crate libc;
mod z80e_core;
use libc::{ c_void, c_int };

/// An interface for a 16-bit addressed container of bytes.
pub trait Z80Memory {
    fn read_byte(&mut self, address: u16) -> u8;
    fn write_byte(&mut self, address: u16, value: u8);
}

impl Z80Memory for Vec<u8> {
    fn read_byte(&mut self, address: u16) -> u8 {
        self[address as usize]
    }
    fn write_byte(&mut self, address: u16, value: u8) {
        self[address as usize] = value;
    }
}

impl Z80Memory for [u8; 0x10000] {
    fn read_byte(&mut self, address: u16) -> u8 {
        self[address as usize]
    }
    fn write_byte(&mut self, address: u16, value: u8) {
        self[address as usize] = value;
    }
}

extern fn read_z80_memory<T: Z80Memory>(memory: *mut c_void, address: u16) -> u8 {
    let memory: &mut T = unsafe { &mut *(memory as *mut T) };
    memory.read_byte(address)
}

extern fn write_z80_memory<T: Z80Memory>(memory: *mut c_void, address: u16, value: u8) {
    let memory: &mut T = unsafe { &mut *(memory as *mut T) };
    memory.write_byte(address, value)
}

/// An interface for implementing one Z80 I/O port.
pub trait Z80IODevice {
    fn read_in(&mut self) -> u8;
    fn write_out(&mut self, value: u8);
}

extern fn read_z80_device<T: Z80IODevice>(device: *mut c_void) -> u8 {
    let device: &mut T = unsafe { &mut *(device as *mut T) };
    device.read_in()
}

extern fn write_z80_device<T: Z80IODevice>(device: *mut c_void, value: u8) {
    let device: &mut T = unsafe { &mut *(device as *mut T) };
    device.write_out(value)
}

/// Z80 CPU implementation.
pub struct Z80 {
    core: *mut z80e_core::z80e_cpu,
}

impl Z80 {
    /// Allocate a new Z80 core and install its memory.
    pub fn new<T: Z80Memory>(memory: &mut T) -> Self {
        unsafe {
            let cpu = Z80 {
                core: z80e_core::cpu_init(),
            };
            (*cpu.core).memory = (memory as *mut _) as *mut c_void;
            (*cpu.core).read_byte = read_z80_memory::<T>;
            (*cpu.core).write_byte = write_z80_memory::<T>;
            cpu
        }
    }
    /// Install a device on a Z80 I/O port.
    pub fn install_device<T: Z80IODevice>(&mut self, port: u8, device: &mut T) {
        let port: usize = port as usize;
        unsafe {
            (*self.core).devices[port].device = (device as *mut _) as *mut c_void;
            (*self.core).devices[port].read_in = read_z80_device::<T>;
            (*self.core).devices[port].write_out = write_z80_device::<T>;
        }
    }
    pub fn execute(&mut self, cycles: u32) -> u32 {
        unsafe {
            z80e_core::cpu_execute(self.core, cycles as c_int) as u32
        }
    }
}

impl Drop for Z80 {
    fn drop(&mut self) {
        unsafe {
            z80e_core::cpu_free(self.core);
        }
    }
}

#[test]
fn it_works() {
}
<|endoftext|>


<commit_before>#[cfg(test)]
#[macro_use]
extern crate quickcheck;
#[cfg(test)]
extern crate rand;

pub mod set;
pub mod map;
mod tree;

pub use set::Set;
pub use map::Map;

#[derive(Clone, Debug)]
pub enum Bound<T> {
    Unbounded,
    Included(T),
    Excluded(T)
}
<commit_msg>More derived traits for Bound<commit_after>#[cfg(test)]
#[macro_use]
extern crate quickcheck;
#[cfg(test)]
extern crate rand;

pub mod set;
pub mod map;
mod tree;

pub use set::Set;
pub use map::Map;

#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum Bound<T> {
    Unbounded,
    Included(T),
    Excluded(T)
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/pipe/0.4.0")]
#![cfg_attr(feature = "unstable-doc-cfg", feature(doc_cfg))]

//! Synchronous in-memory pipe
//!
//! ## Example
//!
//! ```
//! use std::thread::spawn;
//! use std::io::{Read, Write};
//!
//! let (mut read, mut write) = pipe::pipe();
//!
//! let message = "Hello, world!";
//! spawn(move || write.write_all(message.as_bytes()).unwrap());
//!
//! let mut s = String::new();
//! read.read_to_string(&mut s).unwrap();
//!
//! assert_eq!(&s, message);
//! ```

#[cfg(feature="readwrite")]
extern crate readwrite;
extern crate crossbeam_channel;

use crossbeam_channel::{Sender, Receiver};
use std::io::{self, BufRead, Read, Write};
use std::cmp::min;

/// The `Read` end of a pipe (see `pipe()`)
pub struct PipeReader {
    receiver: Receiver<Vec<u8>>,
    buffer: Vec<u8>,
    position: usize,
}

/// The `Write` end of a pipe (see `pipe()`)
#[derive(Clone)]
pub struct PipeWriter {
    sender: Sender<Vec<u8>>
}

/// Creates a synchronous memory pipe
pub fn pipe() -> (PipeReader, PipeWriter) {
    let (sender, receiver) = crossbeam_channel::bounded(0);

    (
        PipeReader { receiver, buffer: Vec::new(), position: 0 },
        PipeWriter { sender },
    )
}

/// Creates a pair of pipes for bidirectional communication, a bit like UNIX's `socketpair(2)`.
#[cfg(feature = "bidirectional")]
#[cfg_attr(feature = "unstable-doc-cfg", doc(cfg(feature = "bidirectional")))]
pub fn bipipe() -> (readwrite::ReadWrite<PipeReader, PipeWriter>, readwrite::ReadWrite<PipeReader, PipeWriter>) {
    let (r1,w1) = pipe();
    let (r2,w2) = pipe();
    ((r1,w2).into(), (r2,w1).into())
}

impl PipeWriter {
    /// Extracts the inner `SyncSender` from the writer
    pub fn into_inner(self) -> Sender<Vec<u8>> {
        self.sender
    }
}

impl PipeReader {
    /// Extracts the inner `Receiver` from the writer, and any pending buffered data
    pub fn into_inner(mut self) -> (Receiver<Vec<u8>>, Vec<u8>) {
        self.buffer.drain(..self.position);
        (self.receiver, self.buffer)
    }
}

impl BufRead for PipeReader {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        while self.position >= self.buffer.len() {
            match self.receiver.recv() {
                // The only existing error is EOF
                Err(_) => break,
                Ok(data) => {
                    self.buffer = data;
                    self.position = 0;
                }
            }
        }

        Ok(&self.buffer[self.position..])
    }

    fn consume(&mut self, amt: usize) {
        debug_assert!(self.buffer.len() - self.position >= amt);
        self.position += amt
    }
}

impl Read for PipeReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }

        let internal = self.fill_buf()?;

        let len = min(buf.len(), internal.len());
        if len > 0 {
            buf[..len].copy_from_slice(&internal[..len]);
            self.consume(len);
        }
        Ok(len)
    }
}

impl Write for PipeWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let data = buf.to_vec();

        self.sender.send(data)
            .map(|_| buf.len())
            .map_err(|_| io::Error::new(io::ErrorKind::BrokenPipe, "pipe reader has been dropped"))
    }

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

#[cfg(test)]
mod tests {
    use std::thread::spawn;
    use std::io::{Read, Write};
    use super::*;

    #[test]
    fn pipe_reader() {
        let i = b"hello there";
        let mut o = Vec::with_capacity(i.len());
        let (mut r, mut w) = pipe();
        let guard = spawn(move || {
            w.write_all(&i[..5]).unwrap();
            w.write_all(&i[5..]).unwrap();
            drop(w);
        });

        r.read_to_end(&mut o).unwrap();
        assert_eq!(i, &o[..]);

        guard.join().unwrap();
    }

    #[test]
    fn pipe_writer_fail() {
        let i = b"hi";
        let (r, mut w) = pipe();
        let guard = spawn(move || {
            drop(r);
        });

        assert!(w.write_all(i).is_err());

        guard.join().unwrap();
    }

    #[test]
    fn small_reads() {
        let block_cnt = 20;
        const BLOCK: usize = 20;
        let (mut r, mut w) = pipe();
        let guard = spawn(move || {
            for _ in 0..block_cnt {
                let data = &[0; BLOCK];
                w.write_all(data).unwrap();
            }
        });

        let mut buff = [0; BLOCK / 2];
        let mut read = 0;
        while let Ok(size) = r.read(&mut buff) {
            // 0 means EOF
            if size == 0 {
                break;
            }
            read += size;
        }
        assert_eq!(block_cnt * BLOCK, read);

        guard.join().unwrap();
    }
}
<commit_msg>impl Write for &PipeWriter<commit_after>#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/pipe/0.4.0")]
#![cfg_attr(feature = "unstable-doc-cfg", feature(doc_cfg))]

//! Synchronous in-memory pipe
//!
//! ## Example
//!
//! ```
//! use std::thread::spawn;
//! use std::io::{Read, Write};
//!
//! let (mut read, mut write) = pipe::pipe();
//!
//! let message = "Hello, world!";
//! spawn(move || write.write_all(message.as_bytes()).unwrap());
//!
//! let mut s = String::new();
//! read.read_to_string(&mut s).unwrap();
//!
//! assert_eq!(&s, message);
//! ```

#[cfg(feature="readwrite")]
extern crate readwrite;
extern crate crossbeam_channel;

use crossbeam_channel::{Sender, Receiver};
use std::io::{self, BufRead, Read, Write};
use std::cmp::min;

/// The `Read` end of a pipe (see `pipe()`)
pub struct PipeReader {
    receiver: Receiver<Vec<u8>>,
    buffer: Vec<u8>,
    position: usize,
}

/// The `Write` end of a pipe (see `pipe()`)
#[derive(Clone)]
pub struct PipeWriter {
    sender: Sender<Vec<u8>>
}

/// Creates a synchronous memory pipe
pub fn pipe() -> (PipeReader, PipeWriter) {
    let (sender, receiver) = crossbeam_channel::bounded(0);

    (
        PipeReader { receiver, buffer: Vec::new(), position: 0 },
        PipeWriter { sender },
    )
}

/// Creates a pair of pipes for bidirectional communication, a bit like UNIX's `socketpair(2)`.
#[cfg(feature = "bidirectional")]
#[cfg_attr(feature = "unstable-doc-cfg", doc(cfg(feature = "bidirectional")))]
pub fn bipipe() -> (readwrite::ReadWrite<PipeReader, PipeWriter>, readwrite::ReadWrite<PipeReader, PipeWriter>) {
    let (r1,w1) = pipe();
    let (r2,w2) = pipe();
    ((r1,w2).into(), (r2,w1).into())
}

impl PipeWriter {
    /// Extracts the inner `SyncSender` from the writer
    pub fn into_inner(self) -> Sender<Vec<u8>> {
        self.sender
    }
}

impl PipeReader {
    /// Extracts the inner `Receiver` from the writer, and any pending buffered data
    pub fn into_inner(mut self) -> (Receiver<Vec<u8>>, Vec<u8>) {
        self.buffer.drain(..self.position);
        (self.receiver, self.buffer)
    }
}

impl BufRead for PipeReader {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        while self.position >= self.buffer.len() {
            match self.receiver.recv() {
                // The only existing error is EOF
                Err(_) => break,
                Ok(data) => {
                    self.buffer = data;
                    self.position = 0;
                }
            }
        }

        Ok(&self.buffer[self.position..])
    }

    fn consume(&mut self, amt: usize) {
        debug_assert!(self.buffer.len() - self.position >= amt);
        self.position += amt
    }
}

impl Read for PipeReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }

        let internal = self.fill_buf()?;

        let len = min(buf.len(), internal.len());
        if len > 0 {
            buf[..len].copy_from_slice(&internal[..len]);
            self.consume(len);
        }
        Ok(len)
    }
}

impl Write for &'_ PipeWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let data = buf.to_vec();

        self.sender.send(data)
            .map(|_| buf.len())
            .map_err(|_| io::Error::new(io::ErrorKind::BrokenPipe, "pipe reader has been dropped"))
    }

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

impl Write for PipeWriter {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        Write::write(&mut &*self, buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        Write::flush(&mut &*self)
    }
}

#[cfg(test)]
mod tests {
    use std::thread::spawn;
    use std::io::{Read, Write};
    use super::*;

    #[test]
    fn pipe_reader() {
        let i = b"hello there";
        let mut o = Vec::with_capacity(i.len());
        let (mut r, mut w) = pipe();
        let guard = spawn(move || {
            w.write_all(&i[..5]).unwrap();
            w.write_all(&i[5..]).unwrap();
            drop(w);
        });

        r.read_to_end(&mut o).unwrap();
        assert_eq!(i, &o[..]);

        guard.join().unwrap();
    }

    #[test]
    fn pipe_writer_fail() {
        let i = b"hi";
        let (r, mut w) = pipe();
        let guard = spawn(move || {
            drop(r);
        });

        assert!(w.write_all(i).is_err());

        guard.join().unwrap();
    }

    #[test]
    fn small_reads() {
        let block_cnt = 20;
        const BLOCK: usize = 20;
        let (mut r, mut w) = pipe();
        let guard = spawn(move || {
            for _ in 0..block_cnt {
                let data = &[0; BLOCK];
                w.write_all(data).unwrap();
            }
        });

        let mut buff = [0; BLOCK / 2];
        let mut read = 0;
        while let Ok(size) = r.read(&mut buff) {
            // 0 means EOF
            if size == 0 {
                break;
            }
            read += size;
        }
        assert_eq!(block_cnt * BLOCK, read);

        guard.join().unwrap();
    }
}
<|endoftext|>


<commit_before>
pub fn puzzle(input: &str) -> usize {
    let initial_world_state = WorldState {
        steps: 0,
        elevator_floor: 0,
    };
    let mut queue = vec![initial_world_state];
    while !queue.is_empty() {
        let world = queue.remove(0);

    }

    panic!("Exhausted all possible moves without finding end condition!");

}

pub struct WorldState {
    steps: u32,
    elevator_floor: usize,
}

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

}
<commit_msg>Set up fns I wish I had for checking for end state<commit_after>
pub fn puzzle(input: &str) -> u32 {
    let initial_world_state = WorldState {
        steps: 0,
        elevator_floor: 0,
    };
    let mut queue = vec![initial_world_state];
    while !queue.is_empty() {
        let world = queue.remove(0);
        if world.in_end_state() {
            return world.steps;
        }

    }

    panic!("Exhausted all possible moves without finding end condition!");

}

pub struct WorldState {
    steps: u32,
    elevator_floor: usize,
}

impl WorldState {
    pub fn in_end_state(&self) -> bool {
        true
    }
}

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

}
<|endoftext|>