<commit_before>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![recursion_limit="128"]

#[macro_use]
extern crate failure_derive;
extern crate failure;

#[macro_use]
extern crate lazy_static;

extern crate rusqlite;

extern crate uuid;

pub extern crate edn;
extern crate mentat_core;
extern crate mentat_db;
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate mentat_query_projector;
extern crate mentat_query_pull;
extern crate mentat_query_translator;
extern crate mentat_sql;
extern crate mentat_tolstoy;

pub use mentat_core::{
    Attribute,
    Entid,
    DateTime,
    HasSchema,
    KnownEntid,
    Keyword,
    Schema,
    Binding,
    TxReport,
    TypedValue,
    Uuid,
    Utc,
    ValueType,
};

pub use mentat_query::{
    FindSpec,
};

pub use mentat_db::{
    CORE_SCHEMA_VERSION,
    DB_SCHEMA_CORE,
    AttributeSet,
    TxObserver,
    new_connection,
};

#[cfg(feature = "sqlcipher")]
pub use mentat_db::{
    new_connection_with_key,
    change_encryption_key,
};

/// Produce the appropriate `Variable` for the provided valid ?-prefixed name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! var {
    ( ? $var:ident ) => {
        $crate::Variable::from_valid_name(concat!("?", stringify!($var)))
    };
}

/// Produce the appropriate `Keyword` for the provided namespace and name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! kw {
    ( : $n:ident ) => {
        $crate::Keyword::plain(
            stringify!($n)
        )
    };

    ( : $ns:ident / $n:ident ) => {
        $crate::Keyword::namespaced(
            stringify!($ns),
            stringify!($n)
        )
    };

    ( : $ns:ident$(. $nss:ident)+ / $n:ident ) => {
        $crate::Keyword::namespaced(
            concat!(stringify!($ns) $(, ".", stringify!($nss))+),
            stringify!($n)
        )
    };
}

#[macro_use]
pub mod errors;
pub use errors::{
    MentatError,
    Result,
};

pub use edn::ParseError;
pub use mentat_db::DbError;
pub use mentat_query_algebrizer::AlgebrizerError;
pub use mentat_query_projector::ProjectorError;
pub use mentat_query_pull::PullError;
pub use mentat_sql::SQLError;

pub mod conn;
pub mod entity_builder;
pub mod query;
pub mod query_builder;
pub mod store;
pub mod vocabulary;

pub use query::{
    IntoResult,
    PlainSymbol,
    QueryExecutionResult,
    QueryExplanation,
    QueryInputs,
    QueryOutput,
    QueryPlanStep,
    QueryResults,
    RelResult,
    Variable,
    q_once,
};

pub use query_builder::{
    QueryBuilder,
};

pub use conn::{
    CacheAction,
    CacheDirection,
    Conn,
    InProgress,
    Metadata,
    Pullable,
    Queryable,
    Syncable,
};

pub use store::{
    Store,
};

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

    #[test]
    fn can_import_edn() {
        assert_eq!(":foo", &Keyword::plain("foo").to_string());
    }

    #[test]
    fn test_kw() {
        assert_eq!(kw!(:foo/bar), Keyword::namespaced("foo", "bar"));
        assert_eq!(kw!(:org.mozilla.foo/bar_baz), Keyword::namespaced("org.mozilla.foo", "bar_baz"));
    }

    #[test]
    fn test_var() {
        let foo_baz = var!(?foo_baz);
        let vu = var!(?vü);
        assert_eq!(foo_baz, Variable::from_valid_name("?foo_baz"));
        assert_eq!(vu, Variable::from_valid_name("?vü"));
        assert_eq!(foo_baz.as_str(), "?foo_baz");
    }
}
<commit_msg>Part 2: Expose time related things at top-level.<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![recursion_limit="128"]

#[macro_use]
extern crate failure_derive;
extern crate failure;

#[macro_use]
extern crate lazy_static;

extern crate rusqlite;

extern crate uuid;

pub extern crate edn;
extern crate mentat_core;
extern crate mentat_db;
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate mentat_query_projector;
extern crate mentat_query_pull;
extern crate mentat_query_translator;
extern crate mentat_sql;
extern crate mentat_tolstoy;

pub use mentat_core::{
    Attribute,
    Binding,
    DateTime,
    Entid,
    HasSchema,
    Keyword,
    KnownEntid,
    Schema,
    StructuredMap,
    TxReport,
    TypedValue,
    Utc,
    Uuid,
    ValueType,
    now,
};

pub use mentat_query::{
    FindSpec,
};

pub use mentat_db::{
    CORE_SCHEMA_VERSION,
    DB_SCHEMA_CORE,
    AttributeSet,
    TxObserver,
    new_connection,
};

#[cfg(feature = "sqlcipher")]
pub use mentat_db::{
    new_connection_with_key,
    change_encryption_key,
};

/// Produce the appropriate `Variable` for the provided valid ?-prefixed name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! var {
    ( ? $var:ident ) => {
        $crate::Variable::from_valid_name(concat!("?", stringify!($var)))
    };
}

/// Produce the appropriate `Keyword` for the provided namespace and name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! kw {
    ( : $n:ident ) => {
        $crate::Keyword::plain(
            stringify!($n)
        )
    };

    ( : $ns:ident / $n:ident ) => {
        $crate::Keyword::namespaced(
            stringify!($ns),
            stringify!($n)
        )
    };

    ( : $ns:ident$(. $nss:ident)+ / $n:ident ) => {
        $crate::Keyword::namespaced(
            concat!(stringify!($ns) $(, ".", stringify!($nss))+),
            stringify!($n)
        )
    };
}

#[macro_use]
pub mod errors;
pub use errors::{
    MentatError,
    Result,
};

pub use edn::{
    FromMicros,
    FromMillis,
    ParseError,
    ToMicros,
    ToMillis,
};
pub use mentat_db::DbError;
pub use mentat_query_algebrizer::AlgebrizerError;
pub use mentat_query_projector::ProjectorError;
pub use mentat_query_pull::PullError;
pub use mentat_sql::SQLError;

pub mod conn;
pub mod entity_builder;
pub mod query;
pub mod query_builder;
pub mod store;
pub mod vocabulary;

pub use query::{
    IntoResult,
    PlainSymbol,
    QueryExecutionResult,
    QueryExplanation,
    QueryInputs,
    QueryOutput,
    QueryPlanStep,
    QueryResults,
    RelResult,
    Variable,
    q_once,
};

pub use query_builder::{
    QueryBuilder,
};

pub use conn::{
    CacheAction,
    CacheDirection,
    Conn,
    InProgress,
    Metadata,
    Pullable,
    Queryable,
    Syncable,
};

pub use store::{
    Store,
};

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

    #[test]
    fn can_import_edn() {
        assert_eq!(":foo", &Keyword::plain("foo").to_string());
    }

    #[test]
    fn test_kw() {
        assert_eq!(kw!(:foo/bar), Keyword::namespaced("foo", "bar"));
        assert_eq!(kw!(:org.mozilla.foo/bar_baz), Keyword::namespaced("org.mozilla.foo", "bar_baz"));
    }

    #[test]
    fn test_var() {
        let foo_baz = var!(?foo_baz);
        let vu = var!(?vü);
        assert_eq!(foo_baz, Variable::from_valid_name("?foo_baz"));
        assert_eq!(vu, Variable::from_valid_name("?vü"));
        assert_eq!(foo_baz.as_str(), "?foo_baz");
    }
}
<|endoftext|>


<commit_before>//! A minimal implementation of SHA1 for rust.
//!
//! Example:
//!
//! ```rust
//! extern crate sha1;
//! # fn main() {
//!
//! let mut m = sha1::Sha1::new();
//! m.update("Hello World!".as_bytes());
//! assert_eq!(m.hexdigest().as_slice(),
//!            "2ef7bde608ce5404e97d5f042f95f89f1c232871");
//! # }
//! ```

#![feature(slicing_syntax)]

#![experimental]

extern crate serialize;

use std::io::{MemWriter, BufWriter};

/// Represents a Sha1 hash object in memory.
#[deriving(Clone)]
pub struct Sha1 {
    state: [u32, ..5],
    data: Vec<u8>,
    len: u64,
}

const DEFAULT_STATE : [u32, ..5] =
    [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];

fn to_hex(input: &[u8]) -> String {
    let mut s = String::new();
    for b in input.iter() {
        s.push_str(format!("{:02x}", *b)[]);
    }
    return s;
}

impl Sha1 {

    /// Creates an fresh sha1 hash object.
    pub fn new() -> Sha1 {
        Sha1 {
            state: DEFAULT_STATE,
            data: Vec::new(),
            len: 0,
        }
    }

    fn process_block(&mut self, block: &[u8]) {
        assert_eq!(block.len(), 64);

        let mut words = [0u32, ..80];
        for (i, chunk) in block.chunks(4).enumerate() {
            words[i] = (chunk[3] as u32) |
                       (chunk[2] as u32 << 8) |
                       (chunk[1] as u32 << 16) |
                       (chunk[0] as u32 << 24);
        }

        let ff = |b: u32, c: u32, d: u32| d ^ (b & (c ^ d));
        let gg = |b: u32, c: u32, d: u32| b ^ c ^ d;
        let hh = |b: u32, c: u32, d: u32| (b & c) | (d & (b | c));
        let ii = |b: u32, c: u32, d: u32| b ^ c ^ d;

        let left_rotate = |x: u32, n: u32| (x << n as uint) | (x >> (32 - n) as uint);

        for i in range(16u, 80u) {
            let n = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
            words[i] = left_rotate(n, 1);
        }

        let mut a = self.state[0];
        let mut b = self.state[1];
        let mut c = self.state[2];
        let mut d = self.state[3];
        let mut e = self.state[4];

        for i in range(0u, 80u) {
            let (f, k) = match i {
                0 ... 19 => (ff(b, c, d), 0x5a827999),
                20 ... 39 => (gg(b, c, d), 0x6ed9eba1),
                40 ... 59 => (hh(b, c, d), 0x8f1bbcdc),
                60 ... 79 => (ii(b, c, d), 0xca62c1d6),
                _ => (0, 0),
            };

            let tmp = left_rotate(a, 5) + f + e + k + words[i];
            e = d;
            d = c;
            c = left_rotate(b, 30);
            b = a;
            a = tmp;
        }

        self.state[0] += a;
        self.state[1] += b;
        self.state[2] += c;
        self.state[3] += d;
        self.state[4] += e;
    }

    /// Resets the hash object to it's initial state.
    pub fn reset(&mut self) {
        self.state = DEFAULT_STATE;
        self.data.clear();
        self.len = 0;
    }

    /// Update hash with input data.
    pub fn update(&mut self, data: &[u8]) {
        let mut d = self.data.clone();
        self.data.clear();

        d.push_all(data);

        for chunk in d[].chunks(64) {
            self.len += chunk.len() as u64;

            if chunk.len() == 64 {
                self.process_block(chunk);
            } else {
                self.data.push_all(chunk);
            }
        }
    }

    /// Retrieve digest result.  The output must be large enough to
    /// contain result (20 bytes).
    pub fn output(&self, out: &mut [u8]) {
        // these are unlikely to fail, since we're writing to memory
        #![allow(unused_must_use)]

        let mut m = Sha1 {
            state: self.state,
            data: Vec::new(),
            len: 0,
        };

        let mut w = MemWriter::new();
        w.write(self.data[]);
        w.write_u8(0x80 as u8);
        w.write(Vec::from_elem(56 - self.data.len() - 1, 0x00 as u8)[]);
        w.write_be_u64(self.len * 8);
        m.process_block(w.get_ref());

        let mut w = BufWriter::new(out);
        for &n in m.state.iter() {
            w.write_be_u32(n);
        }
    }

    /// Shortcut for getting `output` into a new vector.
    pub fn digest(&self) -> Vec<u8> {
        let mut buf = Vec::from_elem(20, 0u8);
        self.output(buf[mut]);
        buf
    }

    /// Shortcut for getting a hex output of the vector.
    pub fn hexdigest(&self) -> String {
        to_hex(self.digest()[])
    }
}

#[test]
fn test_simple() {
    let mut m = Sha1::new();

    let tests = [
        ("The quick brown fox jumps over the lazy dog",
         "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"),
        ("The quick brown fox jumps over the lazy cog",
         "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3"),
        ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709"),
    ];

    for &(s, ref h) in tests.iter() {
        let data = s.as_bytes();

        m.reset();
        m.update(data);
        let hh = m.hexdigest();

        assert_eq!(hh.len(), h.len());
        assert_eq!(hh[], *h);
    }
}
<commit_msg>Fixed sha1 implementation.<commit_after>//! A minimal implementation of SHA1 for rust.
//!
//! Example:
//!
//! ```rust
//! extern crate sha1;
//! # fn main() {
//!
//! let mut m = sha1::Sha1::new();
//! m.update("Hello World!".as_bytes());
//! assert_eq!(m.hexdigest().as_slice(),
//!            "2ef7bde608ce5404e97d5f042f95f89f1c232871");
//! # }
//! ```

#![feature(slicing_syntax)]

#![experimental]

use std::io::{MemWriter, BufWriter};

/// Represents a Sha1 hash object in memory.
#[deriving(Clone)]
pub struct Sha1 {
    state: [u32, ..5],
    data: Vec<u8>,
    len: u64,
}

const DEFAULT_STATE : [u32, ..5] =
    [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];

fn to_hex(input: &[u8]) -> String {
    let mut s = String::new();
    for b in input.iter() {
        s.push_str(format!("{:02x}", *b)[]);
    }
    return s;
}

impl Sha1 {

    /// Creates an fresh sha1 hash object.
    pub fn new() -> Sha1 {
        Sha1 {
            state: DEFAULT_STATE,
            data: Vec::new(),
            len: 0,
        }
    }

    fn process_block(&mut self, block: &[u8]) {
        assert_eq!(block.len(), 64);

        let mut words = [0u32, ..80];
        for (i, chunk) in block.chunks(4).enumerate() {
            words[i] = (chunk[3] as u32) |
                       (chunk[2] as u32 << 8) |
                       (chunk[1] as u32 << 16) |
                       (chunk[0] as u32 << 24);
        }

        let ff = |b: u32, c: u32, d: u32| d ^ (b & (c ^ d));
        let gg = |b: u32, c: u32, d: u32| b ^ c ^ d;
        let hh = |b: u32, c: u32, d: u32| (b & c) | (d & (b | c));
        let ii = |b: u32, c: u32, d: u32| b ^ c ^ d;

        let left_rotate = |x: u32, n: u32| (x << n as uint) | (x >> (32 - n) as uint);

        for i in range(16u, 80u) {
            let n = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
            words[i] = left_rotate(n, 1);
        }

        let mut a = self.state[0];
        let mut b = self.state[1];
        let mut c = self.state[2];
        let mut d = self.state[3];
        let mut e = self.state[4];

        for i in range(0u, 80u) {
            let (f, k) = match i {
                0 ... 19 => (ff(b, c, d), 0x5a827999),
                20 ... 39 => (gg(b, c, d), 0x6ed9eba1),
                40 ... 59 => (hh(b, c, d), 0x8f1bbcdc),
                60 ... 79 => (ii(b, c, d), 0xca62c1d6),
                _ => (0, 0),
            };

            let tmp = left_rotate(a, 5) + f + e + k + words[i];
            e = d;
            d = c;
            c = left_rotate(b, 30);
            b = a;
            a = tmp;
        }

        self.state[0] += a;
        self.state[1] += b;
        self.state[2] += c;
        self.state[3] += d;
        self.state[4] += e;
    }

    /// Resets the hash object to it's initial state.
    pub fn reset(&mut self) {
        self.state = DEFAULT_STATE;
        self.data.clear();
        self.len = 0;
    }

    /// Update hash with input data.
    pub fn update(&mut self, data: &[u8]) {
        let mut d = self.data.clone();
        self.data.clear();

        d.push_all(data);

        for chunk in d[].chunks(64) {
            self.len += chunk.len() as u64;

            if chunk.len() == 64 {
                self.process_block(chunk);
            } else {
                self.data.push_all(chunk);
            }
        }
    }

    /// Retrieve digest result.  The output must be large enough to
    /// contain result (20 bytes).
    pub fn output(&self, out: &mut [u8]) {
        // these are unlikely to fail, since we're writing to memory
        #![allow(unused_must_use)]

        let mut m = Sha1 {
            state: self.state,
            data: Vec::new(),
            len: 0,
        };

        let mut w = MemWriter::new();
        w.write(self.data[]);
        w.write_u8(0x80 as u8);
        let padding = (((56 - self.len as int - 1) % 64) + 64) % 64;
        w.write(Vec::from_elem(padding as uint, 0u8)[]);
        w.write_be_u64(self.len * 8);
        for chunk in w.get_ref()[].chunks(64) {
            m.process_block(chunk);
        }

        let mut w = BufWriter::new(out);
        for &n in m.state.iter() {
            w.write_be_u32(n);
        }
    }

    /// Shortcut for getting `output` into a new vector.
    pub fn digest(&self) -> Vec<u8> {
        let mut buf = Vec::from_elem(20, 0u8);
        self.output(buf[mut]);
        buf
    }

    /// Shortcut for getting a hex output of the vector.
    pub fn hexdigest(&self) -> String {
        to_hex(self.digest()[])
    }
}

#[test]
fn test_simple() {
    let mut m = Sha1::new();

    let tests = [
        ("The quick brown fox jumps over the lazy dog",
         "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"),
        ("The quick brown fox jumps over the lazy cog",
         "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3"),
        ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709"),
        ("testing\n", "9801739daae44ec5293d4e1f53d3f4d2d426d91c"),
        ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
         "025ecbd5d70f8fb3c5457cd96bab13fda305dc59"),
    ];

    for &(s, ref h) in tests.iter() {
        let data = s.as_bytes();

        m.reset();
        m.update(data);
        let hh = m.hexdigest();

        assert_eq!(hh.len(), h.len());
        assert_eq!(hh[], *h);
    }
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(asm, lang_items, plugin)]
#![feature(core_intrinsics, core_slice_ext)]
#![allow(improper_ctypes)]
#![feature(const_fn)]
#![deny(missing_docs)]
#![no_std]

/*!
Zinc is an embedded stack for rust.

Zinc provides a complete embedded stack for application development in rust. It
is provided in a form of library, compiled for a specific MCU, that can be
linked into user's own applications.

### Supported architectures

ARM is the only architecture, supported at the moment. Zinc can be compiled for
"native" architecture as well, which should be useful only for testing the code,
though.

### Supported ARM MCUs

Two MCUs are supported at the moment, specifically

 * NXP LPC1768
 * ST STM32F407
 * ST STM32L152RCT6
 * Freescale MK20DX32
 * TI TM4C123GXL

The code is generic enough to support other MCUs in the same family (LPC17xx and
STM32F403/407).
*/
#![plugin(ioreg)]
#![feature(no_std)]

#[cfg(target_os = "none")]
extern crate rlibc;

#[macro_use] #[no_link] extern crate ioreg;
#[macro_use] extern crate volatile_cell;

#[cfg(test)] extern crate std;

#[cfg(test)] #[macro_use(expect)] extern crate expectest;

pub mod drivers;
pub mod hal;
pub mod util;
pub mod os;

/// Export a subset of `core` as `std.
///
/// This is exported as a temporary convenience as `rustc` still looks
/// for some items in the `std` namespace.
///
/// TODO(farcaller): clean up when fixed.
#[cfg(target_os = "none")]
pub mod std {
  pub use core::cmp;  // used for #[derive(Eq)] until fixed in rust.
  pub use core::option;
  pub use core::num;
  pub use core::marker;
}
<commit_msg>rustup: add core_str_ext feature<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(asm, lang_items, plugin)]
#![feature(core_intrinsics, core_slice_ext, core_str_ext)]
#![allow(improper_ctypes)]
#![feature(const_fn)]
#![deny(missing_docs)]
#![no_std]

/*!
Zinc is an embedded stack for rust.

Zinc provides a complete embedded stack for application development in rust. It
is provided in a form of library, compiled for a specific MCU, that can be
linked into user's own applications.

### Supported architectures

ARM is the only architecture, supported at the moment. Zinc can be compiled for
"native" architecture as well, which should be useful only for testing the code,
though.

### Supported ARM MCUs

Two MCUs are supported at the moment, specifically

 * NXP LPC1768
 * ST STM32F407
 * ST STM32L152RCT6
 * Freescale MK20DX32
 * TI TM4C123GXL

The code is generic enough to support other MCUs in the same family (LPC17xx and
STM32F403/407).
*/
#![plugin(ioreg)]
#![feature(no_std)]

#[cfg(target_os = "none")]
extern crate rlibc;

#[macro_use] #[no_link] extern crate ioreg;
#[macro_use] extern crate volatile_cell;

#[cfg(test)] extern crate std;

#[cfg(test)] #[macro_use(expect)] extern crate expectest;

pub mod drivers;
pub mod hal;
pub mod util;
pub mod os;

/// Export a subset of `core` as `std.
///
/// This is exported as a temporary convenience as `rustc` still looks
/// for some items in the `std` namespace.
///
/// TODO(farcaller): clean up when fixed.
#[cfg(target_os = "none")]
pub mod std {
  pub use core::cmp;  // used for #[derive(Eq)] until fixed in rust.
  pub use core::option;
  pub use core::num;
  pub use core::marker;
}
<|endoftext|>


<commit_before>use std::ops::Deref;
use std::cmp::Ordering;

/// A `Vec` in sorted order without duplicates.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SortedUniqueVec<T: Ord + Clone> {
    vec: Vec<T>,
}

pub fn is_sorted_unique<T: Ord>(slice: &[T]) -> bool {
    if slice.len() < 2 {
        true
    } else {
        slice.windows(2).all(|win| win[0] < win[1])
    }
}

pub enum LeftOrRight {
    Left,
    Right,
}

impl<T: Ord + Clone> SortedUniqueVec<T> {
    pub fn new() -> Self {
        SortedUniqueVec { vec: Vec::new() }
    }

    pub fn with_capacity(capa: usize) -> Self {
        SortedUniqueVec { vec: Vec::with_capacity(capa) }
    }

    /// Panics if sorted order is destroyed by this push operation.
    pub fn push(&mut self, item: T) {
        if let Some(last_item) = self.last() {
            assert!(last_item < &item);
        }
        self.vec.push(item);
    }

    pub fn retain<F>(&mut self, f: F)
        where F: FnMut(&T) -> bool
    {
        self.vec.retain(f);
    }

    pub fn len(&self) -> usize {
        self.vec.len()
    }

    pub fn contains(&self, element: &T) -> bool {
        self.vec.binary_search(element).is_ok()
    }

    pub fn find_by<F>(&self, f: F) -> Option<&T>
        where F: FnMut(&T) -> Ordering
    {
        match self.vec.binary_search_by(f) {
            Ok(idx) => self.vec.get(idx),
            Err(_) => None,
        }
    }

    /// Insert `element` into the sorted list.
    ///
    /// Panics if an element with the same key (according to the Eq trait) already exists.
    pub fn insert(&mut self, element: T) {
        match self.vec.binary_search(&element) {
            Ok(_idx) => {
                panic!("Element already exists");
            }
            Err(idx) => {
                self.vec.insert(idx, element);
            }
        }
    }

    /// Merges `self` and `other` into a new SortedVec.
    /// `choose_equal` decides which one of two equal values to take.
    pub fn merge<F>(&self, other: &Self, choose_equal: &F) -> Self
        where F: Fn(&T, &T) -> LeftOrRight
    {
        let mut vec = Vec::with_capacity(self.len() + other.len());

        let mut left_iter = self.vec.iter().peekable();
        let mut right_iter = other.vec.iter().peekable();

        enum Take {
            OneLeft,
            OneRight,
            Both,
            AllLeft,
            AllRight,
        };

        loop {
            let take;

            match (left_iter.peek(), right_iter.peek()) {
                (Some(l), Some(r)) => {
                    if l < r {
                        take = Take::OneLeft;
                    } else if r < l {
                        take = Take::OneRight;
                    } else {
                        take = Take::Both;
                    }
                }
                (Some(_), None) => {
                    take = Take::AllLeft;
                }
                (None, Some(_)) => {
                    take = Take::AllRight;
                }
                (None, None) => {
                    break;
                }
            }
            match take {
                Take::OneLeft => {
                    vec.push((*left_iter.next().unwrap()).clone());
                }
                Take::OneRight => {
                    vec.push((*right_iter.next().unwrap()).clone());
                }
                Take::Both => {
                    // two equal values
                    let left_value = left_iter.next().unwrap();
                    let right_value = right_iter.next().unwrap();
                    match choose_equal(left_value, right_value) {
                        LeftOrRight::Left => {
                            vec.push((*left_value).clone());
                        }
                        LeftOrRight::Right => {
                            vec.push((*right_value).clone());
                        }
                    }
                }
                Take::AllLeft => {
                    for item in left_iter {
                        vec.push((*item).clone());
                    }
                    break;
                }
                Take::AllRight => {
                    for item in right_iter {
                        vec.push((*item).clone());
                    }
                    break;
                }

            }
        }

        debug_assert!(is_sorted_unique(&vec));
        SortedUniqueVec { vec: vec }
    }
}

impl<T: Ord + Clone> AsRef<[T]> for SortedUniqueVec<T> {
    fn as_ref(&self) -> &[T] {
        &self.vec
    }
}

impl<T: Ord + Clone> Deref for SortedUniqueVec<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        &self.vec
    }
}

#[test]
fn test_insert() {
    let mut s = SortedUniqueVec::new();
    s.insert(5);
    s.insert(1);
    s.insert(8);
    s.insert(0);
    assert!(is_sorted_unique(&s));
    assert_eq!(&[0, 1, 5, 8][..], s.as_ref());
    assert_eq!(4, s.len());
}

#[test]
fn test_merge() {
    let mut s1 = SortedUniqueVec::new();
    s1.insert(5);
    s1.insert(1);
    s1.insert(8);
    s1.insert(0);
    assert!(is_sorted_unique(&s1));

    let mut s2 = SortedUniqueVec::new();
    s2.insert(55);
    s2.insert(1);
    s2.insert(5);
    s2.insert(7);
    s2.insert(9);
    assert!(is_sorted_unique(&s2));

    let r = s1.merge(&s2, &|_, _| LeftOrRight::Left);
    assert!(is_sorted_unique(&r));
    assert_eq!(&[0, 1, 5, 7, 8, 9, 55][..], r.as_ref());
}

#[test]
fn test_push_ok() {
    let mut s = SortedUniqueVec::new();
    s.push(0);
    s.push(5);
    s.push(6);
    assert!(is_sorted_unique(&s));
    assert_eq!(3, s.len());
    assert_eq!(&[0, 5, 6][..], s.as_ref());
}

#[test]
#[should_panic]
fn test_push_fail() {
    let mut s = SortedUniqueVec::new();
    s.push(0);
    s.push(1);
    s.push(1);
}

#[test]
#[should_panic]
fn test_push_fail2() {
    let mut s = SortedUniqueVec::new();
    s.push(0);
    s.push(5);
    s.push(9);
    s.push(3);
}
<commit_msg>Add get(), get_mut() and index_by() methods<commit_after>use std::ops::Deref;
use std::cmp::Ordering;

/// A `Vec` in sorted order without duplicates.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SortedUniqueVec<T: Ord + Clone> {
    vec: Vec<T>,
}

pub fn is_sorted_unique<T: Ord>(slice: &[T]) -> bool {
    if slice.len() < 2 {
        true
    } else {
        slice.windows(2).all(|win| win[0] < win[1])
    }
}

pub enum LeftOrRight {
    Left,
    Right,
}

impl<T: Ord + Clone> SortedUniqueVec<T> {
    pub fn new() -> Self {
        SortedUniqueVec { vec: Vec::new() }
    }

    pub fn with_capacity(capa: usize) -> Self {
        SortedUniqueVec { vec: Vec::with_capacity(capa) }
    }

    /// Panics if sorted order is destroyed by this push operation.
    pub fn push(&mut self, item: T) {
        if let Some(last_item) = self.last() {
            assert!(last_item < &item);
        }
        self.vec.push(item);
    }

    pub fn retain<F>(&mut self, f: F)
        where F: FnMut(&T) -> bool
    {
        self.vec.retain(f);
    }

    pub fn len(&self) -> usize {
        self.vec.len()
    }

    pub fn contains(&self, element: &T) -> bool {
        self.vec.binary_search(element).is_ok()
    }

    pub fn get(&self, idx: usize) -> Option<&T> {
        self.vec.get(idx)
    }

    pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
        self.vec.get_mut(idx)
    }

    pub fn index_by<F>(&self, f: F) -> Option<usize>
        where F: FnMut(&T) -> Ordering
    {
        match self.vec.binary_search_by(f) {
            Ok(idx) => Some(idx),
            Err(_) => None,
        }
    }

    pub fn find_by<F>(&self, f: F) -> Option<&T>
        where F: FnMut(&T) -> Ordering
    {
        match self.vec.binary_search_by(f) {
            Ok(idx) => self.vec.get(idx),
            Err(_) => None,
        }
    }

    /// Insert `element` into the sorted list.
    ///
    /// Panics if an element with the same key (according to the Eq trait) already exists.
    pub fn insert(&mut self, element: T) {
        match self.vec.binary_search(&element) {
            Ok(_idx) => {
                panic!("Element already exists");
            }
            Err(idx) => {
                self.vec.insert(idx, element);
            }
        }
    }

    /// Merges `self` and `other` into a new SortedVec.
    /// `choose_equal` decides which one of two equal values to take.
    pub fn merge<F>(&self, other: &Self, choose_equal: &F) -> Self
        where F: Fn(&T, &T) -> LeftOrRight
    {
        let mut vec = Vec::with_capacity(self.len() + other.len());

        let mut left_iter = self.vec.iter().peekable();
        let mut right_iter = other.vec.iter().peekable();

        enum Take {
            OneLeft,
            OneRight,
            Both,
            AllLeft,
            AllRight,
        };

        loop {
            let take;

            match (left_iter.peek(), right_iter.peek()) {
                (Some(l), Some(r)) => {
                    if l < r {
                        take = Take::OneLeft;
                    } else if r < l {
                        take = Take::OneRight;
                    } else {
                        take = Take::Both;
                    }
                }
                (Some(_), None) => {
                    take = Take::AllLeft;
                }
                (None, Some(_)) => {
                    take = Take::AllRight;
                }
                (None, None) => {
                    break;
                }
            }
            match take {
                Take::OneLeft => {
                    vec.push((*left_iter.next().unwrap()).clone());
                }
                Take::OneRight => {
                    vec.push((*right_iter.next().unwrap()).clone());
                }
                Take::Both => {
                    // two equal values
                    let left_value = left_iter.next().unwrap();
                    let right_value = right_iter.next().unwrap();
                    match choose_equal(left_value, right_value) {
                        LeftOrRight::Left => {
                            vec.push((*left_value).clone());
                        }
                        LeftOrRight::Right => {
                            vec.push((*right_value).clone());
                        }
                    }
                }
                Take::AllLeft => {
                    for item in left_iter {
                        vec.push((*item).clone());
                    }
                    break;
                }
                Take::AllRight => {
                    for item in right_iter {
                        vec.push((*item).clone());
                    }
                    break;
                }

            }
        }

        debug_assert!(is_sorted_unique(&vec));
        SortedUniqueVec { vec: vec }
    }
}

impl<T: Ord + Clone> AsRef<[T]> for SortedUniqueVec<T> {
    fn as_ref(&self) -> &[T] {
        &self.vec
    }
}

impl<T: Ord + Clone> Deref for SortedUniqueVec<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        &self.vec
    }
}

#[test]
fn test_insert() {
    let mut s = SortedUniqueVec::new();
    s.insert(5);
    s.insert(1);
    s.insert(8);
    s.insert(0);
    assert!(is_sorted_unique(&s));
    assert_eq!(&[0, 1, 5, 8][..], s.as_ref());
    assert_eq!(4, s.len());
}

#[test]
fn test_merge() {
    let mut s1 = SortedUniqueVec::new();
    s1.insert(5);
    s1.insert(1);
    s1.insert(8);
    s1.insert(0);
    assert!(is_sorted_unique(&s1));

    let mut s2 = SortedUniqueVec::new();
    s2.insert(55);
    s2.insert(1);
    s2.insert(5);
    s2.insert(7);
    s2.insert(9);
    assert!(is_sorted_unique(&s2));

    let r = s1.merge(&s2, &|_, _| LeftOrRight::Left);
    assert!(is_sorted_unique(&r));
    assert_eq!(&[0, 1, 5, 7, 8, 9, 55][..], r.as_ref());
}

#[test]
fn test_push_ok() {
    let mut s = SortedUniqueVec::new();
    s.push(0);
    s.push(5);
    s.push(6);
    assert!(is_sorted_unique(&s));
    assert_eq!(3, s.len());
    assert_eq!(&[0, 5, 6][..], s.as_ref());
}

#[test]
#[should_panic]
fn test_push_fail() {
    let mut s = SortedUniqueVec::new();
    s.push(0);
    s.push(1);
    s.push(1);
}

#[test]
#[should_panic]
fn test_push_fail2() {
    let mut s = SortedUniqueVec::new();
    s.push(0);
    s.push(5);
    s.push(9);
    s.push(3);
}
<|endoftext|>


<commit_before>//! Access secure credentials at runtime with multiple backends.
//!
//! For more information, see [the
//! homepage](https://github.com/emk/credentials).
//!
//! ```
//! use credentials;
//! use std::env;
//!
//! env::set_var("PASSWORD", "secret");
//! assert_eq!("secret", credentials::var("PASSWORD").unwrap());
//! ```

#[macro_use]
extern crate hyper;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate regex;
extern crate rustc_serialize;
#[cfg(test)] #[macro_use]
extern crate yup_hyper_mock as hyper_mock;

use backend::Backend;
use errors::{ErrorNew, err};
use std::cell::RefCell;
use std::convert::AsRef;
use std::ops::DerefMut;
use std::path::Path;
use std::sync::{Mutex, MutexGuard};

// Be very careful not to export any more of the Secretfile API than
// strictly necessary, because we don't want to stablize too much at this
// point.
pub use secretfile::{Secretfile, SecretfileKeys};
pub use errors::Error;

#[macro_use]
mod errors;

mod backend;
mod chained;
mod envvar;
mod secretfile;
mod vault;

/// A client which fetches secrets.  Under normal circumstances, it's
/// usually easier to use the static `credentials::var` and
/// `credentials::file` methods instead, but you may need to use this to
/// customize behavior.
pub struct Client {
    sf: Secretfile,
    backend: chained::Client,
}

impl Client {
    /// Create a new client using the default `Secretfile`.
    pub fn new() -> Result<Client, Error> {
        Client::with_secretfile(try!(Secretfile::default()))
    }

    /// Create a new client using the specified `Secretfile`.
    pub fn with_secretfile(secretfile: Secretfile) -> Result<Client, Error> {
        Ok(Client {
            sf: secretfile,
            backend: try!(chained::Client::default()),
        })
    }

    /// Provide access to a copy of the Secretfile we're using.
    pub fn secretfile(&self) -> &Secretfile {
        &self.sf
    }

    /// Fetch the value of an environment-variable-style credential.
    pub fn var<S: AsRef<str>>(&mut self, name: S) -> Result<String, Error> {
        let name_ref = name.as_ref();
        trace!("getting secure credential {}", name_ref);
        self.backend.var(&self.sf, name_ref).map_err(|e| {
            let err = Error::credential(name_ref, e);
            warn!("{}", err);
            err
        })
    }

    /// Fetch the value of a file-style credential.
    pub fn file<S: AsRef<Path>>(&mut self, path: S) -> Result<String, Error> {
        let path_ref = path.as_ref();
        let path_str = try!(path_ref.to_str().ok_or_else(|| {
            Error::credential("(invalid path)", err!("Path is not valid Unicode"))
        }));
        trace!("getting secure credential {}", path_str);
        self.backend.file(&self.sf, path_str).map_err(|e| {
            let err = Error::credential(path_str, e);
            warn!("{}", err);
            err
        })
    }
}

lazy_static! {
    // Our shared global client, initialized by `lazy_static!` and
    // protected by a Mutex.
    //
    // Rust deliberately makes it a nuisance to use mutable global
    // variables.  In this case, the `Mutex` provides thread-safe locking,
    // the `RefCell` makes this assignable, and the `Option` makes this
    // optional.  This is a message from the language saying, "Really? A
    // mutable global that might be null? Have you really thought about
    // this?"  But the global default client is only for convenience, so
    // we're OK with it, at least so far.
    static ref CLIENT: Mutex<RefCell<Option<Client>>> =
        Mutex::new(RefCell::new(None));
}

/// Call `body` with the default global client, or return an error if we
/// can't allocate a default global client.
fn with_client<F>(body: F) -> Result<String, Error>
    where F: FnOnce(&mut Client) -> Result<String, Error>
{
    let client_cell: MutexGuard<_> = CLIENT.lock().unwrap();

    // Try to set up the client if we haven't already.
    if client_cell.borrow().is_none() {
        *client_cell.borrow_mut() = Some(try!(Client::new()));
    }

    // Call the provided function.  I have to break out `result` separately
    // for mysterious reasons related to the borrow checker and global
    // mutable state.
    let result = match client_cell.borrow_mut().deref_mut() {
        &mut Some(ref mut client) => body(client),
        // We theoretically handed this just above, and exited if we
        // failed.
        &mut None => panic!("Should have a client, but we don't")
    };
    result
}

/// Fetch the value of an environment-variable-style credential.
pub fn var<S: AsRef<str>>(name: S) -> Result<String, Error> {
    with_client(|client| client.var(name))
}

/// Fetch the value of a file-style credential.
pub fn file<S: AsRef<Path>>(path: S) -> Result<String, Error> {
    with_client(|client| client.file(path))
}

#[cfg(test)]
mod test {
    use std::fs;
    use std::io::Read;
    use super::file;

    #[test]
    fn test_file() {
        // Some arbitrary file contents.
        let mut f = fs::File::open("Cargo.toml").unwrap();
        let mut expected = String::new();
        f.read_to_string(&mut expected).unwrap();

        assert_eq!(expected, file("Cargo.toml").unwrap());
        assert!(file("nosuchfile.txt").is_err());
    }
}
<commit_msg>Provide a Options struct for passing multiple options<commit_after>//! Access secure credentials at runtime with multiple backends.
//!
//! For more information, see [the
//! homepage](https://github.com/emk/credentials).
//!
//! ```
//! use credentials;
//! use std::env;
//!
//! env::set_var("PASSWORD", "secret");
//! assert_eq!("secret", credentials::var("PASSWORD").unwrap());
//! ```

#[macro_use]
extern crate hyper;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate regex;
extern crate rustc_serialize;
#[cfg(test)] #[macro_use]
extern crate yup_hyper_mock as hyper_mock;

use backend::Backend;
use errors::{ErrorNew, err};
use std::cell::RefCell;
use std::convert::AsRef;
use std::default::Default;
use std::ops::DerefMut;
use std::path::Path;
use std::sync::{Mutex, MutexGuard};

// Be very careful not to export any more of the Secretfile API than
// strictly necessary, because we don't want to stablize too much at this
// point.
pub use secretfile::{Secretfile, SecretfileKeys};
pub use errors::Error;

#[macro_use]
mod errors;

mod backend;
mod chained;
mod envvar;
mod secretfile;
mod vault;

/// Options which can be passed to `Client::new`.
pub struct Options {
    sf: Option<Secretfile>,
}

impl Default for Options {
    /// Create an `Options` object using the default values for each
    /// option.
    fn default() -> Options {
        Options {
            sf: None,
        }
    }
}

impl Options {
    /// Specify a `Secretfile` for the `Client` to use.  This takes `self`
    /// by value, so it consumes the `Options` structure it is called on,
    /// and returns a new one.
    pub fn secretfile(mut self, secretfile: Secretfile) -> Options {
        self.sf = Some(secretfile);
        self
    }
}

/// A client which fetches secrets.  Under normal circumstances, it's
/// usually easier to use the static `credentials::var` and
/// `credentials::file` methods instead, but you may need to use this to
/// customize behavior.
pub struct Client {
    sf: Secretfile,
    backend: chained::Client,
}

impl Client {
    /// Create a new client using the specified options.
    pub fn new(options: Options) -> Result<Client, Error> {
        let secretfile = match options.sf {
            Some(sf) => sf,
            None => try!(Secretfile::default()),
        };
        Ok(Client {
            sf: secretfile,
            backend: try!(chained::Client::default()),
        })
    }

    /// Create a new client using the default options.
    pub fn default() -> Result<Client, Error> {
        Client::new(Default::default())
    }

    /// Create a new client using the specified `Secretfile`.
    pub fn with_secretfile(secretfile: Secretfile) -> Result<Client, Error> {
        Client::new(Options::default().secretfile(secretfile))
    }

    /// Provide access to a copy of the Secretfile we're using.
    pub fn secretfile(&self) -> &Secretfile {
        &self.sf
    }

    /// Fetch the value of an environment-variable-style credential.
    pub fn var<S: AsRef<str>>(&mut self, name: S) -> Result<String, Error> {
        let name_ref = name.as_ref();
        trace!("getting secure credential {}", name_ref);
        self.backend.var(&self.sf, name_ref).map_err(|e| {
            let err = Error::credential(name_ref, e);
            warn!("{}", err);
            err
        })
    }

    /// Fetch the value of a file-style credential.
    pub fn file<S: AsRef<Path>>(&mut self, path: S) -> Result<String, Error> {
        let path_ref = path.as_ref();
        let path_str = try!(path_ref.to_str().ok_or_else(|| {
            Error::credential("(invalid path)", err!("Path is not valid Unicode"))
        }));
        trace!("getting secure credential {}", path_str);
        self.backend.file(&self.sf, path_str).map_err(|e| {
            let err = Error::credential(path_str, e);
            warn!("{}", err);
            err
        })
    }
}

lazy_static! {
    // Our shared global client, initialized by `lazy_static!` and
    // protected by a Mutex.
    //
    // Rust deliberately makes it a nuisance to use mutable global
    // variables.  In this case, the `Mutex` provides thread-safe locking,
    // the `RefCell` makes this assignable, and the `Option` makes this
    // optional.  This is a message from the language saying, "Really? A
    // mutable global that might be null? Have you really thought about
    // this?"  But the global default client is only for convenience, so
    // we're OK with it, at least so far.
    static ref CLIENT: Mutex<RefCell<Option<Client>>> =
        Mutex::new(RefCell::new(None));
}

/// Call `body` with the default global client, or return an error if we
/// can't allocate a default global client.
fn with_client<F>(body: F) -> Result<String, Error>
    where F: FnOnce(&mut Client) -> Result<String, Error>
{
    let client_cell: MutexGuard<_> = CLIENT.lock().unwrap();

    // Try to set up the client if we haven't already.
    if client_cell.borrow().is_none() {
        *client_cell.borrow_mut() = Some(try!(Client::default()));
    }

    // Call the provided function.  I have to break out `result` separately
    // for mysterious reasons related to the borrow checker and global
    // mutable state.
    let result = match client_cell.borrow_mut().deref_mut() {
        &mut Some(ref mut client) => body(client),
        // We theoretically handed this just above, and exited if we
        // failed.
        &mut None => panic!("Should have a client, but we don't")
    };
    result
}

/// Fetch the value of an environment-variable-style credential.
pub fn var<S: AsRef<str>>(name: S) -> Result<String, Error> {
    with_client(|client| client.var(name))
}

/// Fetch the value of a file-style credential.
pub fn file<S: AsRef<Path>>(path: S) -> Result<String, Error> {
    with_client(|client| client.file(path))
}

#[cfg(test)]
mod test {
    use std::fs;
    use std::io::Read;
    use super::file;

    #[test]
    fn test_file() {
        // Some arbitrary file contents.
        let mut f = fs::File::open("Cargo.toml").unwrap();
        let mut expected = String::new();
        f.read_to_string(&mut expected).unwrap();

        assert_eq!(expected, file("Cargo.toml").unwrap());
        assert!(file("nosuchfile.txt").is_err());
    }
}
<|endoftext|>


<commit_before>//! Rust binding to the [zstd library][zstd].
//!
//! This crate provides:
//!
//! * An [encoder](struct.Encoder.html) to compress data using zstd
//!   and send the output to another write.
//! * A [decoder](struct.Decoder.html) to read input data from a `Read`
//!   and decompress it.
//! * Convenient functions for common tasks.
//!
//! # Example
//!
//! ```no_run
//! extern crate zstd;
//!
//! use std::io;
//!
//! fn main() {
//! 	// Uncompress input and print the result.
//! 	zstd::stream::copy_decode(io::stdin(), io::stdout()).unwrap();
//! }
//! ```
//!
//! [zstd]: https://github.com/facebook/zstd
#![deny(missing_docs)]
extern crate libc;

mod ll;

pub mod stream;
pub mod block;
pub mod dict;

pub use stream::{Decoder, Encoder, decode_all, encode_all};

use std::io;
use std::ffi::CStr;

/// Parse the result code
///
/// Returns the number of bytes written if the code represents success,
/// or the error message otherwise.
fn parse_code(code: libc::size_t) -> Result<usize, io::Error> {
    unsafe {
        if ll::ZSTD_isError(code) == 0 {
            Ok(code as usize)
        } else {
            let msg = CStr::from_ptr(ll::ZSTD_getErrorName(code));
            let error = io::Error::new(io::ErrorKind::Other,
                                       msg.to_str().unwrap().to_string());
            Err(error)
        }
    }
}

// Some helper functions to write full-cycle tests.

#[cfg(test)]
fn test_cycle<F, G>(data: &[u8], f: F, g: G)
    where F: Fn(&[u8]) -> Vec<u8>,
          G: Fn(&[u8]) -> Vec<u8>
{
    let mid = f(data);
    let end = g(&mid);
    assert_eq!(data, &end[..]);
}

#[cfg(test)]
fn test_cycle_unwrap<F, G>(data: &[u8], f: F, g: G)
    where F: Fn(&[u8]) -> io::Result<Vec<u8>>,
          G: Fn(&[u8]) -> io::Result<Vec<u8>>
{
    test_cycle(data, |data| f(data).unwrap(), |data| g(data).unwrap())
}
<commit_msg>Update documentation<commit_after>//! Rust binding to the [zstd library][zstd].
//!
//! This crate provides:
//!
//! * An [encoder](stream/struct.Encoder.html) to compress data using zstd
//!   and send the output to another write.
//! * A [decoder](stream/struct.Decoder.html) to read input data from a `Read`
//!   and decompress it.
//! * Convenient functions for common tasks.
//!
//! # Example
//!
//! ```no_run
//! extern crate zstd;
//!
//! use std::io;
//!
//! fn main() {
//! 	// Uncompress input and print the result.
//! 	zstd::stream::copy_decode(io::stdin(), io::stdout()).unwrap();
//! }
//! ```
//!
//! [zstd]: https://github.com/facebook/zstd
#![deny(missing_docs)]
extern crate libc;

mod ll;

pub mod stream;
pub mod block;
pub mod dict;

#[doc(no_inline)]
pub use stream::{Decoder, Encoder, decode_all, encode_all};

use std::io;
use std::ffi::CStr;

/// Parse the result code
///
/// Returns the number of bytes written if the code represents success,
/// or the error message otherwise.
fn parse_code(code: libc::size_t) -> Result<usize, io::Error> {
    unsafe {
        if ll::ZSTD_isError(code) == 0 {
            Ok(code as usize)
        } else {
            let msg = CStr::from_ptr(ll::ZSTD_getErrorName(code));
            let error = io::Error::new(io::ErrorKind::Other,
                                       msg.to_str().unwrap().to_string());
            Err(error)
        }
    }
}

// Some helper functions to write full-cycle tests.

#[cfg(test)]
fn test_cycle<F, G>(data: &[u8], f: F, g: G)
    where F: Fn(&[u8]) -> Vec<u8>,
          G: Fn(&[u8]) -> Vec<u8>
{
    let mid = f(data);
    let end = g(&mid);
    assert_eq!(data, &end[..]);
}

#[cfg(test)]
fn test_cycle_unwrap<F, G>(data: &[u8], f: F, g: G)
    where F: Fn(&[u8]) -> io::Result<Vec<u8>>,
          G: Fn(&[u8]) -> io::Result<Vec<u8>>
{
    test_cycle(data, |data| f(data).unwrap(), |data| g(data).unwrap())
}
<|endoftext|>


<commit_before>use std::io::Write;

pub mod builder;

/// Tracks progress of a task
pub struct Progress {
    current: usize,
    total: usize,

    started: bool
}

impl Progress {
    /// Creates a new one
    pub fn new(current: usize, total: usize) -> Self {
        Progress { current: current, total: total, started: false }
    }

    /// Creates a new progress with default values.
    pub fn default() -> Self {
        Progress::new(0, 100)
    }

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

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

    pub fn increment(&mut self) -> &Self {
        if self.current < self.total {
            self.current += 1;
        }
        print_bar(self);
        self
    }

    pub fn decrement(&mut self) -> &Self {
        if self.current > 0 {
            self.current -= 1;
        }
        self
    }

    pub fn finished(&self) -> bool {
        self.current >= self.total
    }

    pub fn process(&self) -> u8 {
        (self.current * 100 / self.total) as u8
    }

    pub fn start(&mut self) -> &Self {
        self.started = true;
        self
    }
}

fn print_bar(p: &Progress) {
    let p_info = format!("{current} / {total} ({process})",
                         current = p.current(),
                         total   = p.total(),
                         process = p.process());
    let caption = "Progress";

    let bar_width  = 79 - p_info.len() - caption.len() - 3 - 2;
    let done_width = (bar_width * p.process() as usize) / 100;
    let todo_width = bar_width - done_width;
    let done_bar   = std::iter::repeat("#").take(done_width).collect::<String>();
    let todo_bar   = std::iter::repeat("-").take(todo_width).collect::<String>();
    let bar = format!("|{}{}|", done_bar, todo_bar);

    print!("{caption}: {bar} {info}\r",
           caption = caption, bar = bar, info = p_info);
    std::io::stdout().flush().unwrap();
}
<commit_msg>Progress: removed constructors and implement Default<commit_after>use std::io::Write;

pub mod builder;

/// Tracks progress of a task
pub struct Progress {
    current: usize,
    total: usize,

    started: bool
}

impl Default for Progress {
    fn default() -> Progress {
        builder::ProgressBuilder::default().build()
    }
}

impl Progress {
    pub fn current(&self) -> usize {
        self.current
    }

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

    pub fn increment(&mut self) -> &Self {
        if self.current < self.total {
            self.current += 1;
        }
        print_bar(self);
        self
    }

    pub fn decrement(&mut self) -> &Self {
        if self.current > 0 {
            self.current -= 1;
        }
        self
    }

    pub fn finished(&self) -> bool {
        self.current >= self.total
    }

    pub fn process(&self) -> u8 {
        (self.current * 100 / self.total) as u8
    }

    pub fn start(&mut self) -> &Self {
        self.started = true;
        self
    }
}

fn print_bar(p: &Progress) {
    let p_info = format!("{current} / {total} ({process})",
                         current = p.current(),
                         total   = p.total(),
                         process = p.process());
    let caption = "Progress";

    let bar_width  = 79 - p_info.len() - caption.len() - 3 - 2;
    let done_width = (bar_width * p.process() as usize) / 100;
    let todo_width = bar_width - done_width;
    let done_bar   = std::iter::repeat("#").take(done_width).collect::<String>();
    let todo_bar   = std::iter::repeat("-").take(todo_width).collect::<String>();
    let bar = format!("|{}{}|", done_bar, todo_bar);

    print!("{caption}: {bar} {info}\r",
           caption = caption, bar = bar, info = p_info);
    std::io::stdout().flush().unwrap();
}
<|endoftext|>


<commit_before>//! Please contact me on github and file any issues if you find some, I'm also open to PRs or other suggestions.
//!
//! Updated to Tera 0.10 / Serde 1.0 / Iron 0.5 !
//! Serde 0.9.0 to_value returns a `Result`, this means you need to handle the possiblity of a serialization failure.
//! If you just want to `unwrap()` there is an implementation of From<Value> for TemplateMode so `Template::new(path, value)`
//! works also.
//!
//! **update iron-tera-0.4.0**: If you build this crate with feature = "unstable" on the nightly compiler,
//! I've included a `TryFrom` impl to improve API ergonomics. Instead of
//! `TemplateMode::from_serial` use `value.try_into()`. This uses the `TryFrom` feature to return a fallible `Result`.
//!
//! ## Examples
//! The following is a complete working example that I've tested with serde 0.9.0, tera 0.7.0 and iron-tera 0.2.0
//!
//! ```ignore
//!   [dependencies]
//!   iron-tera = { version = "0.4.0" }  # optional:  features = [ "unstable" ]
//! ```
//!
//! Using `iron-tera` stable.
//! ```rust
//! extern crate tera;
//! extern crate iron;
//! extern crate router;
//! #[macro_use] extern crate serde_json;
//! #[macro_use] extern crate serde_derive;
//! extern crate iron_tera;
//!
//! # fn main() {
//! use iron::prelude::*;
//! use iron::status;
//! use router::Router;
//! use tera::Context;
//!
//! use iron_tera::{Template, TeraEngine}; // import TemplateMode to explicitly handle serialization errors
//! fn main() {
//!
//!     let mut router = Router::new();
//!     router.get("/context", context_handler, "context");
//!     router.get("/json", json_handler, "json");
//!
//!     let mut chain = Chain::new(router);
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//!
//!
//!     fn context_handler(_: &mut Request) -> IronResult<Response> {
//!         let mut resp = Response::new();
//!
//!         let mut context = Context::new();
//!         context.add("username", &"Bob");
//!         context.add("my_var", &"Thing"); // comment out to see alternate thing
//!         context.add("numbers", &vec![1, 2, 3]);
//!         context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!         // can use Template::new(path, TemplateMode::from_context(context)) or TemplateMode::from(context) also
//!         resp.set_mut(Template::new("users/profile.html", context))
//!             .set_mut(status::Ok);
//!         Ok(resp)
//!     }
//!     fn json_handler(_: &mut Request) -> IronResult<Response> {
//!         let mut resp = Response::new();
//!
//!         let blob = json!({
//!             "username": "John Doe",
//!             "my_var": "Thing",
//!             "numbers": [
//!                 "1",
//!                 "+44 2345678",
//!                 "3"
//!             ],
//!             "bio": "<script>alert('pwnd');</script>"
//!          });
//!         // you can use blob.try_into() and handle the `Result` explicitly (not shown here)
//!         // on the `unstable` feature of `iron-tera`
//!         resp.set_mut(Template::new("users/profile.html", blob))
//!             .set_mut(status::Ok);
//!         Ok(resp)
//!     }
//! }
//! # }
//! ```
//!
//! Creating a template from a struct
//!
//! ```ignore
//! // The following uses serde's Serialize
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//! // Rendering from a struct that implements Serialize
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     // You can use TemplateMode::from()
//!     resp.set_mut(Template::new("product.html", product))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
#![cfg_attr(feature = "unstable", feature(try_from))]

#![allow(dead_code)]
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate tera;
extern crate iron;
extern crate serde;
extern crate plugin;

use iron::{AfterMiddleware, status, typemap};
use iron::headers::ContentType;
use iron::modifier::Modifier;
use iron::prelude::*;

use plugin::Plugin;

use serde::ser::Serialize;
use serde_json::{Value, to_value};

#[cfg(feature = "unstable")]
use std::convert::{TryFrom, TryInto};
use std::convert::From;

use tera::{Context, Tera};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }

    #[cfg(feature = "unstable")]
    pub fn try_serialize<S: Serialize>(
        serializeable: S,
    ) -> Result<TemplateMode, serde_json::Error> {
        Ok(serializeable.try_into()?)
    }

    #[cfg(not(feature = "unstable"))]
    pub fn from_serial<S: Serialize>(serializeable: S) -> Result<TemplateMode, serde_json::Error> {
        Ok(TemplateMode::Serialized(to_value(serializeable)?))
    }
}

impl From<Context> for TemplateMode {
    fn from(context: Context) -> Self {
        TemplateMode::from_context(context)
    }
}

#[cfg(not(feature = "unstable"))]
impl From<Value> for TemplateMode {
    fn from(serializeable: Value) -> Self {
        TemplateMode::from_serial(serializeable).unwrap()
    }
}

#[cfg(feature = "unstable")]
impl<S> TryFrom<S> for TemplateMode
where
    S: Serialize,
{
    type Error = serde_json::Error;
    fn try_from(value: S) -> Result<Self, Self::Error> {
        from_serde(value)
    }
}

#[cfg(feature = "unstable")]
fn from_serde<S: Serialize>(serializeable: S) -> Result<TemplateMode, serde_json::Error> {
    Ok(TemplateMode::Serialized(to_value(serializeable)?))
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    #[cfg(not(feature = "unstable"))]
    pub fn new<T: Into<TemplateMode>, S: Into<String>>(name: S, mode: T) -> Template {
        Template {
            name: name.into(),
            mode: mode.into(),
        }
    }
    #[cfg(feature = "unstable")]
    pub fn new<S: Into<String>>(name: S, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice
    pub fn new<S: AsRef<str>>(dir: S) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir.as_ref()) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(
            |t| match t.mode {
                TemplateMode::TeraContext(ref context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(ref value) => Some(self.tera.render(&t.name, value)),
            },
        );
        match wrapper {
            Some(result) => {
                result
                    .map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

impl Plugin<Response> for TeraEngine {
    type Error = ();

    fn eval(resp: &mut Response) -> Result<Template, ()> {
        match resp.extensions.get::<TeraEngine>() {
            Some(t) => Ok(t.clone()),
            None => Err(()),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Template, TemplateMode, TeraEngine};
    use iron::prelude::*;
    use tera::Context;

    fn from_context_response() -> IronResult<Response> {
        let resp = Response::new();
        let mut context = Context::new();
        context.add("greeting", &"hi!");
        Ok(resp.set(
            Template::new("./test_template/users/foo.html", context),
        ))
    }

    #[test]
    fn test_from_context() {
        let mut resp = from_context_response().ok().expect("response expected");
        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name, "./test_template/users/foo.html".to_string());
                if let TemplateMode::TeraContext(context) = h.mode {
                    assert_eq!(
                        context
                            .as_json()
                            .unwrap()
                            .get("greeting")
                            .unwrap()
                            .as_str()
                            .unwrap(),
                        "hi!"
                    );
                } else {
                    panic!("TeraContext expected");
                }
            }
            _ => panic!("template expected"),
        }
    }
}
<commit_msg>give up on doctest<commit_after>//! Please contact me on github and file any issues if you find some, I'm also open to PRs or other suggestions.
//!
//! Updated to Tera 0.10 / Serde 1.0 / Iron 0.5 !
//! Serde 0.9.0 to_value returns a `Result`, this means you need to handle the possiblity of a serialization failure.
//! If you just want to `unwrap()` there is an implementation of From<Value> for TemplateMode so `Template::new(path, value)`
//! works also.
//!
//! **update iron-tera-0.4.0**: If you build this crate with feature = "unstable" on the nightly compiler,
//! I've included a `TryFrom` impl to improve API ergonomics. Instead of
//! `TemplateMode::from_serial` use `value.try_into()`. This uses the `TryFrom` feature to return a fallible `Result`.
//!
//! ## Examples
//! The following is a complete working example that I've tested with serde 0.9.0, tera 0.7.0 and iron-tera 0.2.0
//!
//! ```ignore
//!   [dependencies]
//!   iron-tera = { version = "0.4.0" }  # optional:  features = [ "unstable" ]
//! ```
//!
//! Using `iron-tera` stable.
//! ```ignore
//! extern crate tera;
//! extern crate iron;
//! extern crate router;
//! #[macro_use] extern crate serde_json;
//! #[macro_use] extern crate serde_derive;
//! extern crate iron_tera;
//!
//! use iron::prelude::*;
//! use iron::status;
//! use router::Router;
//! use tera::Context;
//!
//! use iron_tera::{Template, TeraEngine}; // import TemplateMode to explicitly handle serialization errors
//! fn main() {
//!
//!     let mut router = Router::new();
//!     router.get("/context", context_handler, "context");
//!     router.get("/json", json_handler, "json");
//!
//!     let mut chain = Chain::new(router);
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//!
//!
//!     fn context_handler(_: &mut Request) -> IronResult<Response> {
//!         let mut resp = Response::new();
//!
//!         let mut context = Context::new();
//!         context.add("username", &"Bob");
//!         context.add("my_var", &"Thing"); // comment out to see alternate thing
//!         context.add("numbers", &vec![1, 2, 3]);
//!         context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!         // can use Template::new(path, TemplateMode::from_context(context)) or TemplateMode::from(context) also
//!         resp.set_mut(Template::new("users/profile.html", context))
//!             .set_mut(status::Ok);
//!         Ok(resp)
//!     }
//!     fn json_handler(_: &mut Request) -> IronResult<Response> {
//!         let mut resp = Response::new();
//!
//!         let blob = json!({
//!             "username": "John Doe",
//!             "my_var": "Thing",
//!             "numbers": [
//!                 "1",
//!                 "+44 2345678",
//!                 "3"
//!             ],
//!             "bio": "<script>alert('pwnd');</script>"
//!          });
//!         // you can use blob.try_into() and handle the `Result` explicitly (not shown here)
//!         // on the `unstable` feature of `iron-tera`
//!         resp.set_mut(Template::new("users/profile.html", blob))
//!             .set_mut(status::Ok);
//!         Ok(resp)
//!     }
//! }
//! ```
//!
//! Creating a template from a struct
//!
//! ```ignore
//! // The following uses serde's Serialize
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//! // Rendering from a struct that implements Serialize
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     // You can use TemplateMode::from()
//!     resp.set_mut(Template::new("product.html", product))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
#![cfg_attr(feature = "unstable", feature(try_from))]

#![allow(dead_code)]
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate tera;
extern crate iron;
extern crate serde;
extern crate plugin;

use iron::{AfterMiddleware, status, typemap};
use iron::headers::ContentType;
use iron::modifier::Modifier;
use iron::prelude::*;

use plugin::Plugin;

use serde::ser::Serialize;
use serde_json::{Value, to_value};

#[cfg(feature = "unstable")]
use std::convert::{TryFrom, TryInto};
use std::convert::From;

use tera::{Context, Tera};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }

    #[cfg(feature = "unstable")]
    pub fn try_serialize<S: Serialize>(
        serializeable: S,
    ) -> Result<TemplateMode, serde_json::Error> {
        Ok(serializeable.try_into()?)
    }

    #[cfg(not(feature = "unstable"))]
    pub fn from_serial<S: Serialize>(serializeable: S) -> Result<TemplateMode, serde_json::Error> {
        Ok(TemplateMode::Serialized(to_value(serializeable)?))
    }
}

impl From<Context> for TemplateMode {
    fn from(context: Context) -> Self {
        TemplateMode::from_context(context)
    }
}

#[cfg(not(feature = "unstable"))]
impl From<Value> for TemplateMode {
    fn from(serializeable: Value) -> Self {
        TemplateMode::from_serial(serializeable).unwrap()
    }
}

#[cfg(feature = "unstable")]
impl<S> TryFrom<S> for TemplateMode
where
    S: Serialize,
{
    type Error = serde_json::Error;
    fn try_from(value: S) -> Result<Self, Self::Error> {
        from_serde(value)
    }
}

#[cfg(feature = "unstable")]
fn from_serde<S: Serialize>(serializeable: S) -> Result<TemplateMode, serde_json::Error> {
    Ok(TemplateMode::Serialized(to_value(serializeable)?))
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    #[cfg(not(feature = "unstable"))]
    pub fn new<T: Into<TemplateMode>, S: Into<String>>(name: S, mode: T) -> Template {
        Template {
            name: name.into(),
            mode: mode.into(),
        }
    }
    #[cfg(feature = "unstable")]
    pub fn new<S: Into<String>>(name: S, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice
    pub fn new<S: AsRef<str>>(dir: S) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir.as_ref()) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(
            |t| match t.mode {
                TemplateMode::TeraContext(ref context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(ref value) => Some(self.tera.render(&t.name, value)),
            },
        );
        match wrapper {
            Some(result) => {
                result
                    .map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

impl Plugin<Response> for TeraEngine {
    type Error = ();

    fn eval(resp: &mut Response) -> Result<Template, ()> {
        match resp.extensions.get::<TeraEngine>() {
            Some(t) => Ok(t.clone()),
            None => Err(()),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Template, TemplateMode, TeraEngine};
    use iron::prelude::*;
    use tera::Context;

    fn from_context_response() -> IronResult<Response> {
        let resp = Response::new();
        let mut context = Context::new();
        context.add("greeting", &"hi!");
        Ok(resp.set(
            Template::new("./test_template/users/foo.html", context),
        ))
    }

    #[test]
    fn test_from_context() {
        let mut resp = from_context_response().ok().expect("response expected");
        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name, "./test_template/users/foo.html".to_string());
                if let TemplateMode::TeraContext(context) = h.mode {
                    assert_eq!(
                        context
                            .as_json()
                            .unwrap()
                            .get("greeting")
                            .unwrap()
                            .as_str()
                            .unwrap(),
                        "hi!"
                    );
                } else {
                    panic!("TeraContext expected");
                }
            }
            _ => panic!("template expected"),
        }
    }
}
<|endoftext|>


<commit_before>/* Copyright 2015 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

#![feature(coerce_unsized)]
#![feature(std_panic)]
#![feature(recover)]

extern crate libc;
extern crate iup_sys;
extern crate kernel32;
extern crate smallvec;

#[cfg(windows)]
fn get_thread_id() -> isize {
    use kernel32::GetCurrentThreadId;
    unsafe { GetCurrentThreadId() as isize }
}

macro_rules! impl_control_traits {
    ($control:ident) => {
        unsafe impl Control for ::$control {
            fn handle(&self) -> *mut Ihandle {
                assert!(!self.0.get().is_null(), "attempted to use destroyed control");
                ::check_thread();
                self.0.get()
            }
        }

        unsafe impl UnwrapHandle for ::$control {
            fn try_unwrap_handle(self) -> Result<*mut Ihandle, Self> {
                assert!(!self.0.get().is_null(), "attempted to use destroyed control");
                self.0.try_unwrap().map_err(|handle_rc| ::$control(handle_rc))
            }
        }
    };
}

#[macro_use]
mod callbacks;
#[macro_use]
mod containers;

mod attributes;
mod button;
mod label;
mod dialog;
mod file_dlg;
mod handle_rc;

pub use dialog::{Dialog, ShowCallbackToken, ShowState};
pub use file_dlg::{FileDlg};
pub use button::Button;
pub use label::Label;
pub use containers::{Container, Fill, Hbox, Vbox, NumDiv, GridBox};
pub use callbacks::{CallbackAction, Event};

// With this layout, you can glob import this module's contents but selectively import the
// above types if you want.
pub mod common_attrs_cbs {
    pub use attributes::{CommonAttributes, TitleAttribute};
    pub use callbacks::{MenuCommonCallbacks, GetKillFocusCallbacks, EnterLeaveWindowCallbacks, ButtonCallback};
}

use std::ptr;
use std::sync::atomic::{AtomicIsize, Ordering, ATOMIC_ISIZE_INIT};
use libc::{c_char, c_int};
use iup_sys::*;

// returns false if a panic is pending, but cannot be propagated because the main loop level is too high
fn propagate_panic() -> bool {
    if callbacks::is_panic_pending() && main_loop_level() > 0 {
        exit_loop();
        return false;
    }
    if let Some(payload) = callbacks::take_panic_payload() {
        // TODO: once a new nightly is released, use this
        //::std::panic::propagate(payload);
        panic!(payload.downcast_ref::<String>().unwrap_or(&String::new()).clone());
    }
    true
}

/// Executes the user interaction until `exit_loop` is called or the last visible dialog is hidden.
///
/// If you cascade many calls to `main_loop`, there must be a `exit_loop` call for each cascade
/// level, as hiding all dialogs will close only one level. Call `main_loop_level` to obtain the
/// current level.
///
/// If `main_loop` is called without any visible dialogs and no active timers, the application will
/// hang, and it will not be possible to close the main loop. The process will have to be
/// interrupted by the system.
///
/// When the last visible dialog is hidden, the `exit_loop` function is automatically called,
/// causing the `main_loop` to return. To avoid that, call `set_lock_loop(true)` before hiding the
/// last dialog.
pub fn main_loop() {
    unsafe {
        iup_open();

        // Callbacks can be called before main_loop() ever is. If they have been and have
        // panicked, we need to panic without calling IupMainLoop(). (IupMainLoopLevel() will
        // be 0 in a callback if it is running before IupMainLoop() has been called.)
        if !propagate_panic() { return; }
        IupMainLoop();
        propagate_panic();
    }
}

pub fn main_loop_level() -> i32 {
    unsafe {
        IupMainLoopLevel()
    }
}

pub fn exit_loop() {
    unsafe {
        IupExitLoop();
    }
}

fn iup_open() {
    check_thread();
    unsafe {
        if IupOpen(ptr::null_mut(), ptr::null_mut()) == IUP_OPENED {
            return;
        }
        attributes::set_str_attribute(ptr::null_mut(), "UTF8MODE", "YES");
        attributes::set_str_attribute(ptr::null_mut(), "UTF8MODE_FILE", "YES");
    }
}

static THREAD_ID: AtomicIsize = ATOMIC_ISIZE_INIT;

fn check_thread() {
    let thread_id = get_thread_id();
    let prev = THREAD_ID.compare_and_swap(0, thread_id, Ordering::SeqCst);
    assert!(prev == 0 || prev == thread_id, "IUP/Clear Coat functions must be called from a single thread");
}

// Part of the contract of implementing this trait is that no invalid handle
// is returned. Either the handle will stay valid for the life of the object or
// the method will panic.
pub unsafe trait Control {
    fn handle(&self) -> *mut Ihandle;

    fn detach(&self) {
        unsafe { IupDetach(self.handle()); }
    }

    fn reparent(&self, new_parent: &Container, ref_child: Option<&Control>) -> Result<(), ()> {
        unsafe {
            let ref_child = ref_child.map(|c| c.handle()).unwrap_or(ptr::null_mut());
            if IupReparent(self.handle(), new_parent.handle(), ref_child) == IUP_NOERROR {
                Ok(())
            } else {
                Err(())
            }
        }
    }

    fn get_dialog(&self) -> Option<Dialog> {
        unsafe {
            let handle = IupGetDialog(self.handle());
            if handle == ptr::null_mut() {
                None
            } else {
                Some(Dialog::from_handle(handle))
            }
        }
    }
}

// If this wrapper has the only reference, it gives up shared ownership of the *mut Ihandle.
pub unsafe trait UnwrapHandle : Sized {
    fn try_unwrap_handle(self) -> Result<*mut Ihandle, Self>;
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ScreenPosition { // This is the name IUP uses: SCREENPOSITION attribute
    Absolute(i32),
    Left,
    Right,
    Top,
    Bottom,
    Center,
    MousePos,
    CenterParent,
    Current,
}

impl ScreenPosition {
    #[allow(dead_code)]
    fn from_int_x(i: c_int) -> ScreenPosition {
       match i {
           IUP_LEFT => ScreenPosition::Left,
           IUP_RIGHT => ScreenPosition::Right,
           IUP_CENTER => ScreenPosition::Center,
           IUP_MOUSEPOS => ScreenPosition::MousePos,
           IUP_CENTERPARENT => ScreenPosition::CenterParent,
           IUP_CURRENT => ScreenPosition::Current,
           _ => ScreenPosition::Absolute(i),
       }
    }

    #[allow(dead_code)]
    fn from_int_y(i: c_int) -> ScreenPosition {
       match i {
           IUP_TOP => ScreenPosition::Top,
           IUP_BOTTOM => ScreenPosition::Bottom,
           _ => Self::from_int_x(i),
       }
    }

    fn to_int(self) -> c_int {
        match self {
            ScreenPosition::Absolute(i) => i,
            ScreenPosition::Left => IUP_LEFT,
            ScreenPosition::Right => IUP_RIGHT,
            ScreenPosition::Top => IUP_TOP,
            ScreenPosition::Bottom => IUP_BOTTOM,
            ScreenPosition::Center => IUP_CENTER,
            ScreenPosition::MousePos => IUP_MOUSEPOS,
            ScreenPosition::CenterParent => IUP_CENTERPARENT,
            ScreenPosition::Current => IUP_CURRENT,
        }
    }
}

pub trait Popup : Control {
    fn popup(&self, x: ScreenPosition, y: ScreenPosition) -> Result<(), ()> {
        unsafe {
            if IupPopup(self.handle(), x.to_int(), y.to_int()) == IUP_NOERROR {
                Ok(())
            } else {
                Err(())
            }
        }
    }
}

#[derive(Copy,Clone)]
pub enum MouseButton {
    Button1,
    Button2,
    Button3,
    Button4,
    Button5,
}

impl MouseButton {
    fn from_int(i: c_int) -> MouseButton {
        match i {
            IUP_BUTTON1 => MouseButton::Button1,
            IUP_BUTTON2 => MouseButton::Button2,
            IUP_BUTTON3 => MouseButton::Button3,
            IUP_BUTTON4 => MouseButton::Button4,
            IUP_BUTTON5 => MouseButton::Button5,
            _ => panic!("unknown mouse button"),
        }
    }

    #[allow(dead_code)]
    fn to_int(self) -> c_int {
        match self {
            MouseButton::Button1 => IUP_BUTTON1,
            MouseButton::Button2 => IUP_BUTTON2,
            MouseButton::Button3 => IUP_BUTTON3,
            MouseButton::Button4 => IUP_BUTTON4,
            MouseButton::Button5 => IUP_BUTTON5,
        }
    }
}

#[derive(Clone)]
pub struct KeyboardMouseStatus {
    shift_pressed: bool,
    control_pressed: bool,
    alt_pressed: bool,
    sys_pressed: bool,
    button1_pressed: bool,
    button2_pressed: bool,
    button3_pressed: bool,
    button4_pressed: bool,
    button5_pressed: bool,
}

impl KeyboardMouseStatus {
    unsafe fn from_cstr(s: *const c_char) -> KeyboardMouseStatus {
        KeyboardMouseStatus {
            shift_pressed: iup_isshift(s),
            control_pressed: iup_iscontrol(s),
            alt_pressed: iup_isalt(s),
            sys_pressed: iup_issys(s),
            button1_pressed: iup_isbutton1(s),
            button2_pressed: iup_isbutton2(s),
            button3_pressed: iup_isbutton3(s),
            button4_pressed: iup_isbutton4(s),
            button5_pressed: iup_isbutton5(s),
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum VAlignment {
    Top,
    Center,
    Bottom,
}

impl VAlignment {
    fn from_str(s: &[u8]) -> VAlignment {
        match s {
            b"ATOP" => VAlignment::Top,
            b"ACENTER" => VAlignment::Center,
            b"ABOTTOM" => VAlignment::Bottom,
            _ => panic!("unknown VAlignment"),
        }
    }

    fn to_str(self) -> &'static str {
        match self {
            VAlignment::Top => "ATOP",
            VAlignment::Center => "ACENTER",
            VAlignment::Bottom => "ABOTTOM",
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum HAlignment {
    Left,
    Center,
    Right,
}

impl HAlignment {
    fn from_str(s: &[u8]) -> HAlignment {
        match s {
            b"ALEFT" => HAlignment::Left,
            b"ACENTER" => HAlignment::Center,
            b"ARIGHT" => HAlignment::Right,
            _ => panic!("unknown HAlignment"),
        }
    }

    fn to_str(self) -> &'static str {
        match self {
            HAlignment::Left => "ALEFT",
            HAlignment::Center => "ACENTER",
            HAlignment::Right => "ARIGHT",
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Orientation {
    Horizontal,
    Vertical,
}

impl Orientation {
    fn from_str(s: &[u8]) -> Orientation {
        match s {
            b"HORIZONTAL" => Orientation::Horizontal,
            b"VERTICAL" => Orientation::Vertical,
            _ => panic!("unknown Orientation"),
        }
    }

    fn to_str(self) -> &'static str {
        match self {
            Orientation::Horizontal => "HORIZONTAL",
            Orientation::Vertical => "VERTICAL",
        }
    }
}
<commit_msg>Re-export FileDialogType and FileExtFilter<commit_after>/* Copyright 2015 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

#![feature(coerce_unsized)]
#![feature(std_panic)]
#![feature(recover)]

extern crate libc;
extern crate iup_sys;
extern crate kernel32;
extern crate smallvec;

#[cfg(windows)]
fn get_thread_id() -> isize {
    use kernel32::GetCurrentThreadId;
    unsafe { GetCurrentThreadId() as isize }
}

macro_rules! impl_control_traits {
    ($control:ident) => {
        unsafe impl Control for ::$control {
            fn handle(&self) -> *mut Ihandle {
                assert!(!self.0.get().is_null(), "attempted to use destroyed control");
                ::check_thread();
                self.0.get()
            }
        }

        unsafe impl UnwrapHandle for ::$control {
            fn try_unwrap_handle(self) -> Result<*mut Ihandle, Self> {
                assert!(!self.0.get().is_null(), "attempted to use destroyed control");
                self.0.try_unwrap().map_err(|handle_rc| ::$control(handle_rc))
            }
        }
    };
}

#[macro_use]
mod callbacks;
#[macro_use]
mod containers;

mod attributes;
mod button;
mod label;
mod dialog;
mod file_dlg;
mod handle_rc;

pub use dialog::{Dialog, ShowCallbackToken, ShowState};
pub use file_dlg::{FileDlg, FileDialogType, FileExtFilter};
pub use button::Button;
pub use label::Label;
pub use containers::{Container, Fill, Hbox, Vbox, NumDiv, GridBox};
pub use callbacks::{CallbackAction, Event};

// With this layout, you can glob import this module's contents but selectively import the
// above types if you want.
pub mod common_attrs_cbs {
    pub use attributes::{CommonAttributes, TitleAttribute};
    pub use callbacks::{MenuCommonCallbacks, GetKillFocusCallbacks, EnterLeaveWindowCallbacks, ButtonCallback};
}

use std::ptr;
use std::sync::atomic::{AtomicIsize, Ordering, ATOMIC_ISIZE_INIT};
use libc::{c_char, c_int};
use iup_sys::*;

// returns false if a panic is pending, but cannot be propagated because the main loop level is too high
fn propagate_panic() -> bool {
    if callbacks::is_panic_pending() && main_loop_level() > 0 {
        exit_loop();
        return false;
    }
    if let Some(payload) = callbacks::take_panic_payload() {
        // TODO: once a new nightly is released, use this
        //::std::panic::propagate(payload);
        panic!(payload.downcast_ref::<String>().unwrap_or(&String::new()).clone());
    }
    true
}

/// Executes the user interaction until `exit_loop` is called or the last visible dialog is hidden.
///
/// If you cascade many calls to `main_loop`, there must be a `exit_loop` call for each cascade
/// level, as hiding all dialogs will close only one level. Call `main_loop_level` to obtain the
/// current level.
///
/// If `main_loop` is called without any visible dialogs and no active timers, the application will
/// hang, and it will not be possible to close the main loop. The process will have to be
/// interrupted by the system.
///
/// When the last visible dialog is hidden, the `exit_loop` function is automatically called,
/// causing the `main_loop` to return. To avoid that, call `set_lock_loop(true)` before hiding the
/// last dialog.
pub fn main_loop() {
    unsafe {
        iup_open();

        // Callbacks can be called before main_loop() ever is. If they have been and have
        // panicked, we need to panic without calling IupMainLoop(). (IupMainLoopLevel() will
        // be 0 in a callback if it is running before IupMainLoop() has been called.)
        if !propagate_panic() { return; }
        IupMainLoop();
        propagate_panic();
    }
}

pub fn main_loop_level() -> i32 {
    unsafe {
        IupMainLoopLevel()
    }
}

pub fn exit_loop() {
    unsafe {
        IupExitLoop();
    }
}

fn iup_open() {
    check_thread();
    unsafe {
        if IupOpen(ptr::null_mut(), ptr::null_mut()) == IUP_OPENED {
            return;
        }
        attributes::set_str_attribute(ptr::null_mut(), "UTF8MODE", "YES");
        attributes::set_str_attribute(ptr::null_mut(), "UTF8MODE_FILE", "YES");
    }
}

static THREAD_ID: AtomicIsize = ATOMIC_ISIZE_INIT;

fn check_thread() {
    let thread_id = get_thread_id();
    let prev = THREAD_ID.compare_and_swap(0, thread_id, Ordering::SeqCst);
    assert!(prev == 0 || prev == thread_id, "IUP/Clear Coat functions must be called from a single thread");
}

// Part of the contract of implementing this trait is that no invalid handle
// is returned. Either the handle will stay valid for the life of the object or
// the method will panic.
pub unsafe trait Control {
    fn handle(&self) -> *mut Ihandle;

    fn detach(&self) {
        unsafe { IupDetach(self.handle()); }
    }

    fn reparent(&self, new_parent: &Container, ref_child: Option<&Control>) -> Result<(), ()> {
        unsafe {
            let ref_child = ref_child.map(|c| c.handle()).unwrap_or(ptr::null_mut());
            if IupReparent(self.handle(), new_parent.handle(), ref_child) == IUP_NOERROR {
                Ok(())
            } else {
                Err(())
            }
        }
    }

    fn get_dialog(&self) -> Option<Dialog> {
        unsafe {
            let handle = IupGetDialog(self.handle());
            if handle == ptr::null_mut() {
                None
            } else {
                Some(Dialog::from_handle(handle))
            }
        }
    }
}

// If this wrapper has the only reference, it gives up shared ownership of the *mut Ihandle.
pub unsafe trait UnwrapHandle : Sized {
    fn try_unwrap_handle(self) -> Result<*mut Ihandle, Self>;
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ScreenPosition { // This is the name IUP uses: SCREENPOSITION attribute
    Absolute(i32),
    Left,
    Right,
    Top,
    Bottom,
    Center,
    MousePos,
    CenterParent,
    Current,
}

impl ScreenPosition {
    #[allow(dead_code)]
    fn from_int_x(i: c_int) -> ScreenPosition {
       match i {
           IUP_LEFT => ScreenPosition::Left,
           IUP_RIGHT => ScreenPosition::Right,
           IUP_CENTER => ScreenPosition::Center,
           IUP_MOUSEPOS => ScreenPosition::MousePos,
           IUP_CENTERPARENT => ScreenPosition::CenterParent,
           IUP_CURRENT => ScreenPosition::Current,
           _ => ScreenPosition::Absolute(i),
       }
    }

    #[allow(dead_code)]
    fn from_int_y(i: c_int) -> ScreenPosition {
       match i {
           IUP_TOP => ScreenPosition::Top,
           IUP_BOTTOM => ScreenPosition::Bottom,
           _ => Self::from_int_x(i),
       }
    }

    fn to_int(self) -> c_int {
        match self {
            ScreenPosition::Absolute(i) => i,
            ScreenPosition::Left => IUP_LEFT,
            ScreenPosition::Right => IUP_RIGHT,
            ScreenPosition::Top => IUP_TOP,
            ScreenPosition::Bottom => IUP_BOTTOM,
            ScreenPosition::Center => IUP_CENTER,
            ScreenPosition::MousePos => IUP_MOUSEPOS,
            ScreenPosition::CenterParent => IUP_CENTERPARENT,
            ScreenPosition::Current => IUP_CURRENT,
        }
    }
}

pub trait Popup : Control {
    fn popup(&self, x: ScreenPosition, y: ScreenPosition) -> Result<(), ()> {
        unsafe {
            if IupPopup(self.handle(), x.to_int(), y.to_int()) == IUP_NOERROR {
                Ok(())
            } else {
                Err(())
            }
        }
    }
}

#[derive(Copy,Clone)]
pub enum MouseButton {
    Button1,
    Button2,
    Button3,
    Button4,
    Button5,
}

impl MouseButton {
    fn from_int(i: c_int) -> MouseButton {
        match i {
            IUP_BUTTON1 => MouseButton::Button1,
            IUP_BUTTON2 => MouseButton::Button2,
            IUP_BUTTON3 => MouseButton::Button3,
            IUP_BUTTON4 => MouseButton::Button4,
            IUP_BUTTON5 => MouseButton::Button5,
            _ => panic!("unknown mouse button"),
        }
    }

    #[allow(dead_code)]
    fn to_int(self) -> c_int {
        match self {
            MouseButton::Button1 => IUP_BUTTON1,
            MouseButton::Button2 => IUP_BUTTON2,
            MouseButton::Button3 => IUP_BUTTON3,
            MouseButton::Button4 => IUP_BUTTON4,
            MouseButton::Button5 => IUP_BUTTON5,
        }
    }
}

#[derive(Clone)]
pub struct KeyboardMouseStatus {
    shift_pressed: bool,
    control_pressed: bool,
    alt_pressed: bool,
    sys_pressed: bool,
    button1_pressed: bool,
    button2_pressed: bool,
    button3_pressed: bool,
    button4_pressed: bool,
    button5_pressed: bool,
}

impl KeyboardMouseStatus {
    unsafe fn from_cstr(s: *const c_char) -> KeyboardMouseStatus {
        KeyboardMouseStatus {
            shift_pressed: iup_isshift(s),
            control_pressed: iup_iscontrol(s),
            alt_pressed: iup_isalt(s),
            sys_pressed: iup_issys(s),
            button1_pressed: iup_isbutton1(s),
            button2_pressed: iup_isbutton2(s),
            button3_pressed: iup_isbutton3(s),
            button4_pressed: iup_isbutton4(s),
            button5_pressed: iup_isbutton5(s),
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum VAlignment {
    Top,
    Center,
    Bottom,
}

impl VAlignment {
    fn from_str(s: &[u8]) -> VAlignment {
        match s {
            b"ATOP" => VAlignment::Top,
            b"ACENTER" => VAlignment::Center,
            b"ABOTTOM" => VAlignment::Bottom,
            _ => panic!("unknown VAlignment"),
        }
    }

    fn to_str(self) -> &'static str {
        match self {
            VAlignment::Top => "ATOP",
            VAlignment::Center => "ACENTER",
            VAlignment::Bottom => "ABOTTOM",
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum HAlignment {
    Left,
    Center,
    Right,
}

impl HAlignment {
    fn from_str(s: &[u8]) -> HAlignment {
        match s {
            b"ALEFT" => HAlignment::Left,
            b"ACENTER" => HAlignment::Center,
            b"ARIGHT" => HAlignment::Right,
            _ => panic!("unknown HAlignment"),
        }
    }

    fn to_str(self) -> &'static str {
        match self {
            HAlignment::Left => "ALEFT",
            HAlignment::Center => "ACENTER",
            HAlignment::Right => "ARIGHT",
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Orientation {
    Horizontal,
    Vertical,
}

impl Orientation {
    fn from_str(s: &[u8]) -> Orientation {
        match s {
            b"HORIZONTAL" => Orientation::Horizontal,
            b"VERTICAL" => Orientation::Vertical,
            _ => panic!("unknown Orientation"),
        }
    }

    fn to_str(self) -> &'static str {
        match self {
            Orientation::Horizontal => "HORIZONTAL",
            Orientation::Vertical => "VERTICAL",
        }
    }
}
<|endoftext|>