<commit_before>use crate::value::de::{MapDeserializer, MapRefDeserializer, SeqDeserializer, SeqRefDeserializer};
use crate::value::Value;
use crate::Error;
use serde::de::value::{BorrowedStrDeserializer, StrDeserializer};
use serde::de::{
    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, VariantAccess, Visitor,
};
use serde::ser::{Serialize, SerializeMap, Serializer};
use std::cmp::Ordering;
use std::fmt::{self, Debug, Display};
use std::hash::{Hash, Hasher};

/// A representation of YAML's `!Tag` syntax, used for enums.
///
/// Refer to the example code on [`TaggedValue`] for an example of deserializing
/// tagged values.
#[derive(Clone)]
pub struct Tag {
    pub(crate) string: String,
}

/// A `Tag` + `Value` representing a tagged YAML scalar, sequence, or mapping.
///
/// ```
/// use serde_yaml::value::TaggedValue;
/// use std::collections::BTreeMap;
///
/// let yaml = "
///     scalar: !Thing x
///     sequence_flow: !Thing [first]
///     sequence_block: !Thing
///       - first
///     mapping_flow: !Thing {k: v}
///     mapping_block: !Thing
///       k: v
/// ";
///
/// let data: BTreeMap<String, TaggedValue> = serde_yaml::from_str(yaml).unwrap();
/// assert!(data["scalar"].tag == "Thing");
/// assert!(data["sequence_flow"].tag == "Thing");
/// assert!(data["sequence_block"].tag == "Thing");
/// assert!(data["mapping_flow"].tag == "Thing");
/// assert!(data["mapping_block"].tag == "Thing");
///
/// // The leading '!' in tags are not significant. The following is also true.
/// assert!(data["scalar"].tag == "!Thing");
/// ```
#[derive(Clone, PartialEq, PartialOrd, Hash, Debug)]
pub struct TaggedValue {
    #[allow(missing_docs)]
    pub tag: Tag,
    #[allow(missing_docs)]
    pub value: Value,
}

impl Tag {
    /// Create tag.
    ///
    /// The leading '!' is not significant. It may be provided, but does not
    /// have to be. The following are equivalent:
    ///
    /// ```
    /// use serde_yaml::value::Tag;
    ///
    /// assert_eq!(Tag::new("!Thing"), Tag::new("Thing"));
    ///
    /// let tag = Tag::new("Thing");
    /// assert!(tag == "Thing");
    /// assert!(tag == "!Thing");
    /// assert!(tag.to_string() == "!Thing");
    ///
    /// let tag = Tag::new("!Thing");
    /// assert!(tag == "Thing");
    /// assert!(tag == "!Thing");
    /// assert!(tag.to_string() == "!Thing");
    /// ```
    ///
    /// Such a tag would serialize to `!Thing` in YAML regardless of whether a
    /// '!' was included in the call to `Tag::new`.
    pub fn new(string: impl Into<String>) -> Self {
        Tag {
            string: string.into(),
        }
    }
}

impl Value {
    pub(crate) fn untag(self) -> Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = tagged.value;
        }
        cur
    }

    pub(crate) fn untag_ref(&self) -> &Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &tagged.value;
        }
        cur
    }

    pub(crate) fn untag_mut(&mut self) -> &mut Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &mut tagged.value;
        }
        cur
    }
}

pub(crate) fn nobang(maybe_banged: &str) -> &str {
    maybe_banged.strip_prefix('!').unwrap_or(maybe_banged)
}

impl Eq for Tag {}

impl PartialEq for Tag {
    fn eq(&self, other: &Tag) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(&other.string))
    }
}

impl<T> PartialEq<T> for Tag
where
    T: ?Sized + AsRef<str>,
{
    fn eq(&self, other: &T) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(other.as_ref()))
    }
}

impl Ord for Tag {
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl PartialOrd for Tag {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        PartialOrd::partial_cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl Hash for Tag {
    fn hash<H: Hasher>(&self, hasher: &mut H) {
        nobang(&self.string).hash(hasher);
    }
}

impl Display for Tag {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "!{}", nobang(&self.string))
    }
}

impl Debug for Tag {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(self, formatter)
    }
}

impl Serialize for TaggedValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(1))?;
        map.serialize_entry(&format_args!("!{}", nobang(&self.tag.string)), &self.value)?;
        map.end()
    }
}

impl<'de> Deserialize<'de> for TaggedValue {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct TaggedValueVisitor;

        impl<'de> Visitor<'de> for TaggedValueVisitor {
            type Value = TaggedValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a YAML value with a !Tag")
            }

            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (tag, contents) = data.variant::<String>()?;
                let tag = Tag::new(tag);
                let value = contents.newtype_variant()?;
                Ok(TaggedValue { tag, value })
            }
        }

        deserializer.deserialize_any(TaggedValueVisitor)
    }
}

impl<'de> EnumAccess<'de> for TaggedValue {
    type Error = Error;
    type Variant = Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = StrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, self.value))
    }
}

impl<'de> VariantAccess<'de> for Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}

impl<'de> EnumAccess<'de> for &'de TaggedValue {
    type Error = Error;
    type Variant = &'de Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = BorrowedStrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, &self.value))
    }
}

impl<'de> VariantAccess<'de> for &'de Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}
<commit_msg>Serialize using Tag's Display impl<commit_after>use crate::value::de::{MapDeserializer, MapRefDeserializer, SeqDeserializer, SeqRefDeserializer};
use crate::value::Value;
use crate::Error;
use serde::de::value::{BorrowedStrDeserializer, StrDeserializer};
use serde::de::{
    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, VariantAccess, Visitor,
};
use serde::ser::{Serialize, SerializeMap, Serializer};
use std::cmp::Ordering;
use std::fmt::{self, Debug, Display};
use std::hash::{Hash, Hasher};

/// A representation of YAML's `!Tag` syntax, used for enums.
///
/// Refer to the example code on [`TaggedValue`] for an example of deserializing
/// tagged values.
#[derive(Clone)]
pub struct Tag {
    pub(crate) string: String,
}

/// A `Tag` + `Value` representing a tagged YAML scalar, sequence, or mapping.
///
/// ```
/// use serde_yaml::value::TaggedValue;
/// use std::collections::BTreeMap;
///
/// let yaml = "
///     scalar: !Thing x
///     sequence_flow: !Thing [first]
///     sequence_block: !Thing
///       - first
///     mapping_flow: !Thing {k: v}
///     mapping_block: !Thing
///       k: v
/// ";
///
/// let data: BTreeMap<String, TaggedValue> = serde_yaml::from_str(yaml).unwrap();
/// assert!(data["scalar"].tag == "Thing");
/// assert!(data["sequence_flow"].tag == "Thing");
/// assert!(data["sequence_block"].tag == "Thing");
/// assert!(data["mapping_flow"].tag == "Thing");
/// assert!(data["mapping_block"].tag == "Thing");
///
/// // The leading '!' in tags are not significant. The following is also true.
/// assert!(data["scalar"].tag == "!Thing");
/// ```
#[derive(Clone, PartialEq, PartialOrd, Hash, Debug)]
pub struct TaggedValue {
    #[allow(missing_docs)]
    pub tag: Tag,
    #[allow(missing_docs)]
    pub value: Value,
}

impl Tag {
    /// Create tag.
    ///
    /// The leading '!' is not significant. It may be provided, but does not
    /// have to be. The following are equivalent:
    ///
    /// ```
    /// use serde_yaml::value::Tag;
    ///
    /// assert_eq!(Tag::new("!Thing"), Tag::new("Thing"));
    ///
    /// let tag = Tag::new("Thing");
    /// assert!(tag == "Thing");
    /// assert!(tag == "!Thing");
    /// assert!(tag.to_string() == "!Thing");
    ///
    /// let tag = Tag::new("!Thing");
    /// assert!(tag == "Thing");
    /// assert!(tag == "!Thing");
    /// assert!(tag.to_string() == "!Thing");
    /// ```
    ///
    /// Such a tag would serialize to `!Thing` in YAML regardless of whether a
    /// '!' was included in the call to `Tag::new`.
    pub fn new(string: impl Into<String>) -> Self {
        Tag {
            string: string.into(),
        }
    }
}

impl Value {
    pub(crate) fn untag(self) -> Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = tagged.value;
        }
        cur
    }

    pub(crate) fn untag_ref(&self) -> &Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &tagged.value;
        }
        cur
    }

    pub(crate) fn untag_mut(&mut self) -> &mut Self {
        let mut cur = self;
        while let Value::Tagged(tagged) = cur {
            cur = &mut tagged.value;
        }
        cur
    }
}

pub(crate) fn nobang(maybe_banged: &str) -> &str {
    maybe_banged.strip_prefix('!').unwrap_or(maybe_banged)
}

impl Eq for Tag {}

impl PartialEq for Tag {
    fn eq(&self, other: &Tag) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(&other.string))
    }
}

impl<T> PartialEq<T> for Tag
where
    T: ?Sized + AsRef<str>,
{
    fn eq(&self, other: &T) -> bool {
        PartialEq::eq(nobang(&self.string), nobang(other.as_ref()))
    }
}

impl Ord for Tag {
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl PartialOrd for Tag {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        PartialOrd::partial_cmp(nobang(&self.string), nobang(&other.string))
    }
}

impl Hash for Tag {
    fn hash<H: Hasher>(&self, hasher: &mut H) {
        nobang(&self.string).hash(hasher);
    }
}

impl Display for Tag {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "!{}", nobang(&self.string))
    }
}

impl Debug for Tag {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(self, formatter)
    }
}

impl Serialize for TaggedValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        struct SerializeTag<'a>(&'a Tag);

        impl<'a> Serialize for SerializeTag<'a> {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where
                S: Serializer,
            {
                serializer.collect_str(self.0)
            }
        }

        let mut map = serializer.serialize_map(Some(1))?;
        map.serialize_entry(&SerializeTag(&self.tag), &self.value)?;
        map.end()
    }
}

impl<'de> Deserialize<'de> for TaggedValue {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct TaggedValueVisitor;

        impl<'de> Visitor<'de> for TaggedValueVisitor {
            type Value = TaggedValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a YAML value with a !Tag")
            }

            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (tag, contents) = data.variant::<String>()?;
                let tag = Tag::new(tag);
                let value = contents.newtype_variant()?;
                Ok(TaggedValue { tag, value })
            }
        }

        deserializer.deserialize_any(TaggedValueVisitor)
    }
}

impl<'de> EnumAccess<'de> for TaggedValue {
    type Error = Error;
    type Variant = Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = StrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, self.value))
    }
}

impl<'de> VariantAccess<'de> for Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}

impl<'de> EnumAccess<'de> for &'de TaggedValue {
    type Error = Error;
    type Variant = &'de Value;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
    where
        V: DeserializeSeed<'de>,
    {
        let tag = BorrowedStrDeserializer::<Error>::new(nobang(&self.tag.string));
        let value = seed.deserialize(tag)?;
        Ok((value, &self.value))
    }
}

impl<'de> VariantAccess<'de> for &'de Value {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Error> {
        Deserialize::deserialize(self)
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Sequence(v) = self {
            Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
        }
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Error>
    where
        V: Visitor<'de>,
    {
        if let Value::Mapping(v) = self {
            Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
        } else {
            Err(Error::invalid_type(self.unexpected(), &"struct variant"))
        }
    }
}
<|endoftext|>


<commit_before>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
extern crate serialize;
use std::libc::{c_ulonglong, c_int};
use std::slice::{from_elem};

#[link(name = "sodium")]
extern {
    fn crypto_sign_ed25519_keypair(pk: *mut u8,
                                   sk: *mut u8) -> c_int;
    fn crypto_sign_ed25519_seed_keypair(pk: *mut u8,
                                        sk: *mut u8,
                                        seed: *u8) -> c_int;
    fn crypto_sign_ed25519(sm: *mut u8,
                           smlen: *mut c_ulonglong,
                           m: *u8,
                           mlen: c_ulonglong,
                           sk: *u8) -> c_int;
    fn crypto_sign_ed25519_open(m: *mut u8,
                                mlen: *mut c_ulonglong,
                                sm: *u8,
                                smlen: c_ulonglong,
                                pk: *u8) -> c_int;
}

pub static SEEDBYTES: uint = 32;
pub static SECRETKEYBYTES: uint = 64;
pub static PUBLICKEYBYTES: uint = 32;
pub static SIGNATUREBYTES: uint = 64;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed([u8, ..SEEDBYTES]);
impl Drop for Seed {
    fn drop(&mut self) {
        let &Seed(ref mut s) = self;
        for e in s.mut_iter() { *e = 0 }
    }
}

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey([u8, ..SECRETKEYBYTES]);
impl Drop for SecretKey {
    fn drop(&mut self) {
        let &SecretKey(ref mut sk) = self;
        for e in sk.mut_iter() { *e = 0 }
    }
}
/**
 * `PublicKey` for signatures
 */
pub struct PublicKey([u8, ..PUBLICKEYBYTES]);

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> ~[u8] {
    unsafe {
        let mut sm = from_elem(m.len() + SIGNATUREBYTES, 0u8);
        let mut smlen = 0;
        crypto_sign_ed25519(sm.as_mut_ptr(),
                            &mut smlen,
                            m.as_ptr(),
                            m.len() as c_ulonglong,
                            sk.as_ptr());
        sm.truncate(smlen as uint);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<~[u8]> {
    unsafe {
        let mut m = from_elem(sm.len(), 0u8);
        let mut mlen = 0;
        if crypto_sign_ed25519_open(m.as_mut_ptr(),
                                    &mut mlen,
                                    sm.as_ptr(),
                                    sm.len() as c_ulonglong,
                                    pk.as_ptr()) == 0 {
            m.truncate(mlen as uint);
            Some(m)
        } else {
            None
        }
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in range(0, 256) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 256) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 32) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // form the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::buffered::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8, ..SEEDBYTES];
        for (s, b) in seedbuf.mut_iter().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m, &sk);
        verify(sm, &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.to_hex());
        assert!(x3 == sm.to_hex());
    }
}
<commit_msg>BufferedReader is now in std::io<commit_after>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
extern crate serialize;
use std::libc::{c_ulonglong, c_int};
use std::slice::{from_elem};

#[link(name = "sodium")]
extern {
    fn crypto_sign_ed25519_keypair(pk: *mut u8,
                                   sk: *mut u8) -> c_int;
    fn crypto_sign_ed25519_seed_keypair(pk: *mut u8,
                                        sk: *mut u8,
                                        seed: *u8) -> c_int;
    fn crypto_sign_ed25519(sm: *mut u8,
                           smlen: *mut c_ulonglong,
                           m: *u8,
                           mlen: c_ulonglong,
                           sk: *u8) -> c_int;
    fn crypto_sign_ed25519_open(m: *mut u8,
                                mlen: *mut c_ulonglong,
                                sm: *u8,
                                smlen: c_ulonglong,
                                pk: *u8) -> c_int;
}

pub static SEEDBYTES: uint = 32;
pub static SECRETKEYBYTES: uint = 64;
pub static PUBLICKEYBYTES: uint = 32;
pub static SIGNATUREBYTES: uint = 64;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed([u8, ..SEEDBYTES]);
impl Drop for Seed {
    fn drop(&mut self) {
        let &Seed(ref mut s) = self;
        for e in s.mut_iter() { *e = 0 }
    }
}

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey([u8, ..SECRETKEYBYTES]);
impl Drop for SecretKey {
    fn drop(&mut self) {
        let &SecretKey(ref mut sk) = self;
        for e in sk.mut_iter() { *e = 0 }
    }
}
/**
 * `PublicKey` for signatures
 */
pub struct PublicKey([u8, ..PUBLICKEYBYTES]);

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> ~[u8] {
    unsafe {
        let mut sm = from_elem(m.len() + SIGNATUREBYTES, 0u8);
        let mut smlen = 0;
        crypto_sign_ed25519(sm.as_mut_ptr(),
                            &mut smlen,
                            m.as_ptr(),
                            m.len() as c_ulonglong,
                            sk.as_ptr());
        sm.truncate(smlen as uint);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<~[u8]> {
    unsafe {
        let mut m = from_elem(sm.len(), 0u8);
        let mut mlen = 0;
        if crypto_sign_ed25519_open(m.as_mut_ptr(),
                                    &mut mlen,
                                    sm.as_ptr(),
                                    sm.len() as c_ulonglong,
                                    pk.as_ptr()) == 0 {
            m.truncate(mlen as uint);
            Some(m)
        } else {
            None
        }
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in range(0, 256) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 256) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 32) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // form the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8, ..SEEDBYTES];
        for (s, b) in seedbuf.mut_iter().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m, &sk);
        verify(sm, &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.to_hex());
        assert!(x3 == sm.to_hex());
    }
}
<|endoftext|>


<commit_before>use stats::median;
use request_response_matcher;

pub mod percentile;

#[derive(PartialEq, Debug)]
pub struct RequestLogAnalyzerResult {
    pub count: usize,
    pub max: usize,
    pub min: usize,
    pub avg: usize,
    pub median: usize,
    pub percentile90: usize,
}

pub trait Timing {
    fn num_milliseconds(&self) -> i64;
}

pub fn analyze<T>(timings: &Vec<T>) -> Option<RequestLogAnalyzerResult>
    where T: Timing
{

    if timings.len() == 0 {
        return None;
    }

    let times: Vec<i64> = timings.iter()
        .map(|timing| timing.num_milliseconds())
        .collect();

    let sum: usize = times.iter().sum::<i64>() as usize;
    let avg: usize = sum / times.len();

    let max: usize = *times.iter().max().unwrap() as usize;
    let min: usize = *times.iter().min().unwrap() as usize;

    let percentile90: usize = percentile::percentile(&times, 0.9) as usize;

    let median = median(times.iter().cloned()).unwrap() as usize;

    Some(RequestLogAnalyzerResult {
        count: times.len().into(),
        max: max,
        min: min,
        avg: avg,
        median: median,
        percentile90: percentile90,
    })
}

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

    impl Timing for i64 {
        fn num_milliseconds(&self) -> i64 {
            self.clone()
        }
    }

    #[test]
    fn test_analyze() {
        let times: Vec<i64> = vec![1, 10, 100];

        let result = analyze(&times);

        let expected = Some(RequestLogAnalyzerResult {
            count: 3,
            max: 100,
            min: 1,
            avg: 37,
            median: 10,
            percentile90: 100,
        });

        assert_eq!(result, expected);
    }

    #[test]
    fn test_analyze_empty() {
        let times: Vec<i64> = vec![];

        let result = analyze(&times);

        let expected = None;

        assert_eq!(result, expected);
    }
}
<commit_msg>No more direct dependency<commit_after>use stats::median;

pub mod percentile;

#[derive(PartialEq, Debug)]
pub struct RequestLogAnalyzerResult {
    pub count: usize,
    pub max: usize,
    pub min: usize,
    pub avg: usize,
    pub median: usize,
    pub percentile90: usize,
}

pub trait Timing {
    fn num_milliseconds(&self) -> i64;
}

pub fn analyze<T>(timings: &Vec<T>) -> Option<RequestLogAnalyzerResult>
    where T: Timing
{

    if timings.len() == 0 {
        return None;
    }

    let times: Vec<i64> = timings.iter()
        .map(|timing| timing.num_milliseconds())
        .collect();

    let sum: usize = times.iter().sum::<i64>() as usize;
    let avg: usize = sum / times.len();

    let max: usize = *times.iter().max().unwrap() as usize;
    let min: usize = *times.iter().min().unwrap() as usize;

    let percentile90: usize = percentile::percentile(&times, 0.9) as usize;

    let median = median(times.iter().cloned()).unwrap() as usize;

    Some(RequestLogAnalyzerResult {
        count: times.len().into(),
        max: max,
        min: min,
        avg: avg,
        median: median,
        percentile90: percentile90,
    })
}

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

    impl Timing for i64 {
        fn num_milliseconds(&self) -> i64 {
            self.clone()
        }
    }

    #[test]
    fn test_analyze() {
        let times: Vec<i64> = vec![1, 10, 100];

        let result = analyze(&times);

        let expected = Some(RequestLogAnalyzerResult {
            count: 3,
            max: 100,
            min: 1,
            avg: 37,
            median: 10,
            percentile90: 100,
        });

        assert_eq!(result, expected);
    }

    #[test]
    fn test_analyze_empty() {
        let times: Vec<i64> = vec![];

        let result = analyze(&times);

        let expected = None;

        assert_eq!(result, expected);
    }
}
<|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.

//
// Utilities.
//

// returns an infinite iterator of repeated applications of f to x,
// i.e. [x, f(x), f(f(x)), ...], as haskell iterate function.
fn iterate<'a, T>(x: T, f: &'a fn(&T) -> T) -> Iterate<'a, T> {
    Iterate {f: f, next: x}
}
struct Iterate<'self, T> {
    priv f: &'self fn(&T) -> T,
    priv next: T
}
impl<'self, T> Iterator<T> for Iterate<'self, T> {
    fn next(&mut self) -> Option<T> {
        let mut res = (self.f)(&self.next);
        std::util::swap(&mut res, &mut self.next);
        Some(res)
    }
}

// a linked list using borrowed next.
enum List<'self, T> {
    Nil,
    Cons(T, &'self List<'self, T>)
}
struct ListIterator<'self, T> {
    priv cur: &'self List<'self, T>
}
impl<'self, T> List<'self, T> {
    fn iter(&'self self) -> ListIterator<'self, T> {
        ListIterator{cur: self}
    }
}
impl<'self, T> Iterator<&'self T> for ListIterator<'self, T> {
    fn next(&mut self) -> Option<&'self T> {
        match *self.cur {
            Nil => None,
            Cons(ref elt, next) => {
                self.cur = next;
                Some(elt)
            }
        }
    }
}

//
// preprocess
//

// Takes a pieces p on the form [(y1, x1), (y2, x2), ...] and returns
// every possible transformations (the 6 rotations with their
// corresponding mirrored piece), with, as minimum coordinates, (0,
// 0).  If all is false, only generate half of the possibilities (used
// to break the symetry of the board).
fn transform(p: ~[(int, int)], all: bool) -> ~[~[(int, int)]] {
    let mut res =
        // rotations
        iterate(p, |p| p.iter().map(|&(y, x)| (x + y, -y)).collect())
        .take(if all {6} else {3})
        // mirror
        .flat_map(|p| {
            iterate(p, |p| p.iter().map(|&(y, x)| (x, y)).collect()).take(2)
        }).to_owned_vec();

    // translating to (0, 0) as minimum coordinates.
    for p in res.mut_iter() {
        let (dy, dx) = *p.iter().min_by(|e| *e).unwrap();
        for &(ref mut y, ref mut x) in p.mut_iter() {
            *y -= dy; *x -= dx;
        }
    }

    res
}

// A mask is a piece somewere on the board.  It is represented as a
// u64: for i in the first 50 bits, m[i] = 1 if the cell at (i/5, i%5)
// is occuped.  m[50 + id] = 1 if the identifier of the piece is id.

// Takes a piece with minimum coordinate (0, 0) (as generated by
// transform).  Returns the corresponding mask if p translated by (dy,
// dx) is on the board.
fn mask(dy: int, dx: int, id: uint, p: &[(int, int)]) -> Option<u64> {
    let mut m = 1 << (50 + id);
    for &(y, x) in p.iter() {
        let x = x + dx + (y + (dy % 2)) / 2;
        if x < 0 || x > 4 {return None;}
        let y = y + dy;
        if y < 0 || y > 9 {return None;}
        m |= 1 << (y * 5 + x);
    }
    Some(m)
}

// Makes every possible masks.  masks[id][i] correspond to every
// possible masks for piece with identifier id with minimum coordinate
// (i/5, i%5).
fn make_masks() -> ~[~[~[u64]]] {
    let pieces = ~[
        ~[(0,0),(0,1),(0,2),(0,3),(1,3)],
        ~[(0,0),(0,2),(0,3),(1,0),(1,1)],
        ~[(0,0),(0,1),(0,2),(1,2),(2,1)],
        ~[(0,0),(0,1),(0,2),(1,1),(2,1)],
        ~[(0,0),(0,2),(1,0),(1,1),(2,1)],
        ~[(0,0),(0,1),(0,2),(1,1),(1,2)],
        ~[(0,0),(0,1),(1,1),(1,2),(2,1)],
        ~[(0,0),(0,1),(0,2),(1,0),(1,2)],
        ~[(0,0),(0,1),(0,2),(1,2),(1,3)],
        ~[(0,0),(0,1),(0,2),(0,3),(1,2)]];
    let mut res = ~[];
    for (id, p) in pieces.move_iter().enumerate() {
        // To break the central symetry of the problem, every
        // transformation must be taken except for one piece (piece 3
        // here).
        let trans = transform(p, id != 3);
        let mut cur_piece = ~[];
        for dy in range(0, 10) {
            for dx in range(0, 5) {
                let masks =
                    trans.iter()
                    .filter_map(|t| mask(dy, dx, id, *t))
                    .collect();
                cur_piece.push(masks);
            }
        }
        res.push(cur_piece);
    }
    res
}

// Check if all coordinates can be covered by an unused piece and that
// all unused piece can be placed on the board.
fn is_board_unfeasible(board: u64, masks: &[~[~[u64]]]) -> bool {
    let mut coverable = board;
    for i in range(0, 50).filter(|&i| board & 1 << i == 0) {
        for (cur_id, pos_masks) in masks.iter().enumerate() {
            if board & 1 << (50 + cur_id) != 0 {continue;}
            for &cur_m in pos_masks[i].iter() {
                if cur_m & board == 0 {coverable |= cur_m;}
            }
        }
        if coverable & (1 << i) == 0 {return true;}
    }
    // check if every coordinates can be covered and every piece can
    // be used.
    coverable != (1 << 60) - 1
}

// Filter the masks that we can prove to result to unfeasible board.
fn filter_masks(masks: &[~[~[u64]]]) -> ~[~[~[u64]]] {
    masks.iter().map(
        |p| p.iter().map(
            |p| p.iter()
                .map(|&m| m)
                .filter(|&m| !is_board_unfeasible(m, masks))
                .collect())
            .collect())
        .collect()
}

// Gets the identifier of a mask.
fn get_id(m: u64) -> u8 {
    for id in range(0, 10) {
        if m & (1 << (id + 50)) != 0 {return id as u8;}
    }
    fail!("{:016x} does not have a valid identifier", m);
}

// Converts a list of mask to a ~str.
fn to_utf8(raw_sol: &List<u64>) -> ~str {
    let mut sol: ~[u8] = std::vec::from_elem(50, '.' as u8);
    for &m in raw_sol.iter() {
        let id = get_id(m);
        for i in range(0, 50) {
            if m & 1 << i != 0 {sol[i] = '0' as u8 + id;}
        }
    }
    std::str::from_utf8_owned(sol)
}

// Prints a solution in ~str form.
fn print_sol(sol: &str) {
    for (i, c) in sol.iter().enumerate() {
        if (i) % 5 == 0 {println("");}
        if (i + 5) % 10 == 0 {print(" ");}
        print!("{} ", c);
    }
    println("");
}

// The data managed during the search
struct Data {
    // If more than stop_after is found, stop the search.
    stop_after: int,
    // Number of solution found.
    nb: int,
    // Lexicographically minimal solution found.
    min: ~str,
    // Lexicographically maximal solution found.
    max: ~str
}

// Records a new found solution.  Returns false if the search must be
// stopped.
fn handle_sol(raw_sol: &List<u64>, data: &mut Data) -> bool {
    // because we break the symetry, 2 solutions correspond to a call
    // to this method: the normal solution, and the same solution in
    // reverse order, i.e. the board rotated by half a turn.
    data.nb += 2;
    let sol1 = to_utf8(raw_sol);
    let sol2: ~str = sol1.iter().invert().collect();

    if data.nb == 2 {
        data.min = sol1.clone();
        data.max = sol1.clone();
    }

    if sol1 < data.min {data.min = sol1.clone();}
    if sol2 < data.min {data.min = sol2.clone();}
    if sol1 > data.max {data.max = sol1;}
    if sol2 > data.max {data.max = sol2;}
    data.nb < data.stop_after
}

// Search for every solutions.  Returns false if the search was
// stopped before the end.
fn search(
    masks: &[~[~[u64]]],
    board: u64,
    mut i: int,
    cur: List<u64>,
    data: &mut Data)
    -> bool
{
    // Search for the lesser empty coordinate.
    while board & (1 << i)  != 0 && i < 50 {i += 1;}
    // the board is full: a solution is found.
    if i >= 50 {return handle_sol(&cur, data);}

    // for every unused piece
    for id in range(0, 10).filter(|id| board & (1 << (id + 50)) == 0) {
        // for each mask that fits on the board
        for &m in masks[id][i].iter().filter(|&m| board & *m == 0) {
            // This check is too costy.
            //if is_board_unfeasible(board | m, masks) {continue;}
            if !search(masks, board | m, i + 1, Cons(m, &cur), data) {
                return false;
            }
        }
    }
    return true;
}

fn main () {
    let args = std::os::args();
    let stop_after = if args.len() <= 1 {
        2098
    } else {
        from_str(args[1]).unwrap()
    };
    let masks = make_masks();
    let masks = filter_masks(masks);
    let mut data = Data {stop_after: stop_after, nb: 0, min: ~"", max: ~""};
    search(masks, 0, 0, Nil, &mut data);
    println!("{} solutions found", data.nb);
    print_sol(data.min);
    print_sol(data.max);
    println("");
}
<commit_msg>Improve variable naming.<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.

//
// Utilities.
//

// returns an infinite iterator of repeated applications of f to x,
// i.e. [x, f(x), f(f(x)), ...], as haskell iterate function.
fn iterate<'a, T>(x: T, f: &'a fn(&T) -> T) -> Iterate<'a, T> {
    Iterate {f: f, next: x}
}
struct Iterate<'self, T> {
    priv f: &'self fn(&T) -> T,
    priv next: T
}
impl<'self, T> Iterator<T> for Iterate<'self, T> {
    fn next(&mut self) -> Option<T> {
        let mut res = (self.f)(&self.next);
        std::util::swap(&mut res, &mut self.next);
        Some(res)
    }
}

// a linked list using borrowed next.
enum List<'self, T> {
    Nil,
    Cons(T, &'self List<'self, T>)
}
struct ListIterator<'self, T> {
    priv cur: &'self List<'self, T>
}
impl<'self, T> List<'self, T> {
    fn iter(&'self self) -> ListIterator<'self, T> {
        ListIterator{cur: self}
    }
}
impl<'self, T> Iterator<&'self T> for ListIterator<'self, T> {
    fn next(&mut self) -> Option<&'self T> {
        match *self.cur {
            Nil => None,
            Cons(ref elt, next) => {
                self.cur = next;
                Some(elt)
            }
        }
    }
}

//
// preprocess
//

// Takes a pieces p on the form [(y1, x1), (y2, x2), ...] and returns
// every possible transformations (the 6 rotations with their
// corresponding mirrored piece), with, as minimum coordinates, (0,
// 0).  If all is false, only generate half of the possibilities (used
// to break the symetry of the board).
fn transform(piece: ~[(int, int)], all: bool) -> ~[~[(int, int)]] {
    let mut res =
        // rotations
        iterate(piece, |rot| rot.iter().map(|&(y, x)| (x + y, -y)).collect())
        .take(if all {6} else {3})
        // mirror
        .flat_map(|cur_piece| {
            iterate(cur_piece, |mir| mir.iter().map(|&(y, x)| (x, y)).collect())
            .take(2)
        }).to_owned_vec();

    // translating to (0, 0) as minimum coordinates.
    for cur_piece in res.mut_iter() {
        let (dy, dx) = *cur_piece.iter().min_by(|e| *e).unwrap();
        for &(ref mut y, ref mut x) in cur_piece.mut_iter() {
            *y -= dy; *x -= dx;
        }
    }

    res
}

// A mask is a piece somewere on the board.  It is represented as a
// u64: for i in the first 50 bits, m[i] = 1 if the cell at (i/5, i%5)
// is occuped.  m[50 + id] = 1 if the identifier of the piece is id.

// Takes a piece with minimum coordinate (0, 0) (as generated by
// transform).  Returns the corresponding mask if p translated by (dy,
// dx) is on the board.
fn mask(dy: int, dx: int, id: uint, p: &[(int, int)]) -> Option<u64> {
    let mut m = 1 << (50 + id);
    for &(y, x) in p.iter() {
        let x = x + dx + (y + (dy % 2)) / 2;
        if x < 0 || x > 4 {return None;}
        let y = y + dy;
        if y < 0 || y > 9 {return None;}
        m |= 1 << (y * 5 + x);
    }
    Some(m)
}

// Makes every possible masks.  masks[id][i] correspond to every
// possible masks for piece with identifier id with minimum coordinate
// (i/5, i%5).
fn make_masks() -> ~[~[~[u64]]] {
    let pieces = ~[
        ~[(0,0),(0,1),(0,2),(0,3),(1,3)],
        ~[(0,0),(0,2),(0,3),(1,0),(1,1)],
        ~[(0,0),(0,1),(0,2),(1,2),(2,1)],
        ~[(0,0),(0,1),(0,2),(1,1),(2,1)],
        ~[(0,0),(0,2),(1,0),(1,1),(2,1)],
        ~[(0,0),(0,1),(0,2),(1,1),(1,2)],
        ~[(0,0),(0,1),(1,1),(1,2),(2,1)],
        ~[(0,0),(0,1),(0,2),(1,0),(1,2)],
        ~[(0,0),(0,1),(0,2),(1,2),(1,3)],
        ~[(0,0),(0,1),(0,2),(0,3),(1,2)]];
    let mut res = ~[];
    for (id, p) in pieces.move_iter().enumerate() {
        // To break the central symetry of the problem, every
        // transformation must be taken except for one piece (piece 3
        // here).
        let trans = transform(p, id != 3);
        let mut cur_piece = ~[];
        for dy in range(0, 10) {
            for dx in range(0, 5) {
                let masks =
                    trans.iter()
                    .filter_map(|t| mask(dy, dx, id, *t))
                    .collect();
                cur_piece.push(masks);
            }
        }
        res.push(cur_piece);
    }
    res
}

// Check if all coordinates can be covered by an unused piece and that
// all unused piece can be placed on the board.
fn is_board_unfeasible(board: u64, masks: &[~[~[u64]]]) -> bool {
    let mut coverable = board;
    for i in range(0, 50).filter(|&i| board & 1 << i == 0) {
        for (cur_id, pos_masks) in masks.iter().enumerate() {
            if board & 1 << (50 + cur_id) != 0 {continue;}
            for &cur_m in pos_masks[i].iter() {
                if cur_m & board == 0 {coverable |= cur_m;}
            }
        }
        if coverable & (1 << i) == 0 {return true;}
    }
    // check if every coordinates can be covered and every piece can
    // be used.
    coverable != (1 << 60) - 1
}

// Filter the masks that we can prove to result to unfeasible board.
fn filter_masks(masks: &[~[~[u64]]]) -> ~[~[~[u64]]] {
    masks.iter().map(
        |p| p.iter().map(
            |p| p.iter()
                .map(|&m| m)
                .filter(|&m| !is_board_unfeasible(m, masks))
                .collect())
            .collect())
        .collect()
}

// Gets the identifier of a mask.
fn get_id(m: u64) -> u8 {
    for id in range(0, 10) {
        if m & (1 << (id + 50)) != 0 {return id as u8;}
    }
    fail!("{:016x} does not have a valid identifier", m);
}

// Converts a list of mask to a ~str.
fn to_utf8(raw_sol: &List<u64>) -> ~str {
    let mut sol: ~[u8] = std::vec::from_elem(50, '.' as u8);
    for &m in raw_sol.iter() {
        let id = get_id(m);
        for i in range(0, 50) {
            if m & 1 << i != 0 {sol[i] = '0' as u8 + id;}
        }
    }
    std::str::from_utf8_owned(sol)
}

// Prints a solution in ~str form.
fn print_sol(sol: &str) {
    for (i, c) in sol.iter().enumerate() {
        if (i) % 5 == 0 {println("");}
        if (i + 5) % 10 == 0 {print(" ");}
        print!("{} ", c);
    }
    println("");
}

// The data managed during the search
struct Data {
    // If more than stop_after is found, stop the search.
    stop_after: int,
    // Number of solution found.
    nb: int,
    // Lexicographically minimal solution found.
    min: ~str,
    // Lexicographically maximal solution found.
    max: ~str
}

// Records a new found solution.  Returns false if the search must be
// stopped.
fn handle_sol(raw_sol: &List<u64>, data: &mut Data) -> bool {
    // because we break the symetry, 2 solutions correspond to a call
    // to this method: the normal solution, and the same solution in
    // reverse order, i.e. the board rotated by half a turn.
    data.nb += 2;
    let sol1 = to_utf8(raw_sol);
    let sol2: ~str = sol1.iter().invert().collect();

    if data.nb == 2 {
        data.min = sol1.clone();
        data.max = sol1.clone();
    }

    if sol1 < data.min {data.min = sol1.clone();}
    if sol2 < data.min {data.min = sol2.clone();}
    if sol1 > data.max {data.max = sol1;}
    if sol2 > data.max {data.max = sol2;}
    data.nb < data.stop_after
}

// Search for every solutions.  Returns false if the search was
// stopped before the end.
fn search(
    masks: &[~[~[u64]]],
    board: u64,
    mut i: int,
    cur: List<u64>,
    data: &mut Data)
    -> bool
{
    // Search for the lesser empty coordinate.
    while board & (1 << i)  != 0 && i < 50 {i += 1;}
    // the board is full: a solution is found.
    if i >= 50 {return handle_sol(&cur, data);}

    // for every unused piece
    for id in range(0, 10).filter(|id| board & (1 << (id + 50)) == 0) {
        // for each mask that fits on the board
        for &m in masks[id][i].iter().filter(|&m| board & *m == 0) {
            // This check is too costy.
            //if is_board_unfeasible(board | m, masks) {continue;}
            if !search(masks, board | m, i + 1, Cons(m, &cur), data) {
                return false;
            }
        }
    }
    return true;
}

fn main () {
    let args = std::os::args();
    let stop_after = if args.len() <= 1 {
        2098
    } else {
        from_str(args[1]).unwrap()
    };
    let masks = make_masks();
    let masks = filter_masks(masks);
    let mut data = Data {stop_after: stop_after, nb: 0, min: ~"", max: ~""};
    search(masks, 0, 0, Nil, &mut data);
    println!("{} solutions found", data.nb);
    print_sol(data.min);
    print_sol(data.max);
    println("");
}
<|endoftext|>


<commit_before>use crate::{KHZ_TO_HZ, MHZ_TO_HZ};

/// Write a string to the output channel.
pub unsafe fn puts(s: &str) {}

pub unsafe fn putc(c: char) {}

/// Write a single byte to the output channel.
unsafe fn putb(port: u16, b: u8) {}

pub fn set_output(port: u16) {}

pub fn get_timestamp() -> u64 {
    0
}

pub fn has_tsc() -> bool {
    false
}

pub fn has_invariant_tsc() -> bool {
    false
}

pub fn get_tsc_frequency_hz() -> Option<u64> {
    None
}

pub fn get_vmm_tsc_frequency_hz() -> Option<u64> {
    None
}
<commit_msg>aarch64: remove the unneeded hz conversions<commit_after>/// Write a string to the output channel.
pub unsafe fn puts(s: &str) {}

pub unsafe fn putc(c: char) {}

/// Write a single byte to the output channel.
unsafe fn putb(port: u16, b: u8) {}

pub fn set_output(port: u16) {}

pub fn get_timestamp() -> u64 {
    0
}

pub fn has_tsc() -> bool {
    false
}

pub fn has_invariant_tsc() -> bool {
    false
}

pub fn get_tsc_frequency_hz() -> Option<u64> {
    None
}

pub fn get_vmm_tsc_frequency_hz() -> Option<u64> {
    None
}
<|endoftext|>


<commit_before>use libc::{c_int, c_char, c_long, time_t, size_t};
use data_structs::{JTM};
use jalali_bindings::*;
use std::ffi::CString;
use std::{mem, ptr};

pub struct JTMBuilder {
  pub tm_sec: i32,
  pub tm_min: i32,
  pub tm_hour: i32,
  pub tm_mday: i32,
  pub tm_mon: i32,
  pub tm_year: i32,
  pub tm_wday: i32,
  pub tm_yday: i32,
  pub tm_isdst: i32,
  pub tm_gmtoff: i64,
  pub tm_zone: String,
}

impl JTMBuilder {
  pub fn new() -> Self {
    JTMBuilder {
      tm_sec: 0,
      tm_min: 0,
      tm_hour: 0,
      tm_mday: 0,
      tm_mon: 0,
      tm_year: 0,
      tm_wday: 0,
      tm_yday: 0,
      tm_isdst: 0,
      tm_gmtoff: 0,
      tm_zone: "".to_string(),
    }
  }

  pub fn set_sec(&mut self, sec: i32) -> &mut Self {
    self.tm_sec = sec;
    self
  }

  pub fn set_min(&mut self, min: i32) -> &mut Self {
    self.tm_min = min;
    self
  }

  pub fn set_hour(&mut self, hour: i32) -> &mut Self {
    self.tm_hour = hour;
    self
  }

  pub fn set_mday(&mut self, mday: i32) -> &mut Self {
    self.tm_mday = mday;
    self
  }

  pub fn set_mon(&mut self, mon: i32) -> &mut Self {
    self.tm_mon = mon;
    self
  }

  pub fn set_year(&mut self, year: i32) -> &mut Self {
    self.tm_year = year;
    self
  }

  pub fn set_wday(&mut self, wday: i32) -> &mut Self {
    self.tm_wday = wday;
    self
  }

  pub fn set_yday(&mut self, yday: i32) -> &mut Self {
    self.tm_yday = yday;
    self
  }

  pub fn set_isdst(&mut self, isdst: i32) -> &mut Self {
    self.tm_isdst = isdst;
    self
  }

  pub fn set_gmtoff(&mut self, gmtoff: i64) -> &mut Self {
    self.tm_gmtoff = gmtoff;
    self
  }

  pub fn set_zone(&mut self, zone: String) -> &mut Self {
    self.tm_zone = zone;
    self
  }

  pub fn build(&self) -> JTM {
    JTM {
      tm_sec: self.tm_sec,
      tm_min: self.tm_min,
      tm_hour: self.tm_hour,
      tm_mday: self.tm_mday,
      tm_mon: self.tm_mon,
      tm_year: self.tm_year,
      tm_wday: self.tm_wday,
      tm_yday: self.tm_yday,
      tm_isdst: self.tm_isdst,
      tm_gmtoff: self.tm_gmtoff,
      tm_zone: CString::new(self.tm_zone.clone().into_bytes()).
                                                 unwrap().
                                                 into_raw(),
    }
  }
}

impl JTM {
  pub fn from_secs(secs: i64) -> Self {
    let mut result: Self;
    unsafe {
      result = mem::uninitialized();
      jlocaltime_r(&secs as *const time_t, &mut result);
    }
    result
  }

  pub fn from_days(days: i32) -> Self {
    let mut result: Self;
    unsafe {
      result = mem::uninitialized();
      jalali_get_date(days as c_int, &mut result);
    }
    result
  }

  pub fn from_secs_to_utc(secs: i64) -> Self {
    let mut result: Self;
    unsafe {
      result = mem::uninitialized();
      jgmtime_r(&secs as *const time_t, &mut result);
    }
    result
  }

  pub fn from_formatted_string(s: &String, format: &String) -> Result<Self,()> {
    let mut result: Self;
    let tmp;
    unsafe {
      result = mem::uninitialized();
      tmp = jstrptime(s.as_ptr() as *const i8,
                      format.as_ptr() as *const i8,
                      &mut result);
    }
    result.update();
    if tmp.is_null() {
      Err(())
    } else {
      Ok(result)
    }
  }

  pub fn create_date_from_days(&mut self) -> Result<(),()> {
    let tmp = unsafe {
      jalali_create_date_from_days(self)
    };
    match tmp {
      -1 => Err(()),
      _ => Ok(()),
    }
  }

  pub fn create_days_from_date(&mut self) -> Result<(),()> {
    let tmp = unsafe {
      jalali_create_days_from_date(self)
    };
    match tmp {
      -1 => Err(()),
      _ => Ok(()),
    }
  }

  pub fn get_diff(&self) -> i32 {
    unsafe {
      jalali_get_diff(self)
    }
  }

  pub fn update(&mut self) {
    unsafe {
      jalali_update(self);
    }
  }

  pub fn show_time(&self) {
    unsafe {
      jalali_show_time(self);
    }
  }

  pub fn to_string(&self) -> String {
    let mut buff = Vec::<u8>::with_capacity(100);
    let mut result: String;
    unsafe {
      jasctime_r(self, buff.as_mut_ptr() as *mut i8);
      result = CString::from_raw(buff.as_mut_ptr() as *mut i8).into_string().unwrap();
    }
    mem::forget(buff);
    return result;
  }

  pub fn to_secs(&mut self) -> i64 {
    unsafe {
      jmktime(self)
    }
  }

  pub fn make_formated_string(&self, format: &String, buff: &mut String) -> usize {
    let mut b = String::with_capacity(buff.capacity()).into_bytes();
    let retval: usize;
    unsafe {
      let f = format.as_ptr() as *const i8;
      let max = b.capacity() as size_t;
      retval = jstrftime(b.as_mut_ptr() as *mut i8, max, f, self);
      let tmp = CString::from_raw(b.as_mut_ptr() as *mut i8).into_string().unwrap();
      ptr::copy_nonoverlapping(&tmp, buff, 1);
      mem::forget(tmp);
    }
    mem::forget(b);
    return retval;
  }
}
<commit_msg>define get_timezone method<commit_after>use libc::{c_int, c_char, c_long, time_t, size_t};
use data_structs::{JTM};
use jalali_bindings::*;
use std::ffi::CString;
use std::{mem, ptr};

pub struct JTMBuilder {
  pub tm_sec: i32,
  pub tm_min: i32,
  pub tm_hour: i32,
  pub tm_mday: i32,
  pub tm_mon: i32,
  pub tm_year: i32,
  pub tm_wday: i32,
  pub tm_yday: i32,
  pub tm_isdst: i32,
  pub tm_gmtoff: i64,
  pub tm_zone: String,
}

impl JTMBuilder {
  pub fn new() -> Self {
    JTMBuilder {
      tm_sec: 0,
      tm_min: 0,
      tm_hour: 0,
      tm_mday: 0,
      tm_mon: 0,
      tm_year: 0,
      tm_wday: 0,
      tm_yday: 0,
      tm_isdst: 0,
      tm_gmtoff: 0,
      tm_zone: "".to_string(),
    }
  }

  pub fn set_sec(&mut self, sec: i32) -> &mut Self {
    self.tm_sec = sec;
    self
  }

  pub fn set_min(&mut self, min: i32) -> &mut Self {
    self.tm_min = min;
    self
  }

  pub fn set_hour(&mut self, hour: i32) -> &mut Self {
    self.tm_hour = hour;
    self
  }

  pub fn set_mday(&mut self, mday: i32) -> &mut Self {
    self.tm_mday = mday;
    self
  }

  pub fn set_mon(&mut self, mon: i32) -> &mut Self {
    self.tm_mon = mon;
    self
  }

  pub fn set_year(&mut self, year: i32) -> &mut Self {
    self.tm_year = year;
    self
  }

  pub fn set_wday(&mut self, wday: i32) -> &mut Self {
    self.tm_wday = wday;
    self
  }

  pub fn set_yday(&mut self, yday: i32) -> &mut Self {
    self.tm_yday = yday;
    self
  }

  pub fn set_isdst(&mut self, isdst: i32) -> &mut Self {
    self.tm_isdst = isdst;
    self
  }

  pub fn set_gmtoff(&mut self, gmtoff: i64) -> &mut Self {
    self.tm_gmtoff = gmtoff;
    self
  }

  pub fn set_zone(&mut self, zone: String) -> &mut Self {
    self.tm_zone = zone;
    self
  }

  pub fn build(&self) -> JTM {
    JTM {
      tm_sec: self.tm_sec,
      tm_min: self.tm_min,
      tm_hour: self.tm_hour,
      tm_mday: self.tm_mday,
      tm_mon: self.tm_mon,
      tm_year: self.tm_year,
      tm_wday: self.tm_wday,
      tm_yday: self.tm_yday,
      tm_isdst: self.tm_isdst,
      tm_gmtoff: self.tm_gmtoff,
      tm_zone: CString::new(self.tm_zone.clone().into_bytes()).
                                                 unwrap().
                                                 into_raw(),
    }
  }
}

impl JTM {
  pub fn from_secs(secs: i64) -> Self {
    let mut result: Self;
    unsafe {
      result = mem::uninitialized();
      jlocaltime_r(&secs as *const time_t, &mut result);
    }
    result
  }

  pub fn from_days(days: i32) -> Self {
    let mut result: Self;
    unsafe {
      result = mem::uninitialized();
      jalali_get_date(days as c_int, &mut result);
    }
    result
  }

  pub fn from_secs_to_utc(secs: i64) -> Self {
    let mut result: Self;
    unsafe {
      result = mem::uninitialized();
      jgmtime_r(&secs as *const time_t, &mut result);
    }
    result
  }

  pub fn from_formatted_string(s: &String, format: &String) -> Result<Self,()> {
    let mut result: Self;
    let tmp;
    unsafe {
      result = mem::uninitialized();
      tmp = jstrptime(s.as_ptr() as *const i8,
                      format.as_ptr() as *const i8,
                      &mut result);
    }
    result.update();
    if tmp.is_null() {
      Err(())
    } else {
      Ok(result)
    }
  }

  pub fn get_timezone(&self) -> String {
    let mut tst = String::with_capacity(5);
    self.make_formated_string(&"%Z".to_string(), &mut tst);
    tst
  }

  pub fn create_date_from_days(&mut self) -> Result<(),()> {
    let tmp = unsafe {
      jalali_create_date_from_days(self)
    };
    match tmp {
      -1 => Err(()),
      _ => Ok(()),
    }
  }

  pub fn create_days_from_date(&mut self) -> Result<(),()> {
    let tmp = unsafe {
      jalali_create_days_from_date(self)
    };
    match tmp {
      -1 => Err(()),
      _ => Ok(()),
    }
  }

  pub fn get_diff(&self) -> i32 {
    unsafe {
      jalali_get_diff(self)
    }
  }

  pub fn update(&mut self) {
    unsafe {
      jalali_update(self);
    }
  }

  pub fn show_time(&self) {
    unsafe {
      jalali_show_time(self);
    }
  }

  pub fn to_string(&self) -> String {
    let mut buff = Vec::<u8>::with_capacity(100);
    let mut result: String;
    unsafe {
      jasctime_r(self, buff.as_mut_ptr() as *mut i8);
      result = CString::from_raw(buff.as_mut_ptr() as *mut i8).into_string().unwrap();
    }
    mem::forget(buff);
    return result;
  }

  pub fn to_secs(&mut self) -> i64 {
    unsafe {
      jmktime(self)
    }
  }

  pub fn make_formated_string(&self, format: &String, buff: &mut String) -> usize {
    let mut b = String::with_capacity(buff.capacity()).into_bytes();
    let retval: usize;
    unsafe {
      let f = format.as_ptr() as *const i8;
      let max = b.capacity() as size_t;
      retval = jstrftime(b.as_mut_ptr() as *mut i8, max, f, self);
      let tmp = CString::from_raw(b.as_mut_ptr() as *mut i8).into_string().unwrap();
      ptr::copy_nonoverlapping(&tmp, buff, 1);
      mem::forget(tmp);
    }
    mem::forget(b);
    return retval;
  }
}
<|endoftext|>


<commit_before>use automata::{M};

type RelationMatrixRow = Vec<bool>;
type RelationMatrix = Vec<RelationMatrixRow>;

fn get_relation_matrix(m: &M) -> RelationMatrix {
    let mut matrix: RelationMatrix = Vec::new();

    for qi in m.k.iter() {
        let mut row: RelationMatrixRow = Vec::new();
        for qj in m.k.iter() {
            let mut i_relation_j = false;

            for a in m.alphabet.iter() {
                if m.get_next_states(qi, &a).contains(qj) {
                    i_relation_j = true
                }
            }

            row.push(i_relation_j);
        }
        matrix.push(row);
    }

    matrix
}

    //# Calculate Warshal on the relation matrix
    //for k in n:
        //for i in n:
            //for j in n:
                //T[i][j] = T[i][j] or ( T[i][k] and T[k][j] )

#[cfg(test)]
mod tests {

    #[test]
    fn get_relation_matrix_test() {
        use super::get_relation_matrix;
        use automata::M;

        let k = stateset!("q0", "q1", "q2");
        let alphabet = alphabet!('a', 'b');
        let q0 = "q0".to_string();
        let f = stateset!("q1");
        let delta = delta!(
            ("q0", 'a', "q1"),
            ("q0", 'b', "q0"),
            ("q1", 'a', "q0"),
            ("q1", 'b', "q1"),
            ("q2", 'a', "q2")
        );

        let m = M::new(k, alphabet, q0, f, delta);

        let rm = get_relation_matrix(&m);
        //for i in rm {
            //println!("{:?}", i);
        //}

        let rm_expected = vec![
            [true, true, false],
            [true, true, false],
            [false, false, true]
        ];

        assert!(rm == rm_expected);
    }

}
<commit_msg>fn warshall<commit_after>use automata::{M};

pub type RelationMatrixRow = Vec<bool>;
pub type RelationMatrix = Vec<RelationMatrixRow>;

pub fn get_relation_matrix(m: &M) -> RelationMatrix {
    let mut matrix: RelationMatrix = Vec::new();

    for qi in m.k.iter() {
        let mut row: RelationMatrixRow = Vec::new();
        for qj in m.k.iter() {
            let mut i_relation_j = false;

            for a in m.alphabet.iter() {
                if m.get_next_states(qi, &a).contains(qj) {
                    i_relation_j = true
                }
            }

            row.push(i_relation_j);
        }
        matrix.push(row);
    }

    matrix
}

pub fn warshall(matrix: &RelationMatrix) -> RelationMatrix {
    let n = matrix.len();
    let mut r = matrix.clone();

    for k in 0..n {
        for i in 0..n {
            for j in 0..n {
                r[i][j] = r[i][j] || ( r[i][k] && r[k][j] )
            }
        }
    }

    r
}

#[cfg(test)]
mod tests {
    #[test]
    fn get_relation_matrix_test() {
        use super::get_relation_matrix;
        use automata::M;

        let k = stateset!("q0", "q1", "q2");
        let alphabet = alphabet!('a', 'b');
        let q0 = "q0".to_string();
        let f = stateset!("q1");
        let delta = delta!(
            ("q0", 'a', "q1"),
            ("q0", 'b', "q0"),
            ("q1", 'a', "q0"),
            ("q1", 'b', "q1"),
            ("q2", 'a', "q2")
        );

        let m = M::new(k, alphabet, q0, f, delta);

        let rm = get_relation_matrix(&m);
        //for i in rm {
            //println!("{:?}", i);
        //}

        let rm_expected = vec![
            [true, true, false],
            [true, true, false],
            [false, false, true]
        ];

        assert!(rm == rm_expected);
    }

    #[test]
    fn warshall_test() {
        use super::warshall;

        let rm = vec![
            vec![true, true, false, false],
            vec![false, true, true, false],
            vec![true, false, true, false],
            vec![false, false, false, true]
        ];

        let r = warshall(&rm);
        for i in r {
            println!("{:?}", i);
        }

    }
}
<|endoftext|>


<commit_before>//! TODO Fill in

use super::class::{Class, ClassBuilder};
use super::object::{self, Object, Objectable};
use cairo_sys::cairo_pattern_t;
use rlua::{self, LightUserData, Lua, Table, ToLua, UserData, UserDataMethods, Value};
use std::default::Default;
use std::fmt::{self, Display, Formatter};

/// Handle to the list of global key bindings
pub const ROOT_KEYS_HANDLE: &'static str = "__ROOT_KEYS";

#[derive(Clone, Debug)]
pub struct RootState {
    // TODO Fill in
    dummy: i32
}

pub struct Root<'lua>(Object<'lua>);

impl Default for RootState {
    fn default() -> Self {
        RootState { dummy: 0 }
    }
}

impl Display for RootState {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Root: {:p}", self)
    }
}

impl<'lua> ToLua<'lua> for Root<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.0.to_lua(lua)
    }
}

impl UserData for RootState {
    fn add_methods(methods: &mut UserDataMethods<Self>) {
        object::default_add_methods(methods);
    }
}

pub fn init(lua: &Lua) -> rlua::Result<Class> {
    // FIXME: In awesome there is no root class
    method_setup(lua, Class::builder(lua, "FIXME", None)?)?.save_class("root")?
                                                           .build()
}

fn method_setup<'lua>(lua: &'lua Lua,
                      builder: ClassBuilder<'lua>)
                      -> rlua::Result<ClassBuilder<'lua>> {
    // TODO Do properly
    use super::dummy;
    builder.method("connect_signal".into(), lua.create_function(dummy)?)?
           .method("buttons".into(), lua.create_function(dummy)?)?
           .method("wallpaper".into(), lua.create_function(wallpaper)?)?
           .method("tags".into(), lua.create_function(tags)?)?
           .method("keys".into(), lua.create_function(root_keys)?)?
           .method("size".into(), lua.create_function(dummy_double)?)?
           .method("size_mm".into(), lua.create_function(dummy_double)?)?
           .method("cursor".into(), lua.create_function(dummy)?)
}

impl_objectable!(Root, RootState);

fn dummy_double<'lua>(_: &'lua Lua, _: rlua::Value) -> rlua::Result<(i32, i32)> {
    Ok((0, 0))
}

/// Gets the wallpaper as a cairo surface or set it as a cairo pattern
fn wallpaper<'lua>(lua: &'lua Lua, pattern: Option<LightUserData>) -> rlua::Result<Value<'lua>> {
    // TODO FIXME Implement for realz
    if let Some(pattern) = pattern {
        // TODO Wrap before giving it to set_wallpaper
        let pattern = pattern.0 as *mut cairo_pattern_t;
        return set_wallpaper(lua, pattern)?.to_lua(lua)
    }
    // TODO Look it up in global conf (e.g probably super secret lua value)
    return Ok(Value::Nil)
}

fn set_wallpaper<'lua>(_: &'lua Lua, _pattern: *mut cairo_pattern_t) -> rlua::Result<bool> {
    warn!("Fake setting the wallpaper");
    Ok(true)
}

fn tags<'lua>(lua: &'lua Lua, _: ()) -> rlua::Result<Table<'lua>> {
    let table = lua.create_table()?;
    let activated_tags = lua.named_registry_value::<Table>(super::tag::TAG_LIST)?;
    for pair in activated_tags.pairs::<Value, Value>() {
        let (key, value) = pair?;
        table.set(key, value)?;
    }
    Ok(table)
}

/// Get or set global key bindings.
///
/// These bindings will be available when you press keys on the root window.
fn root_keys<'lua>(lua: &'lua Lua, key_array: rlua::Value<'lua>) -> rlua::Result<rlua::Value<'lua>> {
    match key_array {
        // Set the global keys
        Value::Table(key_array) => {
            let copy = lua.create_table()?;
            // NOTE We make a deep clone so they can't modify references.
            for entry in key_array.clone().pairs() {
                let (key, value) = entry?;
                copy.set::<Value, Value>(key, value)?;
            }
            lua.set_named_registry_value(ROOT_KEYS_HANDLE, copy)?;
            Ok(Value::Table(key_array))
        }
        // Get the global keys
        Value::Nil => {
            let res = lua.create_table()?;
            for entry in lua.globals().get::<_, Table>(ROOT_KEYS_HANDLE).or(lua.create_table())?.pairs() {
                let (key, value) = entry?;
                res.set::<Value, Value>(key, value)?;
            }
            Ok(Value::Table(res))
        }
        v => {
            Err(rlua::Error::RuntimeError(format!("Expected nil or array \
                                                   of keys, got {:?}",
                                                  v)))
        }
    }
}

#[cfg(test)]
mod test {
    use super::super::root;
    use super::super::tag;
    use rlua::Lua;

    #[test]
    fn tags_none() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local t = root.tags()
assert(type(t) == "table")
assert(type(next(t)) == "nil")
"#,
                 None
        ).unwrap()
    }

    #[test]
    fn tags_does_not_copy() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local t = tag{ activated = true }
local t2 = root.tags()[1]
assert(t == t2)
t2.name = "Foo"
assert(t.name == "Foo")
"#,
                 None
        ).unwrap()
    }

    #[test]
    fn tags_some() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local first = tag{ activated = true }
local second = tag{ activated = true }
local t = root.tags()
assert(t[1] == first)
assert(t[2] == second)
"#,
                 None
        ).unwrap()
    }

    #[test]
    fn tags_removal() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local first = tag{ activated = true }
local second = tag{ activated = true }
first.activated = false
local t = root.tags()
assert(t[1] == second)
assert(type(t[2]) == "nil")
"#,
                 None
        ).unwrap()
    }
}
<commit_msg>root.keys(): Fix querying the keys<commit_after>//! TODO Fill in

use super::class::{Class, ClassBuilder};
use super::object::{self, Object, Objectable};
use cairo_sys::cairo_pattern_t;
use rlua::{self, LightUserData, Lua, Table, ToLua, UserData, UserDataMethods, Value};
use std::default::Default;
use std::fmt::{self, Display, Formatter};

/// Handle to the list of global key bindings
pub const ROOT_KEYS_HANDLE: &'static str = "__ROOT_KEYS";

#[derive(Clone, Debug)]
pub struct RootState {
    // TODO Fill in
    dummy: i32
}

pub struct Root<'lua>(Object<'lua>);

impl Default for RootState {
    fn default() -> Self {
        RootState { dummy: 0 }
    }
}

impl Display for RootState {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Root: {:p}", self)
    }
}

impl<'lua> ToLua<'lua> for Root<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.0.to_lua(lua)
    }
}

impl UserData for RootState {
    fn add_methods(methods: &mut UserDataMethods<Self>) {
        object::default_add_methods(methods);
    }
}

pub fn init(lua: &Lua) -> rlua::Result<Class> {
    // FIXME: In awesome there is no root class
    method_setup(lua, Class::builder(lua, "FIXME", None)?)?.save_class("root")?
                                                           .build()
}

fn method_setup<'lua>(lua: &'lua Lua,
                      builder: ClassBuilder<'lua>)
                      -> rlua::Result<ClassBuilder<'lua>> {
    // TODO Do properly
    use super::dummy;
    builder.method("connect_signal".into(), lua.create_function(dummy)?)?
           .method("buttons".into(), lua.create_function(dummy)?)?
           .method("wallpaper".into(), lua.create_function(wallpaper)?)?
           .method("tags".into(), lua.create_function(tags)?)?
           .method("keys".into(), lua.create_function(root_keys)?)?
           .method("size".into(), lua.create_function(dummy_double)?)?
           .method("size_mm".into(), lua.create_function(dummy_double)?)?
           .method("cursor".into(), lua.create_function(dummy)?)
}

impl_objectable!(Root, RootState);

fn dummy_double<'lua>(_: &'lua Lua, _: rlua::Value) -> rlua::Result<(i32, i32)> {
    Ok((0, 0))
}

/// Gets the wallpaper as a cairo surface or set it as a cairo pattern
fn wallpaper<'lua>(lua: &'lua Lua, pattern: Option<LightUserData>) -> rlua::Result<Value<'lua>> {
    // TODO FIXME Implement for realz
    if let Some(pattern) = pattern {
        // TODO Wrap before giving it to set_wallpaper
        let pattern = pattern.0 as *mut cairo_pattern_t;
        return set_wallpaper(lua, pattern)?.to_lua(lua)
    }
    // TODO Look it up in global conf (e.g probably super secret lua value)
    return Ok(Value::Nil)
}

fn set_wallpaper<'lua>(_: &'lua Lua, _pattern: *mut cairo_pattern_t) -> rlua::Result<bool> {
    warn!("Fake setting the wallpaper");
    Ok(true)
}

fn tags<'lua>(lua: &'lua Lua, _: ()) -> rlua::Result<Table<'lua>> {
    let table = lua.create_table()?;
    let activated_tags = lua.named_registry_value::<Table>(super::tag::TAG_LIST)?;
    for pair in activated_tags.pairs::<Value, Value>() {
        let (key, value) = pair?;
        table.set(key, value)?;
    }
    Ok(table)
}

/// Get or set global key bindings.
///
/// These bindings will be available when you press keys on the root window.
fn root_keys<'lua>(lua: &'lua Lua, key_array: rlua::Value<'lua>) -> rlua::Result<rlua::Value<'lua>> {
    match key_array {
        // Set the global keys
        Value::Table(key_array) => {
            let copy = lua.create_table()?;
            // NOTE We make a deep clone so they can't modify references.
            for entry in key_array.clone().pairs() {
                let (key, value) = entry?;
                copy.set::<Value, Value>(key, value)?;
            }
            lua.set_named_registry_value(ROOT_KEYS_HANDLE, copy)?;
            Ok(Value::Table(key_array))
        }
        // Get the global keys
        Value::Nil => {
            let res = lua.create_table()?;
            for entry in lua.named_registry_value::<Table>(ROOT_KEYS_HANDLE).or(lua.create_table())?.pairs() {
                let (key, value) = entry?;
                res.set::<Value, Value>(key, value)?;
            }
            Ok(Value::Table(res))
        }
        v => {
            Err(rlua::Error::RuntimeError(format!("Expected nil or array \
                                                   of keys, got {:?}",
                                                  v)))
        }
    }
}

#[cfg(test)]
mod test {
    use super::super::root;
    use super::super::tag;
    use rlua::Lua;

    #[test]
    fn tags_none() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local t = root.tags()
assert(type(t) == "table")
assert(type(next(t)) == "nil")
"#,
                 None
        ).unwrap()
    }

    #[test]
    fn tags_does_not_copy() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local t = tag{ activated = true }
local t2 = root.tags()[1]
assert(t == t2)
t2.name = "Foo"
assert(t.name == "Foo")
"#,
                 None
        ).unwrap()
    }

    #[test]
    fn tags_some() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local first = tag{ activated = true }
local second = tag{ activated = true }
local t = root.tags()
assert(t[1] == first)
assert(t[2] == second)
"#,
                 None
        ).unwrap()
    }

    #[test]
    fn tags_removal() {
        let lua = Lua::new();
        tag::init(&lua).unwrap();
        root::init(&lua).unwrap();
        lua.eval(
                 r#"
local first = tag{ activated = true }
local second = tag{ activated = true }
first.activated = false
local t = root.tags()
assert(t[1] == second)
assert(type(t[2]) == "nil")
"#,
                 None
        ).unwrap()
    }
}
<|endoftext|>


<commit_before>use internal::input;
use internal::{State, InputModify, ParseResultModify};

use {Input, ParseResult};
use buffer::{IntoStream, ParseError, Stream};

/// Stream implementation for immutable slices.
///
/// ```
/// # #[macro_use] extern crate chomp;
/// # fn main() {
/// use chomp::{token, take};
/// use chomp::buffer::{IntoStream, Stream};
///
/// let i = b"foo";
///
/// let r = i.into_stream().parse(parser!{
///     token(b'f');
///     take(2);
/// });
///
/// assert_eq!(r, Ok(b"oo" as &[u8]));
/// # }
/// ```
///
/// ```
/// # #[macro_use] extern crate chomp;
/// # fn main() {
/// use chomp::{token, many, take};
/// use chomp::buffer::{IntoStream, Stream};
///
/// let i = b"foofoo";
///
/// let r = i.into_stream().parse(parser!{many(parser!{
///     token(b'f');
///     take(2);
/// })});
///
/// assert_eq!(r, Ok(vec![b"oo" as &[u8], b"oo" as &[u8]]));
/// # }
/// ```
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct SliceStream<'i, I: 'i> {
    pos:   usize,
    slice: &'i [I],
}

impl<'i, I: 'i> SliceStream<'i, I> {
    /// Creates a new stream from an immutable slice.
    #[inline]
    pub fn new(slice: &'i [I]) -> Self {
        SliceStream {
            pos:   0,
            slice: slice,
        }
    }

    /// The number of bytes left in the buffer
    #[inline]
    pub fn len(&self) -> usize {
        self.slice.len() - self.pos
    }

    /// Returns true if no more bytes are available
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

impl<'a, 'i, I: 'i> IntoStream<'a, 'i> for &'i [I] {
    type Item = I;
    type Into = SliceStream<'i, I>;

    #[inline]
    fn into_stream(self) -> SliceStream<'i, I> {
        SliceStream::new(self)
    }
}

impl<'a, 'i, I: 'i> Stream<'a, 'i> for SliceStream<'i, I> {
    type Item = I;

    #[inline]
    fn parse<F, T, E>(&'a mut self, f: F) -> Result<T, ParseError<'i, Self::Item, E>>
      where F: FnOnce(Input<'i, Self::Item>) -> ParseResult<'i, Self::Item, T, E>,
            T: 'i,
            E: 'i {
        match f(input::new(input::END_OF_INPUT, &self.slice[self.pos..])).internal() {
            State::Data(remainder, data) => {
                // TODO: Do something neater with the remainder
                self.pos += self.len() - remainder.buffer().len();

                Ok(data)
            },
            State::Error(remainder, err) => {
                // TODO: Do something neater with the remainder
                // TODO: Detail this behaviour, maybe make it configurable
                self.pos += self.len() - remainder.len();

                Err(ParseError::ParseError(remainder, err))
            },
            State::Incomplete(n) => Err(ParseError::Incomplete(n + self.len())),
        }
    }
}
<commit_msg>SliceStream: EndOfInput will now be emitted correctly<commit_after>use internal::input;
use internal::{State, InputModify, ParseResultModify};

use {Input, ParseResult};
use buffer::{IntoStream, ParseError, Stream};

/// Stream implementation for immutable slices.
///
/// ```
/// # #[macro_use] extern crate chomp;
/// # fn main() {
/// use chomp::{token, take};
/// use chomp::buffer::{IntoStream, Stream};
///
/// let i = b"foo";
///
/// let r = i.into_stream().parse(parser!{
///     token(b'f');
///     take(2);
/// });
///
/// assert_eq!(r, Ok(b"oo" as &[u8]));
/// # }
/// ```
///
/// ```
/// # #[macro_use] extern crate chomp;
/// # fn main() {
/// use chomp::{token, many, take};
/// use chomp::buffer::{IntoStream, Stream};
///
/// let i = b"foofoo";
///
/// let r = i.into_stream().parse(parser!{many(parser!{
///     token(b'f');
///     take(2);
/// })});
///
/// assert_eq!(r, Ok(vec![b"oo" as &[u8], b"oo" as &[u8]]));
/// # }
/// ```
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct SliceStream<'i, I: 'i> {
    pos:   usize,
    slice: &'i [I],
}

impl<'i, I: 'i> SliceStream<'i, I> {
    /// Creates a new stream from an immutable slice.
    #[inline]
    pub fn new(slice: &'i [I]) -> Self {
        SliceStream {
            pos:   0,
            slice: slice,
        }
    }

    /// The number of bytes left in the buffer
    #[inline]
    pub fn len(&self) -> usize {
        self.slice.len() - self.pos
    }

    /// Returns true if no more bytes are available
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

impl<'a, 'i, I: 'i> IntoStream<'a, 'i> for &'i [I] {
    type Item = I;
    type Into = SliceStream<'i, I>;

    #[inline]
    fn into_stream(self) -> SliceStream<'i, I> {
        SliceStream::new(self)
    }
}

impl<'a, 'i, I: 'i> Stream<'a, 'i> for SliceStream<'i, I> {
    type Item = I;

    #[inline]
    fn parse<F, T, E>(&'a mut self, f: F) -> Result<T, ParseError<'i, Self::Item, E>>
      where F: FnOnce(Input<'i, Self::Item>) -> ParseResult<'i, Self::Item, T, E>,
            T: 'i,
            E: 'i {
        if self.is_empty() {
            return Err(ParseError::EndOfInput);
        }

        match f(input::new(input::END_OF_INPUT, &self.slice[self.pos..])).internal() {
            State::Data(remainder, data) => {
                // TODO: Do something neater with the remainder
                self.pos += self.len() - remainder.buffer().len();

                Ok(data)
            },
            State::Error(remainder, err) => {
                // TODO: Do something neater with the remainder
                // TODO: Detail this behaviour, maybe make it configurable
                self.pos += self.len() - remainder.len();

                Err(ParseError::ParseError(remainder, err))
            },
            State::Incomplete(n) => Err(ParseError::Incomplete(n + self.len())),
        }
    }
}
<|endoftext|>