<commit_before>// Copyright 2017 The rust-url developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

This crate provides wrappers and convenience functions to make rust-url
and Serde work hand in hand.

The supported types are:

* `url::Url`

# How do I use a data type with a `Url` member with Serde?

Use the serde attributes `deserialize_with` and `serialize_with`.

```
#[derive(serde::Serialize, serde::Deserialize)]
struct MyStruct {
    #[serde(serialize_with = "serialize")]
    url: Url,
}
```

# How do I encode a `Url` value with `serde_json::to_string`?

Use the `Ser` wrapper.

```
serde_json::to_string(&Ser::new(&url))
```

# How do I decode a `Url` value with `serde_json::parse`?

Use the `De` wrapper.

```
serde_json::from_str(r"http:://www.rust-lang.org").map(De::into_inner)
```

# How do I send `Url` values as part of an IPC channel?

Use the `Serde` wrapper. It implements `Deref` and `DerefMut` for convenience.

```
ipc::channel::<Serde<Url>>()
```
*/

#![deny(missing_docs)]
#![deny(unsafe_code)]

extern crate serde;
#[cfg(test)] #[macro_use] extern crate serde_derive;
#[cfg(test)] extern crate serde_json;
extern crate url;

use serde::{Deserialize, Serialize, Serializer, Deserializer};
use std::cmp::PartialEq;
use std::error::Error;
use std::fmt;
use std::io::Write;
use std::ops::{Deref, DerefMut};
use std::str;
use url::{Url, Host};

/// Serialises `value` with a given serializer.
///
/// This is useful to serialize `rust-url` types used in structure fields or
/// tuple members with `#[serde(serialize_with = "url_serde::serialize")]`.
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer, for<'a> Ser<'a, T>: Serialize
{
    Ser::new(value).serialize(serializer)
}

/// A wrapper to serialize `rust-url` types.
///
/// This is useful with functions such as `serde_json::to_string`.
///
/// Values of this type can only be passed to the `serde::Serialize` trait.
#[derive(Debug)]
pub struct Ser<'a, T: 'a>(&'a T);

impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
    /// Returns a new `Ser` wrapper.
    #[inline(always)]
    pub fn new(value: &'a T) -> Self {
        Ser(value)
    }
}

/// Serializes this URL into a `serde` stream.
impl<'a> Serialize for Ser<'a, Url> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        serializer.serialize_str(self.0.as_str())
    }
}

/// Serializes this Option<URL> into a `serde` stream.
impl<'a> Serialize for Ser<'a, Option<Url>> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        if let Some(url) = self.0.as_ref() {
            serializer.serialize_some(url.as_str())
        } else {
            serializer.serialize_none()
        }
    }
}

impl<'a, String> Serialize for Ser<'a, Host<String>> where String: AsRef<str> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        match *self.0 {
            Host::Domain(ref s) => serializer.serialize_str(s.as_ref()),
            Host::Ipv4(_) | Host::Ipv6(_) => {
                // max("101.102.103.104".len(),
                //     "[1000:1002:1003:1004:1005:1006:101.102.103.104]".len())
                const MAX_LEN: usize = 47;
                let mut buffer = [0; MAX_LEN];
                serializer.serialize_str(display_into_buffer(&self.0, &mut buffer))
            }
        }
    }
}

/// Like .to_string(), but doesn’t allocate memory for a `String`.
///
/// Panics if `buffer` is too small.
fn display_into_buffer<'a, T: fmt::Display>(value: &T, buffer: &'a mut [u8]) -> &'a str {
    let remaining_len;
    {
        let mut remaining = &mut *buffer;
        write!(remaining, "{}", value).unwrap();
        remaining_len = remaining.len()
    }
    let written_len = buffer.len() - remaining_len;
    let written = &buffer[..written_len];

    // write! only provides std::fmt::Formatter to Display implementations,
    // which has methods write_str and write_char but no method to write arbitrary bytes.
    // Therefore, `written` is well-formed in UTF-8.
    #[allow(unsafe_code)]
    unsafe {
        str::from_utf8_unchecked(written)
    }
}

/// Deserialises a `T` value with a given deserializer.
///
/// This is useful to deserialize Url types used in structure fields or
/// tuple members with `#[serde(deserialize_with = "url_serde::deserialize")]`.
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where D: Deserializer<'de>, De<T>: Deserialize<'de>
{
    De::deserialize(deserializer).map(De::into_inner)
}

/// A wrapper to deserialize `rust-url` types.
///
/// This is useful with functions such as `serde_json::from_str`.
///
/// Values of this type can only be obtained through
/// the `serde::Deserialize` trait.
#[derive(Debug)]
pub struct De<T>(T);

impl<'de, T> De<T> where De<T>: serde::Deserialize<'de> {
    /// Consumes this wrapper, returning the deserialized value.
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.0
    }
}

/// Deserializes this URL from a `serde` stream.
impl<'de> Deserialize<'de> for De<Url> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let string_representation: String = Deserialize::deserialize(deserializer)?;
        Url::parse(&string_representation).map(De).map_err(|err| {
            serde::de::Error::custom(err.description())
        })
    }
}

/// Deserializes this Option<URL> from a `serde` stream.
impl<'de> Deserialize<'de> for De<Option<Url>> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let option_representation: Option<String> = Deserialize::deserialize(deserializer)?;
        if let Some(s) = option_representation {
            return Url::parse(&s)
                .map(Some)
                .map(De)
                .map_err(|err| {serde::de::Error::custom(err.description())});
        }
        Ok(De(None))

    }
}

impl<'de> Deserialize<'de> for De<Host> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let string_representation: String = Deserialize::deserialize(deserializer)?;
        Host::parse(&string_representation).map(De).map_err(|err| {
            serde::de::Error::custom(err.description())
        })
    }
}

/// A convenience wrapper to be used as a type parameter, for example when
/// a `Vec<T>` or an `HashMap<K, V>` need to be passed to serde.
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct Serde<T>(pub T);

/// A convenience type alias for Serde<Url>.
pub type SerdeUrl = Serde<Url>;

impl<'de, T> Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    /// Consumes this wrapper, returning the inner value.
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<'de, T> fmt::Debug for Serde<T>
where T: fmt::Debug, De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(formatter)
    }
}

impl<'de, T> Deref for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<'de, T> DerefMut for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<'de, T: PartialEq> PartialEq<T> for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn eq(&self, other: &T) -> bool {
        self.0 == *other
    }
}

impl<'de, T> Deserialize<'de> for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        De::deserialize(deserializer).map(De::into_inner).map(Serde)
    }
}

impl<'de, T> Serialize for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        Ser(&self.0).serialize(serializer)
    }
}

#[test]
fn test_ser_de_url() {
    let url = Url::parse("http://www.test.com/foo/bar?$param=bazz").unwrap();
    let s = serde_json::to_string(&Ser::new(&url)).unwrap();
    let new_url: Url = serde_json::from_str(&s).map(De::into_inner).unwrap();
    assert_eq!(url, new_url);
}

#[test]
fn test_derive_deserialize_with_for_url() {
    #[derive(Deserialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(deserialize_with = "deserialize", rename = "_url_")]
        url: Url
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = Test {
        url: Url::parse(url_str).unwrap()
    };
    let json_string = format!(r#"{{"_url_": "{}"}}"#, url_str);
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);

}

#[test]
fn test_derive_deserialize_with_for_option_url() {
    #[derive(Deserialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(deserialize_with = "deserialize", rename = "_url_")]
        url: Option<Url>
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = Test {
        url: Some(Url::parse(url_str).unwrap())
    };
    let json_string = format!(r#"{{"_url_": "{}"}}"#, url_str);
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);

    let expected = Test {
        url: None
    };
    let json_string = r#"{"_url_": null}"#;
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);
}

#[test]
fn test_derive_serialize_with_for_url() {
    #[derive(Serialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(serialize_with = "serialize", rename = "_url_")]
        url: Url
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = format!(r#"{{"_url_":"{}"}}"#, url_str);
    let input = Test {url: Url::parse(url_str).unwrap()};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(expected, got);
}

#[test]
fn test_derive_serialize_with_for_option_url() {
    #[derive(Serialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(serialize_with = "serialize", rename = "_url_")]
        url: Option<Url>
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = format!(r#"{{"_url_":"{}"}}"#, url_str);
    let input = Test {url: Some(Url::parse(url_str).unwrap())};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(expected, got);

    let expected = format!(r#"{{"_url_":null}}"#);
    let input = Test {url: None};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(expected, got);
}

#[test]
fn test_derive_with_for_url() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(with = "self", rename = "_url_")]
        url: Url
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";
    let json_string = format!(r#"{{"_url_":"{}"}}"#, url_str);

    // test deserialization
    let expected = Test {
        url: Url::parse(url_str).unwrap()
    };
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);

    // test serialization
    let input = Test {url: Url::parse(url_str).unwrap()};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(json_string, got);
}

#[test]
fn test_host() {
    for host in &[
        Host::Domain("foo.com".to_owned()),
        Host::Ipv4("127.0.0.1".parse().unwrap()),
        Host::Ipv6("::1".parse().unwrap()),
    ] {
        let json = serde_json::to_string(&Ser(host)).unwrap();
        let de: De<Host> = serde_json::from_str(&json).unwrap();
        assert_eq!(de.into_inner(), *host)
    }
}
<commit_msg>Explicit unnamed member example<commit_after>// Copyright 2017 The rust-url developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

This crate provides wrappers and convenience functions to make rust-url
and Serde work hand in hand.

The supported types are:

* `url::Url`

# How do I use a data type with a `Url` member with Serde?

Use the serde attributes `deserialize_with` and `serialize_with`.

```
#[derive(serde::Serialize, serde::Deserialize)]
struct MyStruct {
    #[serde(serialize_with = "serialize")]
    url: Url,
}
```

# How do I use a data type with an unnamed `Url` member with serde?

Same problem, same solution.

```
#[derive(serde::Serialize, serde::Deserialize)]
enum MyEnum {
    A(#[serde(with = "url_serde")] Url, OtherType),
}
```

# How do I encode a `Url` value with `serde_json::to_string`?

Use the `Ser` wrapper.

```
serde_json::to_string(&Ser::new(&url))
```

# How do I decode a `Url` value with `serde_json::parse`?

Use the `De` wrapper.

```
serde_json::from_str(r"http:://www.rust-lang.org").map(De::into_inner)
```

# How do I send `Url` values as part of an IPC channel?

Use the `Serde` wrapper. It implements `Deref` and `DerefMut` for convenience.

```
ipc::channel::<Serde<Url>>()
```
*/

#![deny(missing_docs)]
#![deny(unsafe_code)]

extern crate serde;
#[cfg(test)] #[macro_use] extern crate serde_derive;
#[cfg(test)] extern crate serde_json;
extern crate url;

use serde::{Deserialize, Serialize, Serializer, Deserializer};
use std::cmp::PartialEq;
use std::error::Error;
use std::fmt;
use std::io::Write;
use std::ops::{Deref, DerefMut};
use std::str;
use url::{Url, Host};

/// Serialises `value` with a given serializer.
///
/// This is useful to serialize `rust-url` types used in structure fields or
/// tuple members with `#[serde(serialize_with = "url_serde::serialize")]`.
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer, for<'a> Ser<'a, T>: Serialize
{
    Ser::new(value).serialize(serializer)
}

/// A wrapper to serialize `rust-url` types.
///
/// This is useful with functions such as `serde_json::to_string`.
///
/// Values of this type can only be passed to the `serde::Serialize` trait.
#[derive(Debug)]
pub struct Ser<'a, T: 'a>(&'a T);

impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
    /// Returns a new `Ser` wrapper.
    #[inline(always)]
    pub fn new(value: &'a T) -> Self {
        Ser(value)
    }
}

/// Serializes this URL into a `serde` stream.
impl<'a> Serialize for Ser<'a, Url> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        serializer.serialize_str(self.0.as_str())
    }
}

/// Serializes this Option<URL> into a `serde` stream.
impl<'a> Serialize for Ser<'a, Option<Url>> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        if let Some(url) = self.0.as_ref() {
            serializer.serialize_some(url.as_str())
        } else {
            serializer.serialize_none()
        }
    }
}

impl<'a, String> Serialize for Ser<'a, Host<String>> where String: AsRef<str> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        match *self.0 {
            Host::Domain(ref s) => serializer.serialize_str(s.as_ref()),
            Host::Ipv4(_) | Host::Ipv6(_) => {
                // max("101.102.103.104".len(),
                //     "[1000:1002:1003:1004:1005:1006:101.102.103.104]".len())
                const MAX_LEN: usize = 47;
                let mut buffer = [0; MAX_LEN];
                serializer.serialize_str(display_into_buffer(&self.0, &mut buffer))
            }
        }
    }
}

/// Like .to_string(), but doesn’t allocate memory for a `String`.
///
/// Panics if `buffer` is too small.
fn display_into_buffer<'a, T: fmt::Display>(value: &T, buffer: &'a mut [u8]) -> &'a str {
    let remaining_len;
    {
        let mut remaining = &mut *buffer;
        write!(remaining, "{}", value).unwrap();
        remaining_len = remaining.len()
    }
    let written_len = buffer.len() - remaining_len;
    let written = &buffer[..written_len];

    // write! only provides std::fmt::Formatter to Display implementations,
    // which has methods write_str and write_char but no method to write arbitrary bytes.
    // Therefore, `written` is well-formed in UTF-8.
    #[allow(unsafe_code)]
    unsafe {
        str::from_utf8_unchecked(written)
    }
}

/// Deserialises a `T` value with a given deserializer.
///
/// This is useful to deserialize Url types used in structure fields or
/// tuple members with `#[serde(deserialize_with = "url_serde::deserialize")]`.
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where D: Deserializer<'de>, De<T>: Deserialize<'de>
{
    De::deserialize(deserializer).map(De::into_inner)
}

/// A wrapper to deserialize `rust-url` types.
///
/// This is useful with functions such as `serde_json::from_str`.
///
/// Values of this type can only be obtained through
/// the `serde::Deserialize` trait.
#[derive(Debug)]
pub struct De<T>(T);

impl<'de, T> De<T> where De<T>: serde::Deserialize<'de> {
    /// Consumes this wrapper, returning the deserialized value.
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.0
    }
}

/// Deserializes this URL from a `serde` stream.
impl<'de> Deserialize<'de> for De<Url> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let string_representation: String = Deserialize::deserialize(deserializer)?;
        Url::parse(&string_representation).map(De).map_err(|err| {
            serde::de::Error::custom(err.description())
        })
    }
}

/// Deserializes this Option<URL> from a `serde` stream.
impl<'de> Deserialize<'de> for De<Option<Url>> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let option_representation: Option<String> = Deserialize::deserialize(deserializer)?;
        if let Some(s) = option_representation {
            return Url::parse(&s)
                .map(Some)
                .map(De)
                .map_err(|err| {serde::de::Error::custom(err.description())});
        }
        Ok(De(None))

    }
}

impl<'de> Deserialize<'de> for De<Host> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let string_representation: String = Deserialize::deserialize(deserializer)?;
        Host::parse(&string_representation).map(De).map_err(|err| {
            serde::de::Error::custom(err.description())
        })
    }
}

/// A convenience wrapper to be used as a type parameter, for example when
/// a `Vec<T>` or an `HashMap<K, V>` need to be passed to serde.
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct Serde<T>(pub T);

/// A convenience type alias for Serde<Url>.
pub type SerdeUrl = Serde<Url>;

impl<'de, T> Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    /// Consumes this wrapper, returning the inner value.
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<'de, T> fmt::Debug for Serde<T>
where T: fmt::Debug, De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(formatter)
    }
}

impl<'de, T> Deref for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<'de, T> DerefMut for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<'de, T: PartialEq> PartialEq<T> for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn eq(&self, other: &T) -> bool {
        self.0 == *other
    }
}

impl<'de, T> Deserialize<'de> for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        De::deserialize(deserializer).map(De::into_inner).map(Serde)
    }
}

impl<'de, T> Serialize for Serde<T>
where De<T>: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        Ser(&self.0).serialize(serializer)
    }
}

#[test]
fn test_ser_de_url() {
    let url = Url::parse("http://www.test.com/foo/bar?$param=bazz").unwrap();
    let s = serde_json::to_string(&Ser::new(&url)).unwrap();
    let new_url: Url = serde_json::from_str(&s).map(De::into_inner).unwrap();
    assert_eq!(url, new_url);
}

#[test]
fn test_derive_deserialize_with_for_url() {
    #[derive(Deserialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(deserialize_with = "deserialize", rename = "_url_")]
        url: Url
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = Test {
        url: Url::parse(url_str).unwrap()
    };
    let json_string = format!(r#"{{"_url_": "{}"}}"#, url_str);
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);

}

#[test]
fn test_derive_deserialize_with_for_option_url() {
    #[derive(Deserialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(deserialize_with = "deserialize", rename = "_url_")]
        url: Option<Url>
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = Test {
        url: Some(Url::parse(url_str).unwrap())
    };
    let json_string = format!(r#"{{"_url_": "{}"}}"#, url_str);
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);

    let expected = Test {
        url: None
    };
    let json_string = r#"{"_url_": null}"#;
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);
}

#[test]
fn test_derive_serialize_with_for_url() {
    #[derive(Serialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(serialize_with = "serialize", rename = "_url_")]
        url: Url
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = format!(r#"{{"_url_":"{}"}}"#, url_str);
    let input = Test {url: Url::parse(url_str).unwrap()};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(expected, got);
}

#[test]
fn test_derive_serialize_with_for_option_url() {
    #[derive(Serialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(serialize_with = "serialize", rename = "_url_")]
        url: Option<Url>
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";

    let expected = format!(r#"{{"_url_":"{}"}}"#, url_str);
    let input = Test {url: Some(Url::parse(url_str).unwrap())};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(expected, got);

    let expected = format!(r#"{{"_url_":null}}"#);
    let input = Test {url: None};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(expected, got);
}

#[test]
fn test_derive_with_for_url() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    struct Test {
        #[serde(with = "self", rename = "_url_")]
        url: Url
    }

    let url_str = "http://www.test.com/foo/bar?$param=bazz";
    let json_string = format!(r#"{{"_url_":"{}"}}"#, url_str);

    // test deserialization
    let expected = Test {
        url: Url::parse(url_str).unwrap()
    };
    let got: Test = serde_json::from_str(&json_string).unwrap();
    assert_eq!(expected, got);

    // test serialization
    let input = Test {url: Url::parse(url_str).unwrap()};
    let got = serde_json::to_string(&input).unwrap();
    assert_eq!(json_string, got);
}

#[test]
fn test_host() {
    for host in &[
        Host::Domain("foo.com".to_owned()),
        Host::Ipv4("127.0.0.1".parse().unwrap()),
        Host::Ipv6("::1".parse().unwrap()),
    ] {
        let json = serde_json::to_string(&Ser(host)).unwrap();
        let de: De<Host> = serde_json::from_str(&json).unwrap();
        assert_eq!(de.into_inner(), *host)
    }
}
<|endoftext|>


<commit_before>use result::Result;

use hoedown::renderer::Render;
use hoedown::Buffer;
use hoedown::Markdown;

pub struct Link {
    pub title: String,
    pub link: String,
}

struct LinkExtractor {
    links: Vec<Link>,
}

impl LinkExtractor {

    pub fn new() -> LinkExtractor {
        LinkExtractor { links: vec![] }
    }

    pub fn links(self) -> Vec<Link> {
        self.links
    }

}

impl Render for LinkExtractor {

    fn link(&mut self,
            _: &mut Buffer,
            content: Option<&Buffer>,
            link: Option<&Buffer>,
            _: Option<&Buffer>)
        -> bool
    {
        let link  = link.and_then(|l| l.to_str().ok()).map(String::from);
        let content = content.and_then(|l| l.to_str().ok()).map(String::from);

        match (link, content) {
            (Some(link), Some(content)) => {
                self.links.push(Link { link: link, title: content });
                false
            },

            (_, _) => {
                false
            },
        }

    }

}

pub fn extract_links(buf: &str) -> Vec<Link> {
    let mut le = LinkExtractor::new();
    le.render(&Markdown::new(buf));
    le.links()
}

#[cfg(test)]
mod test {
    use super::{Link, extract_links};

    #[test]
    fn test_one_link() {
        let testtext = "Some [example text](http://example.com).";

        let exp = Link {
            title: String::from("example text"),
            link:  String::from("http://example.com"),
        };

        let mut links = extract_links(testtext);
        assert_eq!(1, links.len());
        assert_eq!(exp, links.pop().unwrap())
    }

}

<commit_msg>Derive Debug, Clone, PartialEq and Eq for Link type<commit_after>use result::Result;

use hoedown::renderer::Render;
use hoedown::Buffer;
use hoedown::Markdown;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Link {
    pub title: String,
    pub link: String,
}

struct LinkExtractor {
    links: Vec<Link>,
}

impl LinkExtractor {

    pub fn new() -> LinkExtractor {
        LinkExtractor { links: vec![] }
    }

    pub fn links(self) -> Vec<Link> {
        self.links
    }

}

impl Render for LinkExtractor {

    fn link(&mut self,
            _: &mut Buffer,
            content: Option<&Buffer>,
            link: Option<&Buffer>,
            _: Option<&Buffer>)
        -> bool
    {
        let link  = link.and_then(|l| l.to_str().ok()).map(String::from);
        let content = content.and_then(|l| l.to_str().ok()).map(String::from);

        match (link, content) {
            (Some(link), Some(content)) => {
                self.links.push(Link { link: link, title: content });
                false
            },

            (_, _) => {
                false
            },
        }

    }

}

pub fn extract_links(buf: &str) -> Vec<Link> {
    let mut le = LinkExtractor::new();
    le.render(&Markdown::new(buf));
    le.links()
}

#[cfg(test)]
mod test {
    use super::{Link, extract_links};

    #[test]
    fn test_one_link() {
        let testtext = "Some [example text](http://example.com).";

        let exp = Link {
            title: String::from("example text"),
            link:  String::from("http://example.com"),
        };

        let mut links = extract_links(testtext);
        assert_eq!(1, links.len());
        assert_eq!(exp, links.pop().unwrap())
    }

}

<|endoftext|>


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

#![allow(non_snake_case)]

register_long_diagnostics! {

E0373: r##"
This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to
return a closure:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(|y| x + y)
}
```

Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
closed-over data by reference. This means that once `foo()` returns, `x` no
longer exists. An attempt to access `x` within the closure would thus be unsafe.

Another situation where this might be encountered is when spawning threads:

```
fn foo() {
    let x = 0u32;
    let y = 1u32;

    let thr = std::thread::spawn(|| {
        x + y
    });
}
```

Since our new thread runs in parallel, the stack frame containing `x` and `y`
may well have disappeared by the time we try to use them. Even if we call
`thr.join()` within foo (which blocks until `thr` has completed, ensuring the
stack frame won't disappear), we will not succeed: the compiler cannot prove
that this behaviour is safe, and so won't let us do it.

The solution to this problem is usually to switch to using a `move` closure.
This approach moves (or copies, where possible) data into the closure, rather
than taking references to it. For example:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(move |y| x + y)
}
```

Now that the closure has its own copy of the data, there's no need to worry
about safety.
"##,

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
    let x: i32;
    let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##,

E0382: r##"
This error occurs when an attempt is made to use a variable after its contents
have been moved elsewhere. For example:

```
struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;
    x.s = 6;
    println!("{}", x.s);
}
```

Since `MyStruct` is a type that is not marked `Copy`, the data gets moved out
of `x` when we set `y`. This is fundamental to Rust's ownership system: outside
of workarounds like `Rc`, a value cannot be owned by more than one variable.

If we own the type, the easiest way to address this problem is to implement
`Copy` and `Clone` on it, as shown below. This allows `y` to copy the
information in `x`, while leaving the original version owned by `x`. Subsequent
changes to `x` will not be reflected when accessing `y`.

```
#[derive(Copy, Clone)]
struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;
    x.s = 6;
    println!("{}", x.s);
}
```

Alternatively, if we don't control the struct's definition, or mutable shared
ownership is truly required, we can use `Rc` and `RefCell`:

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

struct MyStruct { s: u32 }

fn main() {
    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
    let y = x.clone();
    x.borrow_mut().s = 6;
    println!("{}", x.borrow().s);
}
```

With this approach, x and y share ownership of the data via the `Rc` (reference
count type). `RefCell` essentially performs runtime borrow checking: ensuring
that at most one writer or multiple readers can access the data at any one time.

If you wish to learn more about ownership in Rust, start with the chapter in the
Book:

https://doc.rust-lang.org/book/ownership.html
"##,

E0383: r##"
This error occurs when an attempt is made to partially reinitialize a
structure that is currently uninitialized.

For example, this can happen when a drop has taken place:

```
let mut x = Foo { a: 1 };
drop(x); // `x` is now uninitialized
x.a = 2; // error, partial reinitialization of uninitialized structure `t`
```

This error can be fixed by fully reinitializing the structure in question:

```
let mut x = Foo { a: 1 };
drop(x);
x = Foo { a: 2 };
```
"##,

E0384: r##"
This error occurs when an attempt is made to reassign an immutable variable.
For example:

```
fn main(){
    let x = 3;
    x = 5; // error, reassignment of immutable variable
}
```

By default, variables in Rust are immutable. To fix this error, add the keyword
`mut` after the keyword `let` when declaring the variable. For example:

```
fn main(){
    let mut x = 3;
    x = 5;
}
```
"##,

E0386: r##"
This error occurs when an attempt is made to mutate the target of a mutable
reference stored inside an immutable container.

For example, this can happen when storing a `&mut` inside an immutable `Box`:

```
let mut x: i64 = 1;
let y: Box<_> = Box::new(&mut x);
**y = 2; // error, cannot assign to data in an immutable container
```

This error can be fixed by making the container mutable:

```
let mut x: i64 = 1;
let mut y: Box<_> = Box::new(&mut x);
**y = 2;
```

It can also be fixed by using a type with interior mutability, such as `Cell` or
`RefCell`:

```
let x: i64 = 1;
let y: Box<Cell<_>> = Box::new(Cell::new(x));
y.set(2);
```
"##,

E0387: r##"
This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below:

```
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }

// Attempts to mutate closed-over data.  Error message reads:
// `cannot assign to data in a captured outer variable...`
fn mutable() {
    let mut x = 0u32;
    foo(|| x = 2);
}

// Attempts to take a mutable reference to closed-over data.  Error message
// reads: `cannot borrow data mutably in a captured outer variable...`
fn mut_addr() {
    let mut x = 0u32;
    foo(|| { let y = &mut x; });
}
```

The problem here is that foo is defined as accepting a parameter of type `Fn`.
Closures passed into foo will thus be inferred to be of type `Fn`, meaning that
they capture their context immutably.

If the definition of `foo` is under your control, the simplest solution is to
capture the data mutably. This can be done by defining `foo` to take FnMut
rather than Fn:

```
fn foo<F: FnMut()>(f: F) { }
```

Alternatively, we can consider using the `Cell` and `RefCell` types to achieve
interior mutability through a shared reference. Our example's `mutable` function
could be redefined as below:

```
use std::cell::Cell;

fn mutable() {
    let x = Cell::new(0u32);
    foo(|| x.set(2));
}
```

You can read more about cell types in the API documentation:

https://doc.rust-lang.org/std/cell/
"##,

E0499: r##"
A variable was borrowed as mutable more than once. Erroneous code example:

```
let mut i = 0;
let mut x = &mut i;
let mut a = &mut i;
// error: cannot borrow `i` as mutable more than once at a time
```

Please note that in rust, you can either have many immutable references, or one
mutable reference. Take a look at
https://doc.rust-lang.org/stable/book/references-and-borrowing.html for more
information. Example:

```
let mut i = 0;
let mut x = &mut i; // ok!

// or:
let mut i = 0;
let a = &i; // ok!
let b = &i; // still ok!
let c = &i; // still ok!
```
"##,

E0507: r##"
You tried to move out of a value which was borrowed. Erroneous code example:

```
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);

    x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
}
```

Here, the `nothing_is_true` method takes the ownership of `self`. However,
`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
which is a borrow of the content owned by the `RefCell`. To fix this error,
you have three choices:

* Try to avoid moving the variable.
* Somehow reclaim the ownership.
* Implement the `Copy` trait on the type.

Examples:

```
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(&self) {} // First case, we don't take ownership
}

fn main() {
    let x = RefCell::new(TheDarkKnight);

    x.borrow().nothing_is_true(); // ok!
}
```

Or:

```
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);
    let x = x.into_inner(); // we get back ownership

    x.nothing_is_true(); // ok!
}
```

Or:

```
use std::cell::RefCell;

#[derive(Clone, Copy)] // we implement the Copy trait
struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);

    x.borrow().nothing_is_true(); // ok!
}
```

You can find more information about borrowing in the rust-book:
http://doc.rust-lang.org/stable/book/references-and-borrowing.html
"##,

}

register_diagnostics! {
    E0385, // {} in an aliasable location
    E0388, // {} in a static location
    E0389, // {} in a `&` reference
    E0500, // closure requires unique access to `..` but .. is already borrowed
    E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
    E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
    E0503, // cannot use `..` because it was mutably borrowed
    E0504, // cannot move `..` into closure because it is borrowed
    E0505, // cannot move out of `..` because it is borrowed
    E0506, // cannot assign to `..` because it is borrowed
    E0508, // cannot move out of type `..`, a non-copy fixed-size array
    E0509, // cannot move out of type `..`, which defines the `Drop` trait
}
<commit_msg>Improve message for rustc --explain E0507<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0373: r##"
This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to
return a closure:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(|y| x + y)
}
```

Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
closed-over data by reference. This means that once `foo()` returns, `x` no
longer exists. An attempt to access `x` within the closure would thus be unsafe.

Another situation where this might be encountered is when spawning threads:

```
fn foo() {
    let x = 0u32;
    let y = 1u32;

    let thr = std::thread::spawn(|| {
        x + y
    });
}
```

Since our new thread runs in parallel, the stack frame containing `x` and `y`
may well have disappeared by the time we try to use them. Even if we call
`thr.join()` within foo (which blocks until `thr` has completed, ensuring the
stack frame won't disappear), we will not succeed: the compiler cannot prove
that this behaviour is safe, and so won't let us do it.

The solution to this problem is usually to switch to using a `move` closure.
This approach moves (or copies, where possible) data into the closure, rather
than taking references to it. For example:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(move |y| x + y)
}
```

Now that the closure has its own copy of the data, there's no need to worry
about safety.
"##,

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
    let x: i32;
    let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##,

E0382: r##"
This error occurs when an attempt is made to use a variable after its contents
have been moved elsewhere. For example:

```
struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;
    x.s = 6;
    println!("{}", x.s);
}
```

Since `MyStruct` is a type that is not marked `Copy`, the data gets moved out
of `x` when we set `y`. This is fundamental to Rust's ownership system: outside
of workarounds like `Rc`, a value cannot be owned by more than one variable.

If we own the type, the easiest way to address this problem is to implement
`Copy` and `Clone` on it, as shown below. This allows `y` to copy the
information in `x`, while leaving the original version owned by `x`. Subsequent
changes to `x` will not be reflected when accessing `y`.

```
#[derive(Copy, Clone)]
struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;
    x.s = 6;
    println!("{}", x.s);
}
```

Alternatively, if we don't control the struct's definition, or mutable shared
ownership is truly required, we can use `Rc` and `RefCell`:

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

struct MyStruct { s: u32 }

fn main() {
    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
    let y = x.clone();
    x.borrow_mut().s = 6;
    println!("{}", x.borrow().s);
}
```

With this approach, x and y share ownership of the data via the `Rc` (reference
count type). `RefCell` essentially performs runtime borrow checking: ensuring
that at most one writer or multiple readers can access the data at any one time.

If you wish to learn more about ownership in Rust, start with the chapter in the
Book:

https://doc.rust-lang.org/book/ownership.html
"##,

E0383: r##"
This error occurs when an attempt is made to partially reinitialize a
structure that is currently uninitialized.

For example, this can happen when a drop has taken place:

```
let mut x = Foo { a: 1 };
drop(x); // `x` is now uninitialized
x.a = 2; // error, partial reinitialization of uninitialized structure `t`
```

This error can be fixed by fully reinitializing the structure in question:

```
let mut x = Foo { a: 1 };
drop(x);
x = Foo { a: 2 };
```
"##,

E0384: r##"
This error occurs when an attempt is made to reassign an immutable variable.
For example:

```
fn main(){
    let x = 3;
    x = 5; // error, reassignment of immutable variable
}
```

By default, variables in Rust are immutable. To fix this error, add the keyword
`mut` after the keyword `let` when declaring the variable. For example:

```
fn main(){
    let mut x = 3;
    x = 5;
}
```
"##,

E0386: r##"
This error occurs when an attempt is made to mutate the target of a mutable
reference stored inside an immutable container.

For example, this can happen when storing a `&mut` inside an immutable `Box`:

```
let mut x: i64 = 1;
let y: Box<_> = Box::new(&mut x);
**y = 2; // error, cannot assign to data in an immutable container
```

This error can be fixed by making the container mutable:

```
let mut x: i64 = 1;
let mut y: Box<_> = Box::new(&mut x);
**y = 2;
```

It can also be fixed by using a type with interior mutability, such as `Cell` or
`RefCell`:

```
let x: i64 = 1;
let y: Box<Cell<_>> = Box::new(Cell::new(x));
y.set(2);
```
"##,

E0387: r##"
This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below:

```
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }

// Attempts to mutate closed-over data.  Error message reads:
// `cannot assign to data in a captured outer variable...`
fn mutable() {
    let mut x = 0u32;
    foo(|| x = 2);
}

// Attempts to take a mutable reference to closed-over data.  Error message
// reads: `cannot borrow data mutably in a captured outer variable...`
fn mut_addr() {
    let mut x = 0u32;
    foo(|| { let y = &mut x; });
}
```

The problem here is that foo is defined as accepting a parameter of type `Fn`.
Closures passed into foo will thus be inferred to be of type `Fn`, meaning that
they capture their context immutably.

If the definition of `foo` is under your control, the simplest solution is to
capture the data mutably. This can be done by defining `foo` to take FnMut
rather than Fn:

```
fn foo<F: FnMut()>(f: F) { }
```

Alternatively, we can consider using the `Cell` and `RefCell` types to achieve
interior mutability through a shared reference. Our example's `mutable` function
could be redefined as below:

```
use std::cell::Cell;

fn mutable() {
    let x = Cell::new(0u32);
    foo(|| x.set(2));
}
```

You can read more about cell types in the API documentation:

https://doc.rust-lang.org/std/cell/
"##,

E0499: r##"
A variable was borrowed as mutable more than once. Erroneous code example:

```
let mut i = 0;
let mut x = &mut i;
let mut a = &mut i;
// error: cannot borrow `i` as mutable more than once at a time
```

Please note that in rust, you can either have many immutable references, or one
mutable reference. Take a look at
https://doc.rust-lang.org/stable/book/references-and-borrowing.html for more
information. Example:

```
let mut i = 0;
let mut x = &mut i; // ok!

// or:
let mut i = 0;
let a = &i; // ok!
let b = &i; // still ok!
let c = &i; // still ok!
```
"##,

E0507: r##"
You tried to move out of a value which was borrowed. Erroneous code example:

```
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);

    x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
}
```

Here, the `nothing_is_true` method takes the ownership of `self`. However,
`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
which is a borrow of the content owned by the `RefCell`. To fix this error,
you have three choices:

* Try to avoid moving the variable.
* Somehow reclaim the ownership.
* Implement the `Copy` trait on the type.

Examples:

```
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(&self) {} // First case, we don't take ownership
}

fn main() {
    let x = RefCell::new(TheDarkKnight);

    x.borrow().nothing_is_true(); // ok!
}
```

Or:

```
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);
    let x = x.into_inner(); // we get back ownership

    x.nothing_is_true(); // ok!
}
```

Or:

```
use std::cell::RefCell;

#[derive(Clone, Copy)] // we implement the Copy trait
struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);

    x.borrow().nothing_is_true(); // ok!
}
```

Moving out of a member of a mutably borrowed struct is fine if you put something
back. `mem::replace` can be used for that:

```
struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

struct Batcave {
    knight: TheDarkKnight
}

fn main() {
    use std::mem;

    let mut cave = Batcave {
        knight: TheDarkKnight
    };
    let borrowed = &mut cave;

    borrowed.knight.nothing_is_true(); // E0507
    mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!
}
```

You can find more information about borrowing in the rust-book:
http://doc.rust-lang.org/stable/book/references-and-borrowing.html
"##,

}

register_diagnostics! {
    E0385, // {} in an aliasable location
    E0388, // {} in a static location
    E0389, // {} in a `&` reference
    E0500, // closure requires unique access to `..` but .. is already borrowed
    E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
    E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
    E0503, // cannot use `..` because it was mutably borrowed
    E0504, // cannot move `..` into closure because it is borrowed
    E0505, // cannot move out of `..` because it is borrowed
    E0506, // cannot assign to `..` because it is borrowed
    E0508, // cannot move out of type `..`, a non-copy fixed-size array
    E0509, // cannot move out of type `..`, which defines the `Drop` trait
}
<|endoftext|>


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

use ast;
use parse::{new_parse_sess};
use parse::{ParseSess,string_to_filemap,filemap_to_tts};
use parse::{new_parser_from_source_str};
use parse::parser::Parser;
use parse::token;

// map a string to tts, using a made-up filename: return both the token_trees
// and the ParseSess
pub fn string_to_tts_and_sess (source_str : @str) -> (~[ast::token_tree],@mut ParseSess) {
    let ps = new_parse_sess(None);
    (filemap_to_tts(ps,string_to_filemap(ps,source_str,@"bogofile")),ps)
}

pub fn string_to_parser_and_sess(source_str: @str) -> (Parser,@mut ParseSess) {
    let ps = new_parse_sess(None);
    (new_parser_from_source_str(ps,~[],@"bogofile",source_str),ps)
}

// map string to parser (via tts)
pub fn string_to_parser(source_str: @str) -> Parser {
    let (p,_) = string_to_parser_and_sess(source_str);
    p
}

fn with_error_checking_parse<T>(s: @str, f: &fn(&mut Parser) -> T) -> T {
    let mut p = string_to_parser(s);
    let x = f(&mut p);
    p.abort_if_errors();
    x
}

// parse a string, return a crate.
pub fn string_to_crate (source_str : @str) -> @ast::Crate {
    do with_error_checking_parse(source_str) |p| {
        p.parse_crate_mod()
    }
}

// parse a string, return a crate and the ParseSess
pub fn string_to_crate_and_sess (source_str : @str) -> (@ast::Crate,@mut ParseSess) {
    let (p,ps) = string_to_parser_and_sess(source_str);
    (p.parse_crate_mod(),ps)
}

// parse a string, return an expr
pub fn string_to_expr (source_str : @str) -> @ast::Expr {
    do with_error_checking_parse(source_str) |p| {
        p.parse_expr()
    }
}

// parse a string, return an item
pub fn string_to_item (source_str : @str) -> Option<@ast::item> {
    do with_error_checking_parse(source_str) |p| {
        p.parse_item(~[])
    }
}

// parse a string, return a stmt
pub fn string_to_stmt(source_str : @str) -> @ast::Stmt {
    do with_error_checking_parse(source_str) |p| {
        p.parse_stmt(~[])
    }
}

// parse a string, return a pat. Uses "irrefutable"... which doesn't
// (currently) affect parsing.
pub fn string_to_pat(source_str : @str) -> @ast::Pat {
    string_to_parser(source_str).parse_pat()
}

// convert a vector of strings to a vector of ast::idents
pub fn strs_to_idents(ids: ~[&str]) -> ~[ast::Ident] {
    ids.map(|u| token::str_to_ident(*u))
}

// does the given string match the pattern? whitespace in the first string
// may be deleted or replaced with other whitespace to match the pattern.
// this function is unicode-ignorant; fortunately, the careful design of
// UTF-8 mitigates this ignorance.  In particular, this function only collapses
// sequences of \n, \r, ' ', and \t, but it should otherwise tolerate unicode
// chars. Unsurprisingly, it doesn't do NKF-normalization(?).
pub fn matches_codepattern(a : &str, b : &str) -> bool {
    let mut idx_a = 0;
    let mut idx_b = 0;
    loop {
        if (idx_a == a.len() && idx_b == b.len()) {
            return true;
        }
        else if (idx_a == a.len()) {return false;}
        else if (idx_b == b.len()) {
            // maybe the stuff left in a is all ws?
            if (is_whitespace(a.char_at(idx_a))) {
                return (scan_for_non_ws_or_end(a,idx_a) == a.len());
            } else {
                return false;
            }
        }
        // ws in both given and pattern:
        else if (is_whitespace(a.char_at(idx_a))
           && is_whitespace(b.char_at(idx_b))) {
            idx_a = scan_for_non_ws_or_end(a,idx_a);
            idx_b = scan_for_non_ws_or_end(b,idx_b);
        }
        // ws in given only:
        else if (is_whitespace(a.char_at(idx_a))) {
            idx_a = scan_for_non_ws_or_end(a,idx_a);
        }
        // *don't* silently eat ws in expected only.
        else if (a.char_at(idx_a) == b.char_at(idx_b)) {
            idx_a += 1;
            idx_b += 1;
        }
        else {
            return false;
        }
    }
}

// given a string and an index, return the first uint >= idx
// that is a non-ws-char or is outside of the legal range of
// the string.
fn scan_for_non_ws_or_end(a : &str, idx: uint) -> uint {
    let mut i = idx;
    let len = a.len();
    while ((i < len) && (is_whitespace(a.char_at(i)))) {
        i += 1;
    }
    i
}

// copied from lexer.
pub fn is_whitespace(c: char) -> bool {
    return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}

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

    #[test] fn eqmodws() {
        assert_eq!(matches_codepattern("",""),true);
        assert_eq!(matches_codepattern("","a"),false);
        assert_eq!(matches_codepattern("a",""),false);
        assert_eq!(matches_codepattern("a","a"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b ","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b "),false);
        assert_eq!(matches_codepattern("a   b","a b"),true);
        assert_eq!(matches_codepattern("ab","a b"),false);
        assert_eq!(matches_codepattern("a   b","ab"),true);
    }
}
<commit_msg>added string_to_tts<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ast;
use parse::{new_parse_sess};
use parse::{ParseSess,string_to_filemap,filemap_to_tts};
use parse::{new_parser_from_source_str};
use parse::parser::Parser;
use parse::token;

// map a string to tts, using a made-up filename: return both the token_trees
// and the ParseSess
pub fn string_to_tts_and_sess (source_str : @str) -> (~[ast::token_tree],@mut ParseSess) {
    let ps = new_parse_sess(None);
    (filemap_to_tts(ps,string_to_filemap(ps,source_str,@"bogofile")),ps)
}

// map a string to tts, using a made-up filename:
pub fn string_to_tts(source_str : @str) -> ~[ast::token_tree] {
    let (tts,_) = string_to_tts_and_sess(source_str);
    tts
}

pub fn string_to_parser_and_sess(source_str: @str) -> (Parser,@mut ParseSess) {
    let ps = new_parse_sess(None);
    (new_parser_from_source_str(ps,~[],@"bogofile",source_str),ps)
}

// map string to parser (via tts)
pub fn string_to_parser(source_str: @str) -> Parser {
    let (p,_) = string_to_parser_and_sess(source_str);
    p
}

fn with_error_checking_parse<T>(s: @str, f: &fn(&mut Parser) -> T) -> T {
    let mut p = string_to_parser(s);
    let x = f(&mut p);
    p.abort_if_errors();
    x
}

// parse a string, return a crate.
pub fn string_to_crate (source_str : @str) -> @ast::Crate {
    do with_error_checking_parse(source_str) |p| {
        p.parse_crate_mod()
    }
}

// parse a string, return a crate and the ParseSess
pub fn string_to_crate_and_sess (source_str : @str) -> (@ast::Crate,@mut ParseSess) {
    let (p,ps) = string_to_parser_and_sess(source_str);
    (p.parse_crate_mod(),ps)
}

// parse a string, return an expr
pub fn string_to_expr (source_str : @str) -> @ast::Expr {
    do with_error_checking_parse(source_str) |p| {
        p.parse_expr()
    }
}

// parse a string, return an item
pub fn string_to_item (source_str : @str) -> Option<@ast::item> {
    do with_error_checking_parse(source_str) |p| {
        p.parse_item(~[])
    }
}

// parse a string, return a stmt
pub fn string_to_stmt(source_str : @str) -> @ast::Stmt {
    do with_error_checking_parse(source_str) |p| {
        p.parse_stmt(~[])
    }
}

// parse a string, return a pat. Uses "irrefutable"... which doesn't
// (currently) affect parsing.
pub fn string_to_pat(source_str : @str) -> @ast::Pat {
    string_to_parser(source_str).parse_pat()
}

// convert a vector of strings to a vector of ast::idents
pub fn strs_to_idents(ids: ~[&str]) -> ~[ast::Ident] {
    ids.map(|u| token::str_to_ident(*u))
}

// does the given string match the pattern? whitespace in the first string
// may be deleted or replaced with other whitespace to match the pattern.
// this function is unicode-ignorant; fortunately, the careful design of
// UTF-8 mitigates this ignorance.  In particular, this function only collapses
// sequences of \n, \r, ' ', and \t, but it should otherwise tolerate unicode
// chars. Unsurprisingly, it doesn't do NKF-normalization(?).
pub fn matches_codepattern(a : &str, b : &str) -> bool {
    let mut idx_a = 0;
    let mut idx_b = 0;
    loop {
        if (idx_a == a.len() && idx_b == b.len()) {
            return true;
        }
        else if (idx_a == a.len()) {return false;}
        else if (idx_b == b.len()) {
            // maybe the stuff left in a is all ws?
            if (is_whitespace(a.char_at(idx_a))) {
                return (scan_for_non_ws_or_end(a,idx_a) == a.len());
            } else {
                return false;
            }
        }
        // ws in both given and pattern:
        else if (is_whitespace(a.char_at(idx_a))
           && is_whitespace(b.char_at(idx_b))) {
            idx_a = scan_for_non_ws_or_end(a,idx_a);
            idx_b = scan_for_non_ws_or_end(b,idx_b);
        }
        // ws in given only:
        else if (is_whitespace(a.char_at(idx_a))) {
            idx_a = scan_for_non_ws_or_end(a,idx_a);
        }
        // *don't* silently eat ws in expected only.
        else if (a.char_at(idx_a) == b.char_at(idx_b)) {
            idx_a += 1;
            idx_b += 1;
        }
        else {
            return false;
        }
    }
}

// given a string and an index, return the first uint >= idx
// that is a non-ws-char or is outside of the legal range of
// the string.
fn scan_for_non_ws_or_end(a : &str, idx: uint) -> uint {
    let mut i = idx;
    let len = a.len();
    while ((i < len) && (is_whitespace(a.char_at(i)))) {
        i += 1;
    }
    i
}

// copied from lexer.
pub fn is_whitespace(c: char) -> bool {
    return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}

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

    #[test] fn eqmodws() {
        assert_eq!(matches_codepattern("",""),true);
        assert_eq!(matches_codepattern("","a"),false);
        assert_eq!(matches_codepattern("a",""),false);
        assert_eq!(matches_codepattern("a","a"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b ","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b "),false);
        assert_eq!(matches_codepattern("a   b","a b"),true);
        assert_eq!(matches_codepattern("ab","a b"),false);
        assert_eq!(matches_codepattern("a   b","ab"),true);
    }
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/minimum-path-cost-in-a-grid/
pub fn min_path_cost(grid: Vec<Vec<i32>>, move_cost: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        min_path_cost(
            vec![vec![5, 3], vec![4, 0], vec![2, 1]],
            vec![
                vec![9, 8],
                vec![1, 5],
                vec![10, 12],
                vec![18, 6],
                vec![2, 4],
                vec![14, 3]
            ]
        )
    ); // 17
    println!(
        "{}",
        min_path_cost(
            vec![vec![5, 1, 2], vec![4, 0, 3]],
            vec![
                vec![12, 10, 15],
                vec![20, 23, 8],
                vec![21, 7, 1],
                vec![8, 1, 13],
                vec![9, 10, 25],
                vec![5, 3, 2]
            ]
        )
    ); // 6
}
<commit_msg>Update problem 2304<commit_after>// https://leetcode.com/problems/minimum-path-cost-in-a-grid/
pub fn min_path_cost(grid: Vec<Vec<i32>>, move_cost: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        min_path_cost(
            vec![
                vec![5, 3],
                vec![4, 0],
                vec![2, 1]
            ],
            vec![
                vec![9, 8],
                vec![1, 5],
                vec![10, 12],
                vec![18, 6],
                vec![2, 4],
                vec![14, 3]
            ]
        )
    ); // 17
    println!(
        "{}",
        min_path_cost(
            vec![
                vec![5, 1, 2],
                vec![4, 0, 3]
            ],
            vec![
                vec![12, 10, 15],
                vec![20, 23, 8],
                vec![21, 7, 1],
                vec![8, 1, 13],
                vec![9, 10, 25],
                vec![5, 3, 2]
            ]
        )
    ); // 6
}
<|endoftext|>


<commit_before><commit_msg>Fix bug where typedefs would parse semicolons as type identifiers<commit_after><|endoftext|>


<commit_before>use std::collections::HashSet;
use std::io::{File, fs};
use util;
use core::{Package,Manifest,SourceId};
use util::{CargoResult, human};
use util::important_paths::find_project_manifest_exact;

pub fn read_manifest(contents: &[u8], source_id: &SourceId)
    -> CargoResult<(Manifest, Vec<Path>)>
{
    util::toml::to_manifest(contents, source_id).map_err(human)
}

pub fn read_package(path: &Path, source_id: &SourceId)
    -> CargoResult<(Package, Vec<Path>)>
{
    log!(5, "read_package; path={}; source-id={}", path.display(), source_id);
    let mut file = try!(File::open(path));
    let data = try!(file.read_to_end());
    let (manifest, nested) = try!(read_manifest(data.as_slice(),
                                                      source_id));

    Ok((Package::new(manifest, path, source_id), nested))
}

pub fn read_packages(path: &Path,
                     source_id: &SourceId) -> CargoResult<Vec<Package>>
{
    let mut all_packages = Vec::new();
    let mut visited = HashSet::<Path>::new();

    log!(5, "looking for root package: {}, source_id={}", path.display(), source_id);
    try!(process_possible_package(path, &mut all_packages, source_id, &mut visited));

    try!(walk(path, true, |dir| {
        log!(5, "looking for child package: {}", dir.display());
        if dir.filename_str() == Some(".git") { return Ok(false); }
        if dir.join(".git").is_dir() { return Ok(false); }
        try!(process_possible_package(dir, &mut all_packages, source_id, &mut visited));
        Ok(true)
    }));

    if all_packages.is_empty() {
        Err(human(format!("Could not find Cargo.toml in `{}`", path.display())))
    } else {
        log!(5, "all packages: {}", all_packages);
        Ok(all_packages)
    }
}

fn walk(path: &Path, is_root: bool, callback: |&Path| -> CargoResult<bool>) -> CargoResult<()> {
    if path.is_dir() {
        if !is_root {
            let continues = try!(callback(path));
            if !continues { log!(5, "Found submodule at {}", path.display()); return Ok(()); }
        }

        for dir in try!(fs::readdir(path)).iter() {
            try!(walk(dir, false, |x| callback(x)))
        }
    }

    Ok(())
}

fn process_possible_package(dir: &Path,
                            all_packages: &mut Vec<Package>,
                            source_id: &SourceId,
                            visited: &mut HashSet<Path>) -> CargoResult<()> {

    if !has_manifest(dir) { return Ok(()); }

    let packages = try!(read_nested_packages(dir, source_id, visited));
    push_all(all_packages, packages);

    Ok(())
}

fn has_manifest(path: &Path) -> bool {
    find_project_manifest_exact(path, "Cargo.toml").is_ok()
}

fn read_nested_packages(path: &Path, source_id: &SourceId,
                 visited: &mut HashSet<Path>) -> CargoResult<Vec<Package>> {
    if !visited.insert(path.clone()) { return Ok(Vec::new()) }

    let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));

    let (pkg, nested) = try!(read_package(&manifest, source_id));
    let mut ret = vec![pkg];

    for p in nested.iter() {
        ret.push_all(try!(read_nested_packages(&path.join(p),
                                        source_id,
                                        visited)).as_slice());
    }

    Ok(ret)
}

fn push_all(set: &mut Vec<Package>, packages: Vec<Package>) {
    for package in packages.move_iter() {
        if set.contains(&package) { continue; }

        set.push(package)
    }
}
<commit_msg>Improvements based on the review<commit_after>use std::collections::HashSet;
use std::io::{File, fs};
use util;
use core::{Package,Manifest,SourceId};
use util::{CargoResult, human};
use util::important_paths::find_project_manifest_exact;

pub fn read_manifest(contents: &[u8], source_id: &SourceId)
    -> CargoResult<(Manifest, Vec<Path>)>
{
    util::toml::to_manifest(contents, source_id).map_err(human)
}

pub fn read_package(path: &Path, source_id: &SourceId)
    -> CargoResult<(Package, Vec<Path>)>
{
    log!(5, "read_package; path={}; source-id={}", path.display(), source_id);
    let mut file = try!(File::open(path));
    let data = try!(file.read_to_end());
    let (manifest, nested) = try!(read_manifest(data.as_slice(),
                                                      source_id));

    Ok((Package::new(manifest, path, source_id), nested))
}

pub fn read_packages(path: &Path,
                     source_id: &SourceId) -> CargoResult<Vec<Package>>
{
    let mut all_packages = Vec::new();
    let mut visited = HashSet::<Path>::new();

    log!(5, "looking for root package: {}, source_id={}", path.display(), source_id);
    try!(process_possible_package(path, &mut all_packages, source_id, &mut visited));

    try!(walk(path, true, |dir| {
        log!(5, "looking for child package: {}", dir.display());
        if dir.filename_str() == Some(".git") { return Ok(false); }
        if dir.join(".git").exists() { return Ok(false); }
        try!(process_possible_package(dir, &mut all_packages, source_id, &mut visited));
        Ok(true)
    }));

    if all_packages.is_empty() {
        Err(human(format!("Could not find Cargo.toml in `{}`", path.display())))
    } else {
        log!(5, "all packages: {}", all_packages);
        Ok(all_packages)
    }
}

fn walk(path: &Path, is_root: bool, callback: |&Path| -> CargoResult<bool>) -> CargoResult<()> {
    if path.is_dir() {
        if !is_root {
            let continues = try!(callback(path));
            if !continues { log!(5, "Found submodule at {}", path.display()); return Ok(()); }
        }

        for dir in try!(fs::readdir(path)).iter() {
            try!(walk(dir, false, |x| callback(x)))
        }
    }

    Ok(())
}

fn process_possible_package(dir: &Path,
                            all_packages: &mut Vec<Package>,
                            source_id: &SourceId,
                            visited: &mut HashSet<Path>) -> CargoResult<()> {

    if !has_manifest(dir) { return Ok(()); }

    let packages = try!(read_nested_packages(dir, source_id, visited));
    push_all(all_packages, packages);

    Ok(())
}

fn has_manifest(path: &Path) -> bool {
    find_project_manifest_exact(path, "Cargo.toml").is_ok()
}

fn read_nested_packages(path: &Path, source_id: &SourceId,
                 visited: &mut HashSet<Path>) -> CargoResult<Vec<Package>> {
    if !visited.insert(path.clone()) { return Ok(Vec::new()) }

    let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));

    let (pkg, nested) = try!(read_package(&manifest, source_id));
    let mut ret = vec![pkg];

    for p in nested.iter() {
        ret.push_all_move(try!(read_nested_packages(&path.join(p),
                                        source_id,
                                        visited)));
    }

    Ok(ret)
}

fn push_all(set: &mut Vec<Package>, packages: Vec<Package>) {
    for package in packages.move_iter() {
        if set.contains(&package) { continue; }

        set.push(package)
    }
}
<|endoftext|>