<commit_before>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// 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 crate::{
    error::*,
    fmt::{
        Braced, BracedRef, Hyphenated, HyphenatedRef, Simple, SimpleRef, Urn,
        UrnRef,
    },
    std::fmt,
    Uuid,
};
use serde::{
    de::{self, Error as _},
    Deserialize, Deserializer, Serialize, Serializer,
};

impl Serialize for Uuid {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        if serializer.is_human_readable() {
            serializer.serialize_str(
                self.to_hyphenated()
                    .encode_lower(&mut Uuid::encode_buffer()),
            )
        } else {
            self.as_bytes().serialize(serializer)
        }
    }
}

impl Serialize for Hyphenated {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for HyphenatedRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Simple {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for SimpleRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Urn {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for UrnRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Braced {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for BracedRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl<'de> Deserialize<'de> for Uuid {
    fn deserialize<D: Deserializer<'de>>(
        deserializer: D,
    ) -> Result<Self, D::Error> {
        fn de_error<E: de::Error>(e: Error) -> E {
            E::custom(format_args!("UUID parsing failed: {}", e))
        }

        if deserializer.is_human_readable() {
            struct UuidVisitor;

            impl<'vi> de::Visitor<'vi> for UuidVisitor {
                type Value = Uuid;

                fn expecting(
                    &self,
                    formatter: &mut fmt::Formatter<'_>,
                ) -> fmt::Result {
                    write!(formatter, "a UUID string")
                }

                fn visit_str<E: de::Error>(
                    self,
                    value: &str,
                ) -> Result<Uuid, E> {
                    value.parse::<Uuid>().map_err(de_error)
                }

                fn visit_bytes<E: de::Error>(
                    self,
                    value: &[u8],
                ) -> Result<Uuid, E> {
                    Uuid::from_slice(value).map_err(de_error)
                }

                fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
                where
                    A: de::SeqAccess<'vi>,
                {
                    #[rustfmt::skip]
                    let bytes = [
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                    ];

                    Ok(Uuid::from_bytes(bytes))
                }
            }

            deserializer.deserialize_str(UuidVisitor)
        } else {
            let bytes: [u8; 16] = Deserialize::deserialize(deserializer)?;

            Ok(Uuid::from_bytes(bytes))
        }
    }
}

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

    use serde_test::{Compact, Configure, Readable, Token};

    #[test]
    fn test_serialize_readable_string() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_deserialize_readable_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_deserialize_readable_bytes() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[serde_test::Token::Bytes(uuid_bytes)],
        );
    }

    #[test]
    fn test_serialize_hyphenated() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(
            &u.to_hyphenated(),
            &[Token::Str(uuid_str)],
        );
    }

    #[test]
    fn test_serialize_simple() {
        let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_simple(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_urn() {
        let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_urn(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_braced() {
        let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_braced(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();
        serde_test::assert_tokens(
            &u.compact(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_de_failure() {
        serde_test::assert_de_tokens_error::<Readable<Uuid>>(
            &[Token::Str("hello_world")],
            "UUID parsing failed: invalid length: expected one of [36, 32], found 11",
        );

        serde_test::assert_de_tokens_error::<Compact<Uuid>>(
            &[Token::Bytes(b"hello_world")],
            "invalid type: byte array, expected an array of length 16",
        );
    }
}
<commit_msg>Fixed test<commit_after>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// 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 crate::{
    error::*,
    fmt::{
        Braced, BracedRef, Hyphenated, HyphenatedRef, Simple, SimpleRef, Urn,
        UrnRef,
    },
    std::fmt,
    Uuid,
};
use serde::{
    de::{self, Error as _},
    Deserialize, Deserializer, Serialize, Serializer,
};

impl Serialize for Uuid {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        if serializer.is_human_readable() {
            serializer.serialize_str(
                self.to_hyphenated()
                    .encode_lower(&mut Uuid::encode_buffer()),
            )
        } else {
            self.as_bytes().serialize(serializer)
        }
    }
}

impl Serialize for Hyphenated {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for HyphenatedRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Simple {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for SimpleRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Urn {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for UrnRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Braced {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for BracedRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl<'de> Deserialize<'de> for Uuid {
    fn deserialize<D: Deserializer<'de>>(
        deserializer: D,
    ) -> Result<Self, D::Error> {
        fn de_error<E: de::Error>(e: Error) -> E {
            E::custom(format_args!("UUID parsing failed: {}", e))
        }

        if deserializer.is_human_readable() {
            struct UuidVisitor;

            impl<'vi> de::Visitor<'vi> for UuidVisitor {
                type Value = Uuid;

                fn expecting(
                    &self,
                    formatter: &mut fmt::Formatter<'_>,
                ) -> fmt::Result {
                    write!(formatter, "a UUID string")
                }

                fn visit_str<E: de::Error>(
                    self,
                    value: &str,
                ) -> Result<Uuid, E> {
                    value.parse::<Uuid>().map_err(de_error)
                }

                fn visit_bytes<E: de::Error>(
                    self,
                    value: &[u8],
                ) -> Result<Uuid, E> {
                    Uuid::from_slice(value).map_err(de_error)
                }

                fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
                where
                    A: de::SeqAccess<'vi>,
                {
                    #[rustfmt::skip]
                    let bytes = [
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                    ];

                    Ok(Uuid::from_bytes(bytes))
                }
            }

            deserializer.deserialize_str(UuidVisitor)
        } else {
            let bytes: [u8; 16] = Deserialize::deserialize(deserializer)?;

            Ok(Uuid::from_bytes(bytes))
        }
    }
}

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

    use serde_test::{Compact, Configure, Readable, Token};

    #[test]
    fn test_serialize_readable_string() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_deserialize_readable_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_deserialize_readable_bytes() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[serde_test::Token::Bytes(uuid_bytes)],
        );
    }

    #[test]
    fn test_serialize_hyphenated() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(
            &u.to_hyphenated(),
            &[Token::Str(uuid_str)],
        );
    }

    #[test]
    fn test_serialize_simple() {
        let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_simple(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_urn() {
        let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_urn(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_braced() {
        let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_braced(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();
        serde_test::assert_tokens(
            &u.compact(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_de_failure() {
        serde_test::assert_de_tokens_error::<Readable<Uuid>>(
            &[Token::Str("hello_world")],
            "UUID parsing failed: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `h` at 1",
        );

        serde_test::assert_de_tokens_error::<Compact<Uuid>>(
            &[Token::Bytes(b"hello_world")],
            "invalid type: byte array, expected an array of length 16",
        );
    }
}
<|endoftext|>


<commit_before>use ammonia::{Builder, UrlRelative};
use comrak;
use htmlescape::encode_minimal;
use std::borrow::Cow;
use std::path::Path;
use url::Url;

use util::CargoResult;

/// Context for markdown to HTML rendering.
#[allow(missing_debug_implementations)]
struct MarkdownRenderer<'a> {
    html_sanitizer: Builder<'a>,
}

impl<'a> MarkdownRenderer<'a> {
    /// Creates a new renderer instance.
    ///
    /// Per `readme_to_html`, `base_url` is the base URL prepended to any
    /// relative links in the input document.  See that function for more detail.
    fn new(base_url: Option<&'a str>) -> MarkdownRenderer<'a> {
        let tags = [
            "a",
            "b",
            "blockquote",
            "br",
            "code",
            "dd",
            "del",
            "dl",
            "dt",
            "em",
            "h1",
            "h2",
            "h3",
            "hr",
            "i",
            "img",
            "input",
            "kbd",
            "li",
            "ol",
            "p",
            "pre",
            "s",
            "strike",
            "strong",
            "sub",
            "sup",
            "table",
            "tbody",
            "td",
            "th",
            "thead",
            "tr",
            "ul",
            "hr",
            "span",
        ].iter()
            .cloned()
            .collect();
        let tag_attributes = [
            ("a", ["href", "id", "target"].iter().cloned().collect()),
            (
                "img",
                ["width", "height", "src", "alt", "align"]
                    .iter()
                    .cloned()
                    .collect(),
            ),
            (
                "input",
                ["checked", "disabled", "type"].iter().cloned().collect(),
            ),
        ].iter()
            .cloned()
            .collect();
        let allowed_classes = [
            (
                "code",
                [
                    "language-bash",
                    "language-clike",
                    "language-glsl",
                    "language-go",
                    "language-ini",
                    "language-javascript",
                    "language-json",
                    "language-markup",
                    "language-protobuf",
                    "language-ruby",
                    "language-rust",
                    "language-scss",
                    "language-sql",
                    "yaml",
                ].iter()
                    .cloned()
                    .collect(),
            ),
        ].iter()
            .cloned()
            .collect();

        let sanitizer_base_url = base_url.map(|s| s.to_string());

        // Constrain the type of the closures given to the HTML sanitizer.
        fn constrain_closure<F>(f: F) -> F
        where
            F: for<'a> Fn(&'a str) -> Option<Cow<'a, str>> + Send + Sync,
        {
            f
        }

        let unrelative_url_sanitizer = constrain_closure(|url| {
            // We have no base URL; allow fragment links only.
            if url.starts_with('#') {
                return Some(Cow::Borrowed(url));
            }

            None
        });

        fn is_media_url(url: &str) -> bool {
            Path::new(url)
                .extension()
                .and_then(|e| e.to_str())
                .map_or(false, |e| match e {
                    "png" | "svg" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => true,
                    _ => false,
                })
        }

        let relative_url_sanitizer = constrain_closure(move |url| {
            // sanitizer_base_url is Some(String); use it to fix the relative URL.
            if url.starts_with('#') {
                return Some(Cow::Borrowed(url));
            }

            let mut new_url = sanitizer_base_url.clone().unwrap();
            if !new_url.ends_with('/') {
                new_url.push('/');
            }
            if new_url.ends_with(".git/") {
                let offset = new_url.len() - 5;
                new_url.drain(offset..offset + 4);
            }
            // Assumes GitHub's URL scheme. GitHub renders text and markdown
            // better in the "blob" view, but images need to be served raw.
            new_url += if is_media_url(url) {
                "raw/master"
            } else {
                "blob/master"
            };
            if !url.starts_with('/') {
                new_url.push('/');
            }
            new_url += url;
            Some(Cow::Owned(new_url))
        });

        let use_relative = if let Some(base_url) = base_url {
            if let Ok(url) = Url::parse(base_url) {
                url.host_str() == Some("github.com") || url.host_str() == Some("gitlab.com")
                    || url.host_str() == Some("bitbucket.org")
            } else {
                false
            }
        } else {
            false
        };

        let mut html_sanitizer = Builder::new();
        html_sanitizer
            .link_rel(Some("nofollow noopener noreferrer"))
            .tags(tags)
            .tag_attributes(tag_attributes)
            .allowed_classes(allowed_classes)
            .url_relative(if use_relative {
                UrlRelative::Custom(Box::new(relative_url_sanitizer))
            } else {
                UrlRelative::Custom(Box::new(unrelative_url_sanitizer))
            })
            .id_prefix(Some("user-content-"));

        MarkdownRenderer { html_sanitizer }
    }

    /// Renders the given markdown to HTML using the current settings.
    fn to_html(&self, text: &str) -> CargoResult<String> {
        let options = comrak::ComrakOptions {
            ext_autolink: true,
            ext_strikethrough: true,
            ext_table: true,
            ext_tagfilter: true,
            ext_tasklist: true,
            ext_header_ids: Some("user-content-".to_string()),
            ..comrak::ComrakOptions::default()
        };
        let rendered = comrak::markdown_to_html(text, &options);
        Ok(self.html_sanitizer.clean(&rendered).to_string())
    }
}

/// Renders Markdown text to sanitized HTML with a given `base_url`.
/// See `readme_to_html` for the interpretation of `base_url`.
fn markdown_to_html(text: &str, base_url: Option<&str>) -> CargoResult<String> {
    let renderer = MarkdownRenderer::new(base_url);
    renderer.to_html(text)
}

/// Any readme with a filename ending in one of these extensions will be rendered as Markdown.
/// Note we also render a readme as Markdown if _no_ extension is on the filename.
static MARKDOWN_EXTENSIONS: [&'static str; 7] = [
    ".md",
    ".markdown",
    ".mdown",
    ".mdwn",
    ".mkd",
    ".mkdn",
    ".mkdown",
];

/// Renders a readme to sanitized HTML.  An appropriate rendering method is chosen depending
/// on the extension of the supplied `filename`.
///
/// The returned text will not contain any harmful HTML tag or attribute (such as iframe,
/// onclick, onmouseover, etc.).
///
/// The `base_url` parameter will be used as the base for any relative links found in the
/// Markdown, as long as its host part is github.com, gitlab.com, or bitbucket.org.  The
/// supplied URL will be used as a directory base whether or not the relative link is
/// prefixed with '/'.  If `None` is passed, relative links will be omitted.
///
/// # Examples
///
/// ```
/// use render::render_to_html;
///
/// let text = "[Rust](https://rust-lang.org/) is an awesome *systems programming* language!";
/// let rendered = readme_to_html(text, "README.md", None)?;
/// ```
pub fn readme_to_html(text: &str, filename: &str, base_url: Option<&str>) -> CargoResult<String> {
    let filename = filename.to_lowercase();

    if !filename.contains('.') || MARKDOWN_EXTENSIONS.iter().any(|e| filename.ends_with(e)) {
        return markdown_to_html(text, base_url);
    }

    Ok(encode_minimal(text).replace("\n", "
\n"))
}

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

    #[test]
    fn empty_text() {
        let text = "";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "");
    }

    #[test]
    fn text_with_script_tag() {
        let text = "foo_readme\n\n";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
foo_readme
\n<script>alert(\'Hello World\')</script>\n"
        );
    }

    #[test]
    fn text_with_iframe_tag() {
        let text = "foo_readme\n\nalert('Hello World')";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
foo_readme
\n<iframe>alert(\'Hello World\')</iframe>\n"
        );
    }

    #[test]
    fn text_with_unknown_tag() {
        let text = "foo_readme\n\n<unknown>alert('Hello World')</unknown>";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "
foo_readme
\n
alert(\'Hello World\')
\n");
    }

    #[test]
    fn text_with_inline_javascript() {
        let text =
            r#"foo_readme\n\nCrate page"#;
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
foo_readme\\n\\nCrate page
\n"
        );
    }

    // See https://github.com/kivikakk/comrak/issues/37. This panic happened
    // in comrak 0.1.8 but was fixed in 0.1.9.
    #[test]
    fn text_with_fancy_single_quotes() {
        let text = r#"wb’"#;
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "
wb’
\n");
    }

    #[test]
    fn code_block_with_syntax_highlighting() {
        let code_block = r#"```rust \
                            println!("Hello World"); \
                           ```"#;
        let result = markdown_to_html(code_block, None).unwrap();
        assert!(result.contains(""));
    }

    #[test]
    fn text_with_forbidden_class_attribute() {
        let text = "
Hello World!
";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "
Hello World!
\n");
    }

    #[test]
    fn relative_links() {
        let absolute = "[hi](/hi)";
        let relative = "[there](there)";
        let image = "![alt](img.png)";

        for host in &["github.com", "gitlab.com", "bitbucket.org"] {
            for (&extra_slash, &dot_git) in [true, false].iter().zip(&[true, false]) {
                let url = format!(
                    "https://{}/rust-lang/test{}{}",
                    host,
                    if dot_git { ".git" } else { "" },
                    if extra_slash { "/" } else { "" },
                );

                let result = markdown_to_html(absolute, Some(&url)).unwrap();
                assert_eq!(
                    result,
                    format!(
                        "
hi
\n",
                        host
                    )
                );

                let result = markdown_to_html(relative, Some(&url)).unwrap();
                assert_eq!(
                    result,
                    format!(
                        "
there
\n",
                        host
                    )
                );

                let result = markdown_to_html(image, Some(&url)).unwrap();
                assert_eq!(
                    result,
                    format!(
                        "

\n",
                        host
                    )
                );
            }
        }

        let result = markdown_to_html(absolute, Some("https://google.com/")).unwrap();
        assert_eq!(
            result,
            "
hi
\n"
        );
    }

    #[test]
    fn absolute_links_dont_get_resolved() {
        let readme_text =
            "[![Crates.io](https://img.shields.io/crates/v/clap.svg)](https://crates.io/crates/clap)";
        let repository = "https://github.com/kbknapp/clap-rs/";
        let result = markdown_to_html(readme_text, Some(&repository)).unwrap();

        assert_eq!(
            result,
            "

\n"
        );
    }

    #[test]
    fn readme_to_html_renders_markdown() {
        for f in &["README", "readme.md", "README.MARKDOWN", "whatever.mkd"] {
            assert_eq!(
                readme_to_html("*lobster*", f, None).unwrap(),
                "
lobster
\n"
            );
        }
    }

    #[test]
    fn readme_to_html_renders_other_things() {
        for f in &["readme.exe", "readem.org", "blah.adoc"] {
            assert_eq!(
                readme_to_html("\n\nis my friend\n", f, None).unwrap(),
                "<script>lobster</script>
\n
\nis my friend
\n"
            );
        }
    }

    #[test]
    fn header_has_tags() {
        let text = "# My crate\n\nHello, world!\n";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
My crate
\n
Hello, world!
\n"
        );
    }

    #[test]
    fn manual_anchor_is_sanitized() {
        let text =
            "
My crate
\n
Hello, world!
\n";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
My crate
\n
Hello, world!
\n"
        );
    }
}
<commit_msg>Rustfmt workarounds<commit_after>use ammonia::{Builder, UrlRelative};
use comrak;
use htmlescape::encode_minimal;
use std::borrow::Cow;
use std::path::Path;
use url::Url;

use util::CargoResult;

/// Context for markdown to HTML rendering.
#[allow(missing_debug_implementations)]
struct MarkdownRenderer<'a> {
    html_sanitizer: Builder<'a>,
}

impl<'a> MarkdownRenderer<'a> {
    /// Creates a new renderer instance.
    ///
    /// Per `readme_to_html`, `base_url` is the base URL prepended to any
    /// relative links in the input document.  See that function for more detail.
    fn new(base_url: Option<&'a str>) -> MarkdownRenderer<'a> {
        let tags = [
            "a",
            "b",
            "blockquote",
            "br",
            "code",
            "dd",
            "del",
            "dl",
            "dt",
            "em",
            "h1",
            "h2",
            "h3",
            "hr",
            "i",
            "img",
            "input",
            "kbd",
            "li",
            "ol",
            "p",
            "pre",
            "s",
            "strike",
            "strong",
            "sub",
            "sup",
            "table",
            "tbody",
            "td",
            "th",
            "thead",
            "tr",
            "ul",
            "hr",
            "span",
        ].iter()
            .cloned()
            .collect();
        let tag_attributes = [
            ("a", ["href", "id", "target"].iter().cloned().collect()),
            (
                "img",
                ["width", "height", "src", "alt", "align"]
                    .iter()
                    .cloned()
                    .collect(),
            ),
            (
                "input",
                ["checked", "disabled", "type"].iter().cloned().collect(),
            ),
        ].iter()
            .cloned()
            .collect();
        let allowed_classes = [
            (
                "code",
                [
                    "language-bash",
                    "language-clike",
                    "language-glsl",
                    "language-go",
                    "language-ini",
                    "language-javascript",
                    "language-json",
                    "language-markup",
                    "language-protobuf",
                    "language-ruby",
                    "language-rust",
                    "language-scss",
                    "language-sql",
                    "yaml",
                ].iter()
                    .cloned()
                    .collect(),
            ),
        ].iter()
            .cloned()
            .collect();

        let sanitizer_base_url = base_url.map(|s| s.to_string());

        // Constrain the type of the closures given to the HTML sanitizer.
        fn constrain_closure<F>(f: F) -> F
        where
            F: for<'a> Fn(&'a str) -> Option<Cow<'a, str>> + Send + Sync,
        {
            f
        }

        let unrelative_url_sanitizer = constrain_closure(|url| {
            // We have no base URL; allow fragment links only.
            if url.starts_with('#') {
                return Some(Cow::Borrowed(url));
            }

            None
        });

        fn is_media_url(url: &str) -> bool {
            Path::new(url)
                .extension()
                .and_then(|e| e.to_str())
                .map_or(false, |e| match e {
                    "png" | "svg" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => true,
                    _ => false,
                })
        }

        let relative_url_sanitizer = constrain_closure(move |url| {
            // sanitizer_base_url is Some(String); use it to fix the relative URL.
            if url.starts_with('#') {
                return Some(Cow::Borrowed(url));
            }

            let mut new_url = sanitizer_base_url.clone().unwrap();
            if !new_url.ends_with('/') {
                new_url.push('/');
            }
            if new_url.ends_with(".git/") {
                let offset = new_url.len() - 5;
                new_url.drain(offset..offset + 4);
            }
            // Assumes GitHub’s URL scheme. GitHub renders text and markdown
            // better in the "blob" view, but images need to be served raw.
            new_url += if is_media_url(url) {
                "raw/master"
            } else {
                "blob/master"
            };
            if !url.starts_with('/') {
                new_url.push('/');
            }
            new_url += url;
            Some(Cow::Owned(new_url))
        });

        let use_relative = if let Some(base_url) = base_url {
            if let Ok(url) = Url::parse(base_url) {
                url.host_str() == Some("github.com") || url.host_str() == Some("gitlab.com")
                    || url.host_str() == Some("bitbucket.org")
            } else {
                false
            }
        } else {
            false
        };

        let mut html_sanitizer = Builder::new();
        html_sanitizer
            .link_rel(Some("nofollow noopener noreferrer"))
            .tags(tags)
            .tag_attributes(tag_attributes)
            .allowed_classes(allowed_classes)
            .url_relative(if use_relative {
                UrlRelative::Custom(Box::new(relative_url_sanitizer))
            } else {
                UrlRelative::Custom(Box::new(unrelative_url_sanitizer))
            })
            .id_prefix(Some("user-content-"));

        MarkdownRenderer { html_sanitizer }
    }

    /// Renders the given markdown to HTML using the current settings.
    fn to_html(&self, text: &str) -> CargoResult<String> {
        let options = comrak::ComrakOptions {
            ext_autolink: true,
            ext_strikethrough: true,
            ext_table: true,
            ext_tagfilter: true,
            ext_tasklist: true,
            ext_header_ids: Some("user-content-".to_string()),
            ..comrak::ComrakOptions::default()
        };
        let rendered = comrak::markdown_to_html(text, &options);
        Ok(self.html_sanitizer.clean(&rendered).to_string())
    }
}

/// Renders Markdown text to sanitized HTML with a given `base_url`.
/// See `readme_to_html` for the interpretation of `base_url`.
fn markdown_to_html(text: &str, base_url: Option<&str>) -> CargoResult<String> {
    let renderer = MarkdownRenderer::new(base_url);
    renderer.to_html(text)
}

/// Any readme with a filename ending in one of these extensions will be rendered as Markdown.
/// Note we also render a readme as Markdown if _no_ extension is on the filename.
static MARKDOWN_EXTENSIONS: [&'static str; 7] = [
    ".md",
    ".markdown",
    ".mdown",
    ".mdwn",
    ".mkd",
    ".mkdn",
    ".mkdown",
];

/// Renders a readme to sanitized HTML.  An appropriate rendering method is chosen depending
/// on the extension of the supplied `filename`.
///
/// The returned text will not contain any harmful HTML tag or attribute (such as iframe,
/// onclick, onmouseover, etc.).
///
/// The `base_url` parameter will be used as the base for any relative links found in the
/// Markdown, as long as its host part is github.com, gitlab.com, or bitbucket.org.  The
/// supplied URL will be used as a directory base whether or not the relative link is
/// prefixed with '/'.  If `None` is passed, relative links will be omitted.
///
/// # Examples
///
/// ```
/// use render::render_to_html;
///
/// let text = "[Rust](https://rust-lang.org/) is an awesome *systems programming* language!";
/// let rendered = readme_to_html(text, "README.md", None)?;
/// ```
pub fn readme_to_html(text: &str, filename: &str, base_url: Option<&str>) -> CargoResult<String> {
    let filename = filename.to_lowercase();

    if !filename.contains('.') || MARKDOWN_EXTENSIONS.iter().any(|e| filename.ends_with(e)) {
        return markdown_to_html(text, base_url);
    }

    Ok(encode_minimal(text).replace("\n", "
\n"))
}

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

    #[test]
    fn empty_text() {
        let text = "";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "");
    }

    #[test]
    fn text_with_script_tag() {
        let text = "foo_readme\n\n";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
foo_readme
\n<script>alert(\'Hello World\')</script>\n"
        );
    }

    #[test]
    fn text_with_iframe_tag() {
        let text = "foo_readme\n\nalert('Hello World')";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
foo_readme
\n<iframe>alert(\'Hello World\')</iframe>\n"
        );
    }

    #[test]
    fn text_with_unknown_tag() {
        let text = "foo_readme\n\n<unknown>alert('Hello World')</unknown>";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "
foo_readme
\n
alert(\'Hello World\')
\n");
    }

    #[test]
    fn text_with_inline_javascript() {
        let text =
            r#"foo_readme\n\nCrate page"#;
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
foo_readme\\n\\nCrate page
\n"
        );
    }

    // See https://github.com/kivikakk/comrak/issues/37. This panic happened
    // in comrak 0.1.8 but was fixed in 0.1.9.
    #[test]
    fn text_with_fancy_single_quotes() {
        let text = r#"wb’"#;
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "
wb’
\n");
    }

    #[test]
    fn code_block_with_syntax_highlighting() {
        let code_block = r#"```rust \
                            println!("Hello World"); \
                           ```"#;
        let result = markdown_to_html(code_block, None).unwrap();
        assert!(result.contains(""));
    }

    #[test]
    fn text_with_forbidden_class_attribute() {
        let text = "
Hello World!
";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(result, "
Hello World!
\n");
    }

    #[test]
    fn relative_links() {
        let absolute = "[hi](/hi)";
        let relative = "[there](there)";
        let image = "![alt](img.png)";

        for host in &["github.com", "gitlab.com", "bitbucket.org"] {
            for (&extra_slash, &dot_git) in [true, false].iter().zip(&[true, false]) {
                let url = format!(
                    "https://{}/rust-lang/test{}{}",
                    host,
                    if dot_git { ".git" } else { "" },
                    if extra_slash { "/" } else { "" },
                );

                let result = markdown_to_html(absolute, Some(&url)).unwrap();
                assert_eq!(
                    result,
                    format!(
                        "
hi
\n",
                        host
                    )
                );

                let result = markdown_to_html(relative, Some(&url)).unwrap();
                assert_eq!(
                    result,
                    format!(
                        "
there
\n",
                        host
                    )
                );

                let result = markdown_to_html(image, Some(&url)).unwrap();
                assert_eq!(
                    result,
                    format!(
                 "

\n",
                        host
                    )
                );
            }
        }

        let result = markdown_to_html(absolute, Some("https://google.com/")).unwrap();
        assert_eq!(
            result,
            "
hi
\n"
        );
    }

    #[test]
    fn absolute_links_dont_get_resolved() {
        let readme_text =
            "[![Crates.io](https://img.shields.io/crates/v/clap.svg)](https://crates.io/crates/clap)";
        let repository = "https://github.com/kbknapp/clap-rs/";
        let result = markdown_to_html(readme_text, Some(&repository)).unwrap();

        assert_eq!(
            result,
            "

\n"
        );
    }

    #[test]
    fn readme_to_html_renders_markdown() {
        for f in &["README", "readme.md", "README.MARKDOWN", "whatever.mkd"] {
            assert_eq!(
                readme_to_html("*lobster*", f, None).unwrap(),
                "
lobster
\n"
            );
        }
    }

    #[test]
    fn readme_to_html_renders_other_things() {
        for f in &["readme.exe", "readem.org", "blah.adoc"] {
            assert_eq!(
                readme_to_html("\n\nis my friend\n", f, None).unwrap(),
                "<script>lobster</script>
\n
\nis my friend
\n"
            );
        }
    }

    #[test]
    fn header_has_tags() {
        let text = "# My crate\n\nHello, world!\n";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
My crate
\n
Hello, world!
\n"
        );
    }

    #[test]
    fn manual_anchor_is_sanitized() {
        let text =
            "
My crate
\n
Hello, world!
\n";
        let result = markdown_to_html(text, None).unwrap();
        assert_eq!(
            result,
            "
My crate
\n
Hello, world!
\n"
        );
    }
}
<|endoftext|>


<commit_before>//Interrupt bit masks
const VBLANK_MASK:  u8 = 1 << 0;
const LCDSTAT_MASK: u8 = 1 << 1;
const TIMER_MASK:   u8 = 1 << 2;
const SERIAL_MASK:  u8 = 1 << 3;
const JOYPAD_MASK:  u8 = 1 << 4;

//Interrupt handler addresses
const VBLANK_ADDR:  u16 = 0x0040;
const LCDSTAT_ADDR: u16 = 0x0048;
const TIMER_ADDR:   u16 = 0x0050;
const SERIAL_ADDR:  u16 = 0x0058;
const JOYPAD_ADDR:  u16 = 0x0060;

#[derive(Debug, PartialEq, Eq)]
pub enum Interrupt {
	VBlank, LcdStat, Timer, Serial, Joypad
}

impl Interrupt {
	pub fn mask(&self) -> u8 {
		use self::Interrupt::*;
		match *self {
			VBlank => VBLANK_MASK,
			LcdStat => LCDSTAT_MASK,
			Timer => TIMER_MASK,
			Serial => SERIAL_MASK,
			Joypad => JOYPAD_MASK
		}
	}

	pub fn address(&self) -> u16 {
		use self::Interrupt::*;
		match *self {
			VBlank => VBLANK_ADDR,
			LcdStat => LCDSTAT_ADDR,
			Timer => TIMER_ADDR,
			Serial => SERIAL_ADDR,
			Joypad => JOYPAD_ADDR
		}
	}
}

/// Interrupt Flag Register - $FF0F
#[derive(Clone, Copy)]
pub struct InterruptFlag {
	value: u8,
}

impl InterruptFlag {
	/// Constructor that initializes the value of the register to the post bootrom value
	pub fn new() -> InterruptFlag {
		InterruptFlag { value: 0x01 }
	}

	pub fn reset(&mut self) {
		self.value = 1;
	}

	pub fn request_interrupt(&mut self, int: Interrupt) {
		self.value |= int.mask();
	}

	pub fn clear_interrupt(&mut self, int: Interrupt) {
		self.value &= !int.mask();
	}

	//TODO: are the high bits always read as 1 or are they always read as 0
	pub fn read(&self) -> u8 {
		self.value & 0x1F
	}

	pub fn write(&mut self, value: u8) {
		self.value = value & 0x1F;
	}
}

#[derive(Clone, Copy, Default)]
pub struct InterruptEnable {
	value: u8
}

/// Interrupt Enable Register - $FFFF
impl InterruptEnable {
	/// Constructor that initializes the value of the register to the post bootrom value
	pub fn new() -> InterruptEnable {
		InterruptEnable { value: 0 }
	}

	pub fn reset(&mut self) {
		self.value = 0;
	}

	//TODO: are the high bits always read as 1 or are they always read as 0
	pub fn read(&self) -> u8 {
		self.value & 0x1F
	}

	pub fn write(&mut self, value: u8) {
		self.value = value & 0x1F;
	}
}

/// Passed to components that need to request interrupts, but don't have access to the global emulator state.
pub struct InterruptLine<'a> {
	interrupt_flag: &'a mut InterruptFlag,
	halt: &'a mut bool,
	stop: &'a mut bool
}

impl<'a> InterruptLine<'a> {
	pub fn new(interrupt_flag: &'a mut InterruptFlag, halt: &'a mut bool, stop: &'a mut bool) -> InterruptLine<'a> {
		InterruptLine {
			interrupt_flag: interrupt_flag,
			halt: halt,
			stop: stop
		}
	}

	/// Request an interrupt
	/// Interrupts will wake the cpu if it is stopped or halted.
	pub fn request_interrupt(&mut self, int: Interrupt) {
		self.interrupt_flag.request_interrupt(int);
		*self.halt = false;
		*self.stop = false;
	}
}
<commit_msg>High 3 bits of IE and IF should always be read as 1.<commit_after>//Interrupt bit masks
const VBLANK_MASK:  u8 = 1 << 0;
const LCDSTAT_MASK: u8 = 1 << 1;
const TIMER_MASK:   u8 = 1 << 2;
const SERIAL_MASK:  u8 = 1 << 3;
const JOYPAD_MASK:  u8 = 1 << 4;

//Interrupt handler addresses
const VBLANK_ADDR:  u16 = 0x0040;
const LCDSTAT_ADDR: u16 = 0x0048;
const TIMER_ADDR:   u16 = 0x0050;
const SERIAL_ADDR:  u16 = 0x0058;
const JOYPAD_ADDR:  u16 = 0x0060;

#[derive(Debug, PartialEq, Eq)]
pub enum Interrupt {
	VBlank, LcdStat, Timer, Serial, Joypad
}

impl Interrupt {
	pub fn mask(&self) -> u8 {
		use self::Interrupt::*;
		match *self {
			VBlank => VBLANK_MASK,
			LcdStat => LCDSTAT_MASK,
			Timer => TIMER_MASK,
			Serial => SERIAL_MASK,
			Joypad => JOYPAD_MASK
		}
	}

	pub fn address(&self) -> u16 {
		use self::Interrupt::*;
		match *self {
			VBlank => VBLANK_ADDR,
			LcdStat => LCDSTAT_ADDR,
			Timer => TIMER_ADDR,
			Serial => SERIAL_ADDR,
			Joypad => JOYPAD_ADDR
		}
	}
}

/// Interrupt Flag Register - $FF0F
#[derive(Clone, Copy)]
pub struct InterruptFlag {
	value: u8,
}

impl InterruptFlag {
	/// Constructor that initializes the value of the register to the post bootrom value
	pub fn new() -> InterruptFlag {
		InterruptFlag { value: 0x01 }
	}

	pub fn reset(&mut self) {
		self.value = 1;
	}

	pub fn request_interrupt(&mut self, int: Interrupt) {
		self.value |= int.mask();
	}

	pub fn clear_interrupt(&mut self, int: Interrupt) {
		self.value &= !int.mask();
	}

	/// Read from the IF register.
	/// High 3 bits always read as 1.
	pub fn read(&self) -> u8 {
		self.value | 0xE0
	}

	pub fn write(&mut self, value: u8) {
		self.value = value & 0x1F;
	}
}

#[derive(Clone, Copy, Default)]
pub struct InterruptEnable {
	value: u8
}

/// Interrupt Enable Register - $FFFF
impl InterruptEnable {
	/// Constructor that initializes the value of the register to the post bootrom value
	pub fn new() -> InterruptEnable {
		InterruptEnable { value: 0 }
	}

	pub fn reset(&mut self) {
		self.value = 0;
	}

	/// Read from the IE register.
	/// High 3 bits always read as 1.
	pub fn read(&self) -> u8 {
		self.value | 0xE0
	}

	pub fn write(&mut self, value: u8) {
		self.value = value & 0x1F;
	}
}

/// Passed to components that need to request interrupts, but don't have access to the global emulator state.
pub struct InterruptLine<'a> {
	interrupt_flag: &'a mut InterruptFlag,
	halt: &'a mut bool,
	stop: &'a mut bool
}

impl<'a> InterruptLine<'a> {
	pub fn new(interrupt_flag: &'a mut InterruptFlag, halt: &'a mut bool, stop: &'a mut bool) -> InterruptLine<'a> {
		InterruptLine {
			interrupt_flag: interrupt_flag,
			halt: halt,
			stop: stop
		}
	}

	/// Request an interrupt
	/// Interrupts will wake the cpu if it is stopped or halted.
	pub fn request_interrupt(&mut self, int: Interrupt) {
		self.interrupt_flag.request_interrupt(int);
		*self.halt = false;
		*self.stop = false;
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//! Routers allow converting IPC channels to crossbeam channels.
//! The [RouterProxy](router::RouterProxy) provides various methods to register `IpcReceiver<T>`s.
//! The router will then either call the appropriate callback
//! or route the message to a crossbeam `Sender<T>` or `Receiver<T>`.
//! You should use the global `ROUTER` to access the `RouterProxy` methods (via `ROUTER`'s
//! `Deref` for `RouterProxy`.
use std::collections::HashMap;
use std::sync::Mutex;
use std::thread;

use crate::ipc::OpaqueIpcReceiver;
use crate::ipc::{
    self, IpcReceiver, IpcReceiverSet, IpcSelectionResult, IpcSender, OpaqueIpcMessage,
};
use crossbeam_channel::{self, Receiver, Sender};
use serde::{Deserialize, Serialize};

lazy_static! {
    /// Global object wrapping a `RouterProxy`.
    /// Add routes ([add_route](RouterProxy::add_route)), or convert IpcReceiver<T>
    /// to crossbeam channels (e.g. [route_ipc_receiver_to_new_crossbeam_receiver](RouterProxy::route_ipc_receiver_to_new_crossbeam_receiver))
    pub static ref ROUTER: RouterProxy = RouterProxy::new();
}

/// A `RouterProxy` provides methods for talking to the router. Calling
/// [new](RouterProxy::new) automatically spins up a router thread which
/// waits for events on its registered `IpcReceiver<T>`s. The `RouterProxy`'s
/// methods communicate with the running router thread to register new
/// `IpcReceiver<T>`'s
pub struct RouterProxy {
    comm: Mutex<RouterProxyComm>,
}

impl RouterProxy {
    pub fn new() -> RouterProxy {
        // Router acts like a receiver, running in its own thread with both
        // receiver ends.
        // Router proxy takes both sending ends.
        let (msg_sender, msg_receiver) = crossbeam_channel::unbounded();
        let (wakeup_sender, wakeup_receiver) = ipc::channel().unwrap();
        thread::spawn(move || Router::new(msg_receiver, wakeup_receiver).run());
        RouterProxy {
            comm: Mutex::new(RouterProxyComm {
                msg_sender: msg_sender,
                wakeup_sender: wakeup_sender,
            }),
        }
    }

    /// Add a new (receiver, callback) pair to the router, and send a wakeup message
    /// to the router.
    pub fn add_route(&self, receiver: OpaqueIpcReceiver, callback: RouterHandler) {
        let comm = self.comm.lock().unwrap();
        comm.msg_sender
            .send(RouterMsg::AddRoute(receiver, callback))
            .unwrap();
        comm.wakeup_sender.send(()).unwrap();
    }

    /// A convenience function to route an `IpcReceiver<T>` to an existing `Sender<T>`.
    pub fn route_ipc_receiver_to_crossbeam_sender<T>(
        &self,
        ipc_receiver: IpcReceiver<T>,
        crossbeam_sender: Sender<T>,
    ) where
        T: for<'de> Deserialize<'de> + Serialize + Send + 'static,
    {
        self.add_route(
            ipc_receiver.to_opaque(),
            Box::new(move |message| drop(crossbeam_sender.send(message.to::<T>().unwrap()))),
        )
    }

    /// A convenience function to route an `IpcReceiver<T>` to a `Receiver<T>`: the most common
    /// use of a `Router`.
    pub fn route_ipc_receiver_to_new_crossbeam_receiver<T>(
        &self,
        ipc_receiver: IpcReceiver<T>,
    ) -> Receiver<T>
    where
        T: for<'de> Deserialize<'de> + Serialize + Send + 'static,
    {
        let (crossbeam_sender, crossbeam_receiver) = crossbeam_channel::unbounded();
        self.route_ipc_receiver_to_crossbeam_sender(ipc_receiver, crossbeam_sender);
        crossbeam_receiver
    }
}

struct RouterProxyComm {
    msg_sender: Sender<RouterMsg>,
    wakeup_sender: IpcSender<()>,
}

/// Router runs in its own thread listening for events. Adds events to its IpcReceiverSet
/// and listens for events using select().
struct Router {
    /// Get messages from RouterProxy. Currently, the only message supported is:
    /// `AddRoute(OpaqueIpcReceiver, RouterHandler)`. Add a new receiver which will
    /// call function: RouterHandler when new event arrives.
    msg_receiver: Receiver<RouterMsg>,
    /// The ID/index of the special channel we use to identify messages from msg_receiver.
    msg_wakeup_id: u64,
    /// Set of all receivers which have been registered for us to select on.
    ipc_receiver_set: IpcReceiverSet,
    /// Maps ids to their handler functions.
    handlers: HashMap<u64, RouterHandler>,
}

impl Router {
    fn new(msg_receiver: Receiver<RouterMsg>, wakeup_receiver: IpcReceiver<()>) -> Router {
        let mut ipc_receiver_set = IpcReceiverSet::new().unwrap();
        let msg_wakeup_id = ipc_receiver_set.add(wakeup_receiver).unwrap();
        Router {
            msg_receiver: msg_receiver,
            msg_wakeup_id: msg_wakeup_id,
            ipc_receiver_set: ipc_receiver_set,
            handlers: HashMap::new(),
        }
    }

    /// Continously loop waiting for wakeup signals from router proxy.
    /// Iterate over events either:
    /// 1) If a message comes in from our special `wakeup_receiver` (identified through
    ///    msg_wakeup_id. Read message from `msg_receiver` and add a new receiver
    ///    to our receiver set.
    /// 2) Call appropriate handler based on message id.
    /// 3) Remove handler once channel closes.
    fn run(&mut self) {
        loop {
            // Wait for events to come from our select() new channels are added to
            // our ReceiverSet below.
            let results = match self.ipc_receiver_set.select() {
                Ok(results) => results,
                Err(_) => break,
            };

            // Iterate over numerous events that were ready at this time.
            for result in results.into_iter() {
                match result {
                    // Message came from the RouterProxy. Listen on our `msg_receiver`
                    // channel.
                    IpcSelectionResult::MessageReceived(id, _) if id == self.msg_wakeup_id =>
                        match self.msg_receiver.recv().unwrap() {
                            RouterMsg::AddRoute(receiver, handler) => {
                                let new_receiver_id =
                                    self.ipc_receiver_set.add_opaque(receiver).unwrap();
                                self.handlers.insert(new_receiver_id, handler);
                            },
                        },
                    // Event from one of our registered receivers, call callback.
                    IpcSelectionResult::MessageReceived(id, message) =>
                        self.handlers.get_mut(&id).unwrap()(message),
                    IpcSelectionResult::ChannelClosed(id) => {
                        self.handlers.remove(&id).unwrap();
                    },
                }
            }
        }
    }
}

enum RouterMsg {
    /// Register the receiver OpaqueIpcReceiver for listening for events on.
    /// When a message comes from this receiver, call RouterHandler.
    AddRoute(OpaqueIpcReceiver, RouterHandler),
}

/// Function to call when a new event is received from the corresponding receiver.
pub type RouterHandler = Box<FnMut(OpaqueIpcMessage) + Send>;
<commit_msg>Silence two warnings<commit_after>// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//! Routers allow converting IPC channels to crossbeam channels.
//! The [RouterProxy](router::RouterProxy) provides various methods to register `IpcReceiver<T>`s.
//! The router will then either call the appropriate callback
//! or route the message to a crossbeam `Sender<T>` or `Receiver<T>`.
//! You should use the global `ROUTER` to access the `RouterProxy` methods (via `ROUTER`'s
//! `Deref` for `RouterProxy`.
use std::collections::HashMap;
use std::sync::Mutex;
use std::thread;

use crate::ipc::OpaqueIpcReceiver;
use crate::ipc::{
    self, IpcReceiver, IpcReceiverSet, IpcSelectionResult, IpcSender, OpaqueIpcMessage,
};
use crossbeam_channel::{self, Receiver, Sender};
use serde::{Deserialize, Serialize};

lazy_static! {
    /// Global object wrapping a `RouterProxy`.
    /// Add routes ([add_route](RouterProxy::add_route)), or convert IpcReceiver<T>
    /// to crossbeam channels (e.g. [route_ipc_receiver_to_new_crossbeam_receiver](RouterProxy::route_ipc_receiver_to_new_crossbeam_receiver))
    pub static ref ROUTER: RouterProxy = RouterProxy::new();
}

/// A `RouterProxy` provides methods for talking to the router. Calling
/// [new](RouterProxy::new) automatically spins up a router thread which
/// waits for events on its registered `IpcReceiver<T>`s. The `RouterProxy`'s
/// methods communicate with the running router thread to register new
/// `IpcReceiver<T>`'s
pub struct RouterProxy {
    comm: Mutex<RouterProxyComm>,
}

impl RouterProxy {
    pub fn new() -> RouterProxy {
        // Router acts like a receiver, running in its own thread with both
        // receiver ends.
        // Router proxy takes both sending ends.
        let (msg_sender, msg_receiver) = crossbeam_channel::unbounded();
        let (wakeup_sender, wakeup_receiver) = ipc::channel().unwrap();
        thread::spawn(move || Router::new(msg_receiver, wakeup_receiver).run());
        RouterProxy {
            comm: Mutex::new(RouterProxyComm {
                msg_sender: msg_sender,
                wakeup_sender: wakeup_sender,
            }),
        }
    }

    /// Add a new (receiver, callback) pair to the router, and send a wakeup message
    /// to the router.
    pub fn add_route(&self, receiver: OpaqueIpcReceiver, callback: RouterHandler) {
        let comm = self.comm.lock().unwrap();
        comm.msg_sender
            .send(RouterMsg::AddRoute(receiver, callback))
            .unwrap();
        comm.wakeup_sender.send(()).unwrap();
    }

    /// A convenience function to route an `IpcReceiver<T>` to an existing `Sender<T>`.
    pub fn route_ipc_receiver_to_crossbeam_sender<T>(
        &self,
        ipc_receiver: IpcReceiver<T>,
        crossbeam_sender: Sender<T>,
    ) where
        T: for<'de> Deserialize<'de> + Serialize + Send + 'static,
    {
        self.add_route(
            ipc_receiver.to_opaque(),
            Box::new(move |message| drop(crossbeam_sender.send(message.to::<T>().unwrap()))),
        )
    }

    /// A convenience function to route an `IpcReceiver<T>` to a `Receiver<T>`: the most common
    /// use of a `Router`.
    pub fn route_ipc_receiver_to_new_crossbeam_receiver<T>(
        &self,
        ipc_receiver: IpcReceiver<T>,
    ) -> Receiver<T>
    where
        T: for<'de> Deserialize<'de> + Serialize + Send + 'static,
    {
        let (crossbeam_sender, crossbeam_receiver) = crossbeam_channel::unbounded();
        self.route_ipc_receiver_to_crossbeam_sender(ipc_receiver, crossbeam_sender);
        crossbeam_receiver
    }
}

struct RouterProxyComm {
    msg_sender: Sender<RouterMsg>,
    wakeup_sender: IpcSender<()>,
}

/// Router runs in its own thread listening for events. Adds events to its IpcReceiverSet
/// and listens for events using select().
struct Router {
    /// Get messages from RouterProxy. Currently, the only message supported is:
    /// `AddRoute(OpaqueIpcReceiver, RouterHandler)`. Add a new receiver which will
    /// call function: RouterHandler when new event arrives.
    msg_receiver: Receiver<RouterMsg>,
    /// The ID/index of the special channel we use to identify messages from msg_receiver.
    msg_wakeup_id: u64,
    /// Set of all receivers which have been registered for us to select on.
    ipc_receiver_set: IpcReceiverSet,
    /// Maps ids to their handler functions.
    handlers: HashMap<u64, RouterHandler>,
}

impl Router {
    fn new(msg_receiver: Receiver<RouterMsg>, wakeup_receiver: IpcReceiver<()>) -> Router {
        let mut ipc_receiver_set = IpcReceiverSet::new().unwrap();
        let msg_wakeup_id = ipc_receiver_set.add(wakeup_receiver).unwrap();
        Router {
            msg_receiver: msg_receiver,
            msg_wakeup_id: msg_wakeup_id,
            ipc_receiver_set: ipc_receiver_set,
            handlers: HashMap::new(),
        }
    }

    /// Continously loop waiting for wakeup signals from router proxy.
    /// Iterate over events either:
    /// 1) If a message comes in from our special `wakeup_receiver` (identified through
    ///    msg_wakeup_id. Read message from `msg_receiver` and add a new receiver
    ///    to our receiver set.
    /// 2) Call appropriate handler based on message id.
    /// 3) Remove handler once channel closes.
    fn run(&mut self) {
        loop {
            // Wait for events to come from our select() new channels are added to
            // our ReceiverSet below.
            let results = match self.ipc_receiver_set.select() {
                Ok(results) => results,
                Err(_) => break,
            };

            // Iterate over numerous events that were ready at this time.
            for result in results.into_iter() {
                match result {
                    // Message came from the RouterProxy. Listen on our `msg_receiver`
                    // channel.
                    IpcSelectionResult::MessageReceived(id, _) if id == self.msg_wakeup_id =>
                        match self.msg_receiver.recv().unwrap() {
                            RouterMsg::AddRoute(receiver, handler) => {
                                let new_receiver_id =
                                    self.ipc_receiver_set.add_opaque(receiver).unwrap();
                                self.handlers.insert(new_receiver_id, handler);
                            },
                        },
                    // Event from one of our registered receivers, call callback.
                    IpcSelectionResult::MessageReceived(id, message) =>
                        self.handlers.get_mut(&id).unwrap()(message),
                    IpcSelectionResult::ChannelClosed(id) => {
                        let _ = self.handlers.remove(&id).unwrap();
                    },
                }
            }
        }
    }
}

enum RouterMsg {
    /// Register the receiver OpaqueIpcReceiver for listening for events on.
    /// When a message comes from this receiver, call RouterHandler.
    AddRoute(OpaqueIpcReceiver, RouterHandler),
}

/// Function to call when a new event is received from the corresponding receiver.
pub type RouterHandler = Box<dyn FnMut(OpaqueIpcMessage) + Send>;
<|endoftext|>


<commit_before>
use std::cmp::min;
use std::fmt::Debug;
use ndarray::LinalgScalar;
use num_traits::float::Float;

use error::LapackError;
use binding;

pub trait MyFloat: Float {
    fn to_int(self) -> i32;
}

impl MyFloat for f64 {
    fn to_int(self) -> i32 {
        self as i32
    }
}
impl MyFloat for f32 {
    fn to_int(self) -> i32 {
        self as i32
    }
}

pub trait LapackScalar: Debug + MyFloat + LinalgScalar + binding::LapackBinding {
    fn eigh(n: usize, mut a: Vec<Self>) -> Result<(Vec<Self>, Vec<Self>), LapackError> {
        let mut w = vec![Self::zero(); n];
        let mut work = vec![Self::zero(); 4 * n];
        let mut info = 0;
        Self::_syev(b'V',
                    b'U',
                    n as i32,
                    &mut a,
                    n as i32,
                    &mut w,
                    &mut work,
                    4 * n as i32,
                    &mut info);
        if info == 0 {
            Ok((w, a))
        } else {
            Err(From::from(info))
        }
    }
    fn inv(size: usize, mut a: Vec<Self>) -> Result<Vec<Self>, LapackError> {
        let n = size as i32;
        let lda = n;
        let mut ipiv = vec![0; size];
        let mut info = 0;
        Self::_getrf(n, n, &mut a, lda, &mut ipiv, &mut info);
        if info != 0 {
            return Err(From::from(info));
        }
        let lwork = n;
        let mut work = vec![Self::zero(); size];
        Self::_getri(n, &mut a, lda, &mut ipiv, &mut work, lwork, &mut info);
        if info == 0 {
            Ok(a)
        } else {
            Err(From::from(info))
        }
    }
    fn norm_1(m: usize, n: usize, mut a: Vec<Self>) -> Self {
        let mut work = Vec::<Self>::new();
        Self::_lange(b'o', m as i32, n as i32, &mut a, m as i32, &mut work)
    }
    fn norm_i(m: usize, n: usize, mut a: Vec<Self>) -> Self {
        let mut work = vec![Self::zero(); m];
        Self::_lange(b'i', m as i32, n as i32, &mut a, m as i32, &mut work)
    }
    fn norm_f(m: usize, n: usize, mut a: Vec<Self>) -> Self {
        let mut work = Vec::<Self>::new();
        Self::_lange(b'f', m as i32, n as i32, &mut a, m as i32, &mut work)
    }
    fn svd(n: usize,
           m: usize,
           mut a: Vec<Self>)
           -> Result<(Vec<Self>, Vec<Self>, Vec<Self>), LapackError> {
        let mut info = 0;
        let n = n as i32;
        let m = m as i32;
        let lda = m;
        let ldu = m;
        let ldvt = n;
        let lwmax = 1000; // XXX
        let lwork = -1;
        let mut u = vec![Self::zero(); (ldu * m) as usize];
        let mut vt = vec![Self::zero(); (ldvt * n) as usize];
        let mut s = vec![Self::zero(); n as usize];
        let mut work = vec![Self::zero(); lwmax];
        Self::_gesvd('A' as u8,
                     'A' as u8,
                     m,
                     n,
                     &mut a,
                     lda,
                     &mut s,
                     &mut u,
                     ldu,
                     &mut vt,
                     ldvt,
                     &mut work,
                     lwork,
                     &mut info); // calc optimal work
        let lwork = min(lwmax as i32, work[0].to_int());
        Self::_gesvd('A' as u8,
                     'A' as u8,
                     m,
                     n,
                     &mut a,
                     lda,
                     &mut s,
                     &mut u,
                     ldu,
                     &mut vt,
                     ldvt,
                     &mut work,
                     lwork,
                     &mut info);
        if info == 0 {
            Ok((u, s, vt))
        } else {
            Err(From::from(info))
        }
    }
}

impl LapackScalar for f64 {}
impl LapackScalar for f32 {}
<commit_msg>s/MyFloat/TruncatableFloat/g<commit_after>
use std::cmp::min;
use std::fmt::Debug;
use ndarray::LinalgScalar;
use num_traits::float::Float;

use error::LapackError;
use binding;

pub trait TruncatableFloat: Float {
    fn to_int(self) -> i32;
}

impl TruncatableFloat for f64 {
    fn to_int(self) -> i32 {
        self as i32
    }
}
impl TruncatableFloat for f32 {
    fn to_int(self) -> i32 {
        self as i32
    }
}

pub trait LapackScalar
    : Debug + TruncatableFloat + LinalgScalar + binding::LapackBinding {
    fn eigh(n: usize, mut a: Vec<Self>) -> Result<(Vec<Self>, Vec<Self>), LapackError> {
        let mut w = vec![Self::zero(); n];
        let mut work = vec![Self::zero(); 4 * n];
        let mut info = 0;
        Self::_syev(b'V',
                    b'U',
                    n as i32,
                    &mut a,
                    n as i32,
                    &mut w,
                    &mut work,
                    4 * n as i32,
                    &mut info);
        if info == 0 {
            Ok((w, a))
        } else {
            Err(From::from(info))
        }
    }
    fn inv(size: usize, mut a: Vec<Self>) -> Result<Vec<Self>, LapackError> {
        let n = size as i32;
        let lda = n;
        let mut ipiv = vec![0; size];
        let mut info = 0;
        Self::_getrf(n, n, &mut a, lda, &mut ipiv, &mut info);
        if info != 0 {
            return Err(From::from(info));
        }
        let lwork = n;
        let mut work = vec![Self::zero(); size];
        Self::_getri(n, &mut a, lda, &mut ipiv, &mut work, lwork, &mut info);
        if info == 0 {
            Ok(a)
        } else {
            Err(From::from(info))
        }
    }
    fn norm_1(m: usize, n: usize, mut a: Vec<Self>) -> Self {
        let mut work = Vec::<Self>::new();
        Self::_lange(b'o', m as i32, n as i32, &mut a, m as i32, &mut work)
    }
    fn norm_i(m: usize, n: usize, mut a: Vec<Self>) -> Self {
        let mut work = vec![Self::zero(); m];
        Self::_lange(b'i', m as i32, n as i32, &mut a, m as i32, &mut work)
    }
    fn norm_f(m: usize, n: usize, mut a: Vec<Self>) -> Self {
        let mut work = Vec::<Self>::new();
        Self::_lange(b'f', m as i32, n as i32, &mut a, m as i32, &mut work)
    }
    fn svd(n: usize,
           m: usize,
           mut a: Vec<Self>)
           -> Result<(Vec<Self>, Vec<Self>, Vec<Self>), LapackError> {
        let mut info = 0;
        let n = n as i32;
        let m = m as i32;
        let lda = m;
        let ldu = m;
        let ldvt = n;
        let lwmax = 1000; // XXX
        let lwork = -1;
        let mut u = vec![Self::zero(); (ldu * m) as usize];
        let mut vt = vec![Self::zero(); (ldvt * n) as usize];
        let mut s = vec![Self::zero(); n as usize];
        let mut work = vec![Self::zero(); lwmax];
        Self::_gesvd('A' as u8,
                     'A' as u8,
                     m,
                     n,
                     &mut a,
                     lda,
                     &mut s,
                     &mut u,
                     ldu,
                     &mut vt,
                     ldvt,
                     &mut work,
                     lwork,
                     &mut info); // calc optimal work
        let lwork = min(lwmax as i32, work[0].to_int());
        Self::_gesvd('A' as u8,
                     'A' as u8,
                     m,
                     n,
                     &mut a,
                     lda,
                     &mut s,
                     &mut u,
                     ldu,
                     &mut vt,
                     ldvt,
                     &mut work,
                     lwork,
                     &mut info);
        if info == 0 {
            Ok((u, s, vt))
        } else {
            Err(From::from(info))
        }
    }
}

impl LapackScalar for f64 {}
impl LapackScalar for f32 {}
<|endoftext|>


<commit_before>use hyper::server::{Server, Request, Response, Listening};

pub struct Tungsten {
    server: Option<Listening>
}

impl Tungsten {
    pub fn new() -> Tungsten {
        Tungsten { server: None }
    }

    pub fn listen(&mut self, host_port: &str) {
        let server = Server::http(host_port)
            .unwrap()
            .handle(|_req: Request, res: Response| {
                res.send(b"Hello World!").unwrap();
            })
            .unwrap();
        self.server = Some(server);
    }
}
<commit_msg>implement a request handler struct<commit_after>use hyper::server::{Handler, Server, Listening};
use hyper::server::Request as UnwrappedRequest;
use hyper::server::Response as UnwrappedResponse;

struct RequestHandler;

impl Handler for RequestHandler {
    fn handle(&self, _req: UnwrappedRequest, res: UnwrappedResponse) {
        res.send(b"Hello World!").unwrap();
    }
}

pub struct Tungsten {
    server: Option<Listening>
}

impl Tungsten {
    pub fn new() -> Tungsten {
        Tungsten { server: None }
    }

    pub fn listen(&mut self, host_port: &str) {
        let server = Server::http(host_port)
            .unwrap()
            .handle(RequestHandler)
            .unwrap();
        self.server = Some(server);
    }
}
<|endoftext|>