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

// error-pattern:cargo-clippy
#![feature(plugin_registrar)]
#![feature(rustc_private)]
#![allow(clippy::missing_docs_in_private_items)]
#![warn(rust_2018_idioms)]

// FIXME: switch to something more ergonomic here, once available.
// (currently there is no way to opt into sysroot crates w/o `extern crate`)
#[allow(unused_extern_crates)]
extern crate rustc_plugin;
use self::rustc_plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry<'_>) {
    reg.sess.lint_store.with_read_lock(|lint_store| {
        for (lint, _, _) in lint_store.get_lint_groups() {
            reg.sess
                .struct_warn(
                    "the clippy plugin is being deprecated, please use cargo clippy or rls with the clippy feature",
                )
                .emit();
            if lint == "clippy" {
                // cargo clippy run on a crate that also uses the plugin
                return;
            }
        }
    });

    let conf = clippy_lints::read_conf(reg);
    clippy_lints::register_plugins(reg, &conf);
}

// only exists to let the dogfood integration test works.
// Don't run clippy as an executable directly
#[allow(dead_code)]
fn main() {
    panic!("Please use the cargo-clippy executable");
}
<commit_msg>Auto merge of #3564 - alexcrichton:rustc-driver, r=phansch<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:cargo-clippy
#![feature(plugin_registrar)]
#![feature(rustc_private)]
#![allow(clippy::missing_docs_in_private_items)]
#![warn(rust_2018_idioms)]

// FIXME: switch to something more ergonomic here, once available.
// (currently there is no way to opt into sysroot crates w/o `extern crate`)
#[allow(unused_extern_crates)]
extern crate rustc_driver;
#[allow(unused_extern_crates)]
extern crate rustc_plugin;
use self::rustc_plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry<'_>) {
    reg.sess.lint_store.with_read_lock(|lint_store| {
        for (lint, _, _) in lint_store.get_lint_groups() {
            reg.sess
                .struct_warn(
                    "the clippy plugin is being deprecated, please use cargo clippy or rls with the clippy feature",
                )
                .emit();
            if lint == "clippy" {
                // cargo clippy run on a crate that also uses the plugin
                return;
            }
        }
    });

    let conf = clippy_lints::read_conf(reg);
    clippy_lints::register_plugins(reg, &conf);
}

// only exists to let the dogfood integration test works.
// Don't run clippy as an executable directly
#[allow(dead_code)]
fn main() {
    panic!("Please use the cargo-clippy executable");
}
<|endoftext|>


<commit_before>#![feature(libc)]
#![feature(core)]
#![feature(debug_builders)]
extern crate libc;

pub mod instruction;
pub mod constants;
pub mod ffi;
pub mod capstone;

pub use instruction::*;
pub use constants::*;

pub use capstone::Capstone;

/// An opaque reference to a capstone engine.
///
/// bindgen by default used this type name everywhere, so it is easier to leave it with a confusing
/// name.
///
/// It should not be exported, rust's new visibility rules make tackling this not immediately
/// obvious
#[allow(non_camel_case_types)]
pub type csh = libc::size_t;
<commit_msg>Add demo as a test<commit_after>#![feature(libc)]
#![feature(core)]
#![feature(debug_builders)]
extern crate libc;

pub mod instruction;
pub mod constants;
pub mod ffi;
pub mod capstone;

pub use instruction::*;
pub use constants::*;

pub use capstone::Capstone;

/// An opaque reference to a capstone engine.
///
/// bindgen by default used this type name everywhere, so it is easier to leave it with a confusing
/// name.
///
/// It should not be exported, rust's new visibility rules make tackling this not immediately
/// obvious
#[allow(non_camel_case_types)]
pub type csh = libc::size_t;

#[cfg(test)]
mod test {
    use super::*;
    static CODE: &'static [u8] = b"\x55\x48\x8b\x05\xb8\x13\x00\x00";

    #[test]
    fn test_x86_simple() {
    match capstone::Capstone::new(constants::CsArch::ARCH_X86,
                                  constants::CsMode::MODE_64) {
        Some(cs) => {
            if let Some(insns) = cs.disasm(CODE, 0x1000, 0) {
                assert_eq!(insns.len(), 2);
                let is: Vec<_> = insns.iter().collect();
                assert_eq!(is[0].mnemonic().unwrap(), "push");
                assert_eq!(is[1].mnemonic().unwrap(), "mov");

                assert_eq!(is[0].address, 0x1000);
                assert_eq!(is[1].address, 0x1001);
            } else {
                assert!(false, "Couldn't disasm instructions")
            }
        },
        None => {
            assert!(false, "Couldn't create a cs engine");
        }
    }
}
}
<|endoftext|>


<commit_before>//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
//!
//! Without specialization, Rust forces Serde to treat `&[u8]` just like any
//! other slice and `Vec<u8>` just like any other vector. In reality this
//! particular slice and vector can often be serialized and deserialized in a
//! more efficient, compact representation in many formats.
//!
//! When working with such a format, you can opt into specialized handling of
//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
//! in `serde_bytes::ByteBuf`.
//!
//! This crate supports the Serde `with` attribute to enable efficient handling
//! of `&[u8]` and `Vec<u8>` in structs without needing a wrapper type.
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate serde;
//! extern crate serde_bytes;
//!
//! #[derive(Serialize)]
//! struct Efficient<'a> {
//!     #[serde(with = "serde_bytes")]
//!     bytes: &'a [u8],
//!
//!     #[serde(with = "serde_bytes")]
//!     byte_buf: Vec<u8>,
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Packet {
//!     #[serde(with = "serde_bytes")]
//!     payload: Vec<u8>,
//! }
//! #
//! # fn main() {}
//! ```
//!
//! Rust support for specialization is being tracked in [rust-lang/rust#31844].
//! Once it lands in the stable compiler Serde will be deprecating these wrapper
//! types in favor of optimizing `&[u8]` and `Vec<u8>` out of the box.
//!
//! [rust-lang/rust#31844]: https://github.com/rust-lang/rust/issues/31844

#![doc(html_root_url = "https://docs.rs/serde_bytes/0.10.1")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![deny(missing_docs)]

#[cfg(feature = "std")]
use std::{fmt, ops};

#[cfg(not(feature = "std"))]
use core::{fmt, ops};

use self::fmt::Debug;

#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::Vec;

#[macro_use]
extern crate serde;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Visitor, Error};

#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::bytebuf::ByteBuf;

mod value;

//////////////////////////////////////////////////////////////////////////////

/// Serde `serialize_with` function to serialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(serialize_with = "serde_bytes::serialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Serialize)]
/// struct Efficient<'a> {
///     #[serde(with = "serde_bytes")]
///     bytes: &'a [u8],
///
///     #[serde(with = "serde_bytes")]
///     byte_buf: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
    where T: AsRef<[u8]>,
          S: Serializer
{
    serializer.serialize_bytes(bytes.as_ref())
}

/// Serde `deserialize_with` function to deserialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Deserialize)]
/// struct Packet {
///     #[serde(with = "serde_bytes")]
///     payload: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where T: From<Vec<u8>>,
          D: Deserializer<'de>
{
    ByteBuf::deserialize(deserializer).map(|buf| Into::<Vec<u8>>::into(buf).into())
}

//////////////////////////////////////////////////////////////////////////////

/// Wrapper around `&[u8]` to serialize and deserialize efficiently.
///
/// ```rust
/// extern crate bincode;
/// extern crate serde_bytes;
///
/// use std::collections::HashMap;
/// use std::io;
///
/// use serde_bytes::Bytes;
///
/// fn print_encoded_cache() -> Result<(), bincode::Error> {
///     let mut cache = HashMap::new();
///     cache.insert(3, Bytes::new(b"three"));
///     cache.insert(2, Bytes::new(b"two"));
///     cache.insert(1, Bytes::new(b"one"));
///
///     bincode::serialize_into(&mut io::stdout(), &cache, bincode::Infinite)
/// }
/// #
/// # fn main() {
/// #     print_encoded_cache().unwrap();
/// # }
/// ```
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
    bytes: &'a [u8],
}

impl<'a> Bytes<'a> {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &'a [u8]) -> Self {
        Bytes { bytes: bytes }
    }
}

impl<'a> Debug for Bytes<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self.bytes, f)
    }
}

impl<'a> From<&'a [u8]> for Bytes<'a> {
    fn from(bytes: &'a [u8]) -> Self {
        Bytes::new(bytes)
    }
}

impl<'a> From<Bytes<'a>> for &'a [u8] {
    fn from(wrapper: Bytes<'a>) -> &'a [u8] {
        wrapper.bytes
    }
}

impl<'a> ops::Deref for Bytes<'a> {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        self.bytes
    }
}

impl<'a> Serialize for Bytes<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_bytes(self.bytes)
    }
}

struct BytesVisitor;

impl<'de> Visitor<'de> for BytesVisitor {
    type Value = Bytes<'de>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("byte array")
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v))
    }

    #[inline]
    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v.as_bytes()))
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for Bytes<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Bytes<'a>, D::Error>
        where D: Deserializer<'de>
    {
        deserializer.deserialize_bytes(BytesVisitor)
    }
}

//////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "alloc"))]
mod bytebuf {
    #[cfg(feature = "std")]
    use std::{cmp, fmt, ops};

    #[cfg(not(feature = "std"))]
    use core::{cmp, fmt, ops};

    use self::fmt::Debug;

    #[cfg(feature = "alloc")]
    use alloc::{String, Vec};

    use serde::ser::{Serialize, Serializer};
    use serde::de::{Deserialize, Deserializer, Visitor, SeqAccess, Error};

    /// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
    ///
    /// ```rust
    /// extern crate bincode;
    /// extern crate serde_bytes;
    ///
    /// use std::collections::HashMap;
    /// use std::io;
    ///
    /// use serde_bytes::ByteBuf;
    ///
    /// fn deserialize_bytebufs() -> Result<(), bincode::Error> {
    ///     let example_data = [
    ///         2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116,
    ///         119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101];
    ///
    ///     let map: HashMap<u32, ByteBuf> =
    ///         bincode::deserialize_from(&mut &example_data[..], bincode::Infinite)?;
    ///
    ///     println!("{:?}", map);
    ///
    ///     Ok(())
    /// }
    /// #
    /// # fn main() {
    /// #     deserialize_bytebufs().unwrap();
    /// # }
    /// ```
    #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
    pub struct ByteBuf {
        bytes: Vec<u8>,
    }

    impl ByteBuf {
        /// Construct a new, empty `ByteBuf`.
        pub fn new() -> Self {
            ByteBuf::from(Vec::new())
        }

        /// Construct a new, empty `ByteBuf` with the specified capacity.
        pub fn with_capacity(cap: usize) -> Self {
            ByteBuf::from(Vec::with_capacity(cap))
        }

        /// Wrap existing bytes in a `ByteBuf`.
        pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
            ByteBuf { bytes: bytes.into() }
        }
    }

    impl Debug for ByteBuf {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            Debug::fmt(&self.bytes, f)
        }
    }

    impl From<ByteBuf> for Vec<u8> {
        fn from(wrapper: ByteBuf) -> Vec<u8> {
            wrapper.bytes
        }
    }

    impl From<Vec<u8>> for ByteBuf {
        fn from(bytes: Vec<u8>) -> Self {
            ByteBuf::from(bytes)
        }
    }

    impl AsRef<Vec<u8>> for ByteBuf {
        fn as_ref(&self) -> &Vec<u8> {
            &self.bytes
        }
    }

    impl AsRef<[u8]> for ByteBuf {
        fn as_ref(&self) -> &[u8] {
            &self.bytes
        }
    }

    impl AsMut<Vec<u8>> for ByteBuf {
        fn as_mut(&mut self) -> &mut Vec<u8> {
            &mut self.bytes
        }
    }

    impl AsMut<[u8]> for ByteBuf {
        fn as_mut(&mut self) -> &mut [u8] {
            &mut self.bytes
        }
    }

    impl ops::Deref for ByteBuf {
        type Target = [u8];

        fn deref(&self) -> &[u8] {
            &self.bytes[..]
        }
    }

    impl ops::DerefMut for ByteBuf {
        fn deref_mut(&mut self) -> &mut [u8] {
            &mut self.bytes[..]
        }
    }

    impl Serialize for ByteBuf {
        #[inline]
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where S: Serializer
        {
            serializer.serialize_bytes(&self.bytes)
        }
    }

    struct ByteBufVisitor;

    impl<'de> Visitor<'de> for ByteBufVisitor {
        type Value = ByteBuf;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("byte array")
        }

        #[inline]
        fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
            where V: SeqAccess<'de>
        {
            let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
            let mut values = Vec::with_capacity(len);

            while let Some(value) = try!(visitor.next_element()) {
                values.push(value);
            }

            Ok(ByteBuf::from(values))
        }

        #[inline]
        fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }
    }

    impl<'de> Deserialize<'de> for ByteBuf {
        #[inline]
        fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
            where D: Deserializer<'de>
        {
            deserializer.deserialize_byte_buf(ByteBufVisitor)
        }
    }
}
<commit_msg>Tweak borrowed byte array error message<commit_after>//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
//!
//! Without specialization, Rust forces Serde to treat `&[u8]` just like any
//! other slice and `Vec<u8>` just like any other vector. In reality this
//! particular slice and vector can often be serialized and deserialized in a
//! more efficient, compact representation in many formats.
//!
//! When working with such a format, you can opt into specialized handling of
//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
//! in `serde_bytes::ByteBuf`.
//!
//! This crate supports the Serde `with` attribute to enable efficient handling
//! of `&[u8]` and `Vec<u8>` in structs without needing a wrapper type.
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate serde;
//! extern crate serde_bytes;
//!
//! #[derive(Serialize)]
//! struct Efficient<'a> {
//!     #[serde(with = "serde_bytes")]
//!     bytes: &'a [u8],
//!
//!     #[serde(with = "serde_bytes")]
//!     byte_buf: Vec<u8>,
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Packet {
//!     #[serde(with = "serde_bytes")]
//!     payload: Vec<u8>,
//! }
//! #
//! # fn main() {}
//! ```
//!
//! Rust support for specialization is being tracked in [rust-lang/rust#31844].
//! Once it lands in the stable compiler Serde will be deprecating these wrapper
//! types in favor of optimizing `&[u8]` and `Vec<u8>` out of the box.
//!
//! [rust-lang/rust#31844]: https://github.com/rust-lang/rust/issues/31844

#![doc(html_root_url = "https://docs.rs/serde_bytes/0.10.1")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![deny(missing_docs)]

#[cfg(feature = "std")]
use std::{fmt, ops};

#[cfg(not(feature = "std"))]
use core::{fmt, ops};

use self::fmt::Debug;

#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::Vec;

#[macro_use]
extern crate serde;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Visitor, Error};

#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::bytebuf::ByteBuf;

mod value;

//////////////////////////////////////////////////////////////////////////////

/// Serde `serialize_with` function to serialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(serialize_with = "serde_bytes::serialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Serialize)]
/// struct Efficient<'a> {
///     #[serde(with = "serde_bytes")]
///     bytes: &'a [u8],
///
///     #[serde(with = "serde_bytes")]
///     byte_buf: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
    where T: AsRef<[u8]>,
          S: Serializer
{
    serializer.serialize_bytes(bytes.as_ref())
}

/// Serde `deserialize_with` function to deserialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Deserialize)]
/// struct Packet {
///     #[serde(with = "serde_bytes")]
///     payload: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where T: From<Vec<u8>>,
          D: Deserializer<'de>
{
    ByteBuf::deserialize(deserializer).map(|buf| Into::<Vec<u8>>::into(buf).into())
}

//////////////////////////////////////////////////////////////////////////////

/// Wrapper around `&[u8]` to serialize and deserialize efficiently.
///
/// ```rust
/// extern crate bincode;
/// extern crate serde_bytes;
///
/// use std::collections::HashMap;
/// use std::io;
///
/// use serde_bytes::Bytes;
///
/// fn print_encoded_cache() -> Result<(), bincode::Error> {
///     let mut cache = HashMap::new();
///     cache.insert(3, Bytes::new(b"three"));
///     cache.insert(2, Bytes::new(b"two"));
///     cache.insert(1, Bytes::new(b"one"));
///
///     bincode::serialize_into(&mut io::stdout(), &cache, bincode::Infinite)
/// }
/// #
/// # fn main() {
/// #     print_encoded_cache().unwrap();
/// # }
/// ```
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
    bytes: &'a [u8],
}

impl<'a> Bytes<'a> {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &'a [u8]) -> Self {
        Bytes { bytes: bytes }
    }
}

impl<'a> Debug for Bytes<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self.bytes, f)
    }
}

impl<'a> From<&'a [u8]> for Bytes<'a> {
    fn from(bytes: &'a [u8]) -> Self {
        Bytes::new(bytes)
    }
}

impl<'a> From<Bytes<'a>> for &'a [u8] {
    fn from(wrapper: Bytes<'a>) -> &'a [u8] {
        wrapper.bytes
    }
}

impl<'a> ops::Deref for Bytes<'a> {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        self.bytes
    }
}

impl<'a> Serialize for Bytes<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_bytes(self.bytes)
    }
}

struct BytesVisitor;

impl<'de> Visitor<'de> for BytesVisitor {
    type Value = Bytes<'de>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a borrowed byte array")
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v))
    }

    #[inline]
    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v.as_bytes()))
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for Bytes<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Bytes<'a>, D::Error>
        where D: Deserializer<'de>
    {
        deserializer.deserialize_bytes(BytesVisitor)
    }
}

//////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "alloc"))]
mod bytebuf {
    #[cfg(feature = "std")]
    use std::{cmp, fmt, ops};

    #[cfg(not(feature = "std"))]
    use core::{cmp, fmt, ops};

    use self::fmt::Debug;

    #[cfg(feature = "alloc")]
    use alloc::{String, Vec};

    use serde::ser::{Serialize, Serializer};
    use serde::de::{Deserialize, Deserializer, Visitor, SeqAccess, Error};

    /// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
    ///
    /// ```rust
    /// extern crate bincode;
    /// extern crate serde_bytes;
    ///
    /// use std::collections::HashMap;
    /// use std::io;
    ///
    /// use serde_bytes::ByteBuf;
    ///
    /// fn deserialize_bytebufs() -> Result<(), bincode::Error> {
    ///     let example_data = [
    ///         2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116,
    ///         119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101];
    ///
    ///     let map: HashMap<u32, ByteBuf> =
    ///         bincode::deserialize_from(&mut &example_data[..], bincode::Infinite)?;
    ///
    ///     println!("{:?}", map);
    ///
    ///     Ok(())
    /// }
    /// #
    /// # fn main() {
    /// #     deserialize_bytebufs().unwrap();
    /// # }
    /// ```
    #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
    pub struct ByteBuf {
        bytes: Vec<u8>,
    }

    impl ByteBuf {
        /// Construct a new, empty `ByteBuf`.
        pub fn new() -> Self {
            ByteBuf::from(Vec::new())
        }

        /// Construct a new, empty `ByteBuf` with the specified capacity.
        pub fn with_capacity(cap: usize) -> Self {
            ByteBuf::from(Vec::with_capacity(cap))
        }

        /// Wrap existing bytes in a `ByteBuf`.
        pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
            ByteBuf { bytes: bytes.into() }
        }
    }

    impl Debug for ByteBuf {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            Debug::fmt(&self.bytes, f)
        }
    }

    impl From<ByteBuf> for Vec<u8> {
        fn from(wrapper: ByteBuf) -> Vec<u8> {
            wrapper.bytes
        }
    }

    impl From<Vec<u8>> for ByteBuf {
        fn from(bytes: Vec<u8>) -> Self {
            ByteBuf::from(bytes)
        }
    }

    impl AsRef<Vec<u8>> for ByteBuf {
        fn as_ref(&self) -> &Vec<u8> {
            &self.bytes
        }
    }

    impl AsRef<[u8]> for ByteBuf {
        fn as_ref(&self) -> &[u8] {
            &self.bytes
        }
    }

    impl AsMut<Vec<u8>> for ByteBuf {
        fn as_mut(&mut self) -> &mut Vec<u8> {
            &mut self.bytes
        }
    }

    impl AsMut<[u8]> for ByteBuf {
        fn as_mut(&mut self) -> &mut [u8] {
            &mut self.bytes
        }
    }

    impl ops::Deref for ByteBuf {
        type Target = [u8];

        fn deref(&self) -> &[u8] {
            &self.bytes[..]
        }
    }

    impl ops::DerefMut for ByteBuf {
        fn deref_mut(&mut self) -> &mut [u8] {
            &mut self.bytes[..]
        }
    }

    impl Serialize for ByteBuf {
        #[inline]
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where S: Serializer
        {
            serializer.serialize_bytes(&self.bytes)
        }
    }

    struct ByteBufVisitor;

    impl<'de> Visitor<'de> for ByteBufVisitor {
        type Value = ByteBuf;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("byte array")
        }

        #[inline]
        fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
            where V: SeqAccess<'de>
        {
            let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
            let mut values = Vec::with_capacity(len);

            while let Some(value) = try!(visitor.next_element()) {
                values.push(value);
            }

            Ok(ByteBuf::from(values))
        }

        #[inline]
        fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }
    }

    impl<'de> Deserialize<'de> for ByteBuf {
        #[inline]
        fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
            where D: Deserializer<'de>
        {
            deserializer.deserialize_byte_buf(ByteBufVisitor)
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate hyper;
extern crate serde_json;

use hyper::{Client, Error as HttpError, Url};
use serde_json::StreamDeserializer;
use std::io::Read;
use std::sync::mpsc::{channel, Receiver};
use std::thread;

include!(concat!(env!("OUT_DIR"), "/lib.rs"));

const DEFAULT_HOST: &'static str = "http://localhost:8001";

pub type Result<T> = std::result::Result<T, Error>;

/// An enumerator of potential errors
#[derive(Debug)]
pub enum Error {
    Transport(HttpError),
}

impl From<HttpError> for Error {
    fn from(error: HttpError) -> Error {
        Error::Transport(error)
    }
}

/// A cluster contains an address
/// for interacting with a kubernetes Cluster
/// of nodes
pub struct Cluster {
    host: Url,
}

/// Events provides a means for generating
/// a reciever for events
pub trait Events {
    fn events(&mut self) -> Result<Receiver<Event>>;

    fn generator<Iter>(&self, iter: Iter) -> Result<Receiver<Event>>
        where Iter: Iterator<Item = std::io::Result<u8>>,
              Iter: Send + 'static
    {
        let (tx, rx) = channel();
        let stream: StreamDeserializer<Event, _> = StreamDeserializer::new(iter);
        thread::spawn(move || {
            for e in stream {
                match e {
                    Ok(event) => {
                        if let Err(e) = tx.send(event) {
                            debug!("{:#?}", e);
                            break
                        }
                    },
                    Err(e) => {
                        debug!("{:#?}", e);
                        break
                    }
                }
            }
        });
        Ok(rx)
    }
}

impl Cluster {
    pub fn new() -> Cluster {
        Cluster { host: Url::parse(DEFAULT_HOST).unwrap() }
    }
}

impl Events for Cluster {
    fn events(&mut self) -> Result<Receiver<Event>> {
        let res = try!(Client::new()
            .get(self.host.join("/api/v1/events?watch=true").unwrap())
            .send());
        self.generator(res.bytes())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::mpsc::Receiver;
    use std::io::Read;
    #[test]
    fn events_generator() {
        impl Events for &'static str {
            fn events(&mut self) -> Result<Receiver<Event>> {
                self.generator(self.bytes().into_iter().map(|b| Ok(b)))
            }
        }
        let events = r#"{
            "object":{
                "apiVersion": "1",
                "count": 1,
                "firstTimestamp": "...",
                "lastTimestamp": "...",
                "kind":"Event",
                "message":"test",
                "involvedObject": {
                    "apiVersion": "1",
                    "kind": "POD",
                    "name": "test_name",
                    "namespace": "test_namespace"
                },
                "metadata": {
                    "creationTimestamp": "...",
                    "deletionTimestamp": "...",
                    "name": "test",
                    "namespace":"default",
                    "resourceVersion": "1",
                    "selfLink": "...",
                    "uid": "1"
                },
                "reason": "started",
                "source": {
                    "component": "test",
                    "host": "foo.com"
                },
                "type": "Normal"
            },
            "type":"ADDED"
        }"#.events();
        assert!(
            events.unwrap()
                .into_iter()
                .map(|e| e.object.involved_object.namespace)
                .nth(0)
                    == Some("test_namespace".to_owned())
        )
    }
}
<commit_msg>update docs<commit_after>//! # Scuttlebutt
//!
//! Scuttlebutt is an interface for consuming a stream of kubernetes
//! cluster events to act on

#[macro_use]
extern crate log;
extern crate hyper;
extern crate serde_json;

use hyper::{Client, Error as HttpError, Url};
use serde_json::StreamDeserializer;
use std::io::Read;
use std::sync::mpsc::{channel, Receiver};
use std::thread;

include!(concat!(env!("OUT_DIR"), "/lib.rs"));

const DEFAULT_HOST: &'static str = "http://localhost:8001";

pub type Result<T> = std::result::Result<T, Error>;

/// An enumeratation of potential errors
#[derive(Debug)]
pub enum Error {
    Transport(HttpError),
}

impl From<HttpError> for Error {
    fn from(error: HttpError) -> Error {
        Error::Transport(error)
    }
}

/// A cluster contains an address
/// for interacting with a kubernetes Cluster
/// of nodes
pub struct Cluster {
    host: Url,
}

/// Events provides a means for generating
/// a reciever for events
pub trait Events {
    fn events(&mut self) -> Result<Receiver<Event>>;

    fn generator<Iter>(&self, iter: Iter) -> Result<Receiver<Event>>
        where Iter: Iterator<Item = std::io::Result<u8>>,
              Iter: Send + 'static
    {
        let (tx, rx) = channel();
        let stream: StreamDeserializer<Event, _> = StreamDeserializer::new(iter);
        thread::spawn(move || {
            for e in stream {
                match e {
                    Ok(event) => {
                        if let Err(e) = tx.send(event) {
                            debug!("{:#?}", e);
                            break
                        }
                    },
                    Err(e) => {
                        debug!("{:#?}", e);
                        break
                    }
                }
            }
        });
        Ok(rx)
    }
}

impl Cluster {
    pub fn new() -> Cluster {
        Cluster { host: Url::parse(DEFAULT_HOST).unwrap() }
    }
}

impl Events for Cluster {
    fn events(&mut self) -> Result<Receiver<Event>> {
        let res = try!(Client::new()
            .get(self.host.join("/api/v1/events?watch=true").unwrap())
            .send());
        self.generator(res.bytes())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::mpsc::Receiver;
    use std::io::Read;
    #[test]
    fn events_generator() {
        impl Events for &'static str {
            fn events(&mut self) -> Result<Receiver<Event>> {
                self.generator(self.bytes().into_iter().map(|b| Ok(b)))
            }
        }
        let events = r#"{
            "object":{
                "apiVersion": "1",
                "count": 1,
                "firstTimestamp": "...",
                "lastTimestamp": "...",
                "kind":"Event",
                "message":"test",
                "involvedObject": {
                    "apiVersion": "1",
                    "kind": "POD",
                    "name": "test_name",
                    "namespace": "test_namespace"
                },
                "metadata": {
                    "creationTimestamp": "...",
                    "deletionTimestamp": "...",
                    "name": "test",
                    "namespace":"default",
                    "resourceVersion": "1",
                    "selfLink": "...",
                    "uid": "1"
                },
                "reason": "started",
                "source": {
                    "component": "test",
                    "host": "foo.com"
                },
                "type": "Normal"
            },
            "type":"ADDED"
        }"#.events();
        assert!(
            events.unwrap()
                .into_iter()
                .map(|e| e.object.involved_object.namespace)
                .nth(0)
                    == Some("test_namespace".to_owned())
        )
    }
}
<|endoftext|>


<commit_before>extern crate glob;
extern crate nix;
extern crate reqwest;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate toml;

#[macro_use]
extern crate lazy_static;

use std::ffi::CStr;
use std::io::{BufRead, Write};
extern crate libc;

mod structs;
use structs::Config;
mod ghclient;
mod buffer;
use buffer::Buffer;
mod cstructs;
use cstructs::{Group, Passwd, Spwd};
mod runfiles;
mod statics;
use statics::{CLIENT, CONFIG};

#[allow(dead_code)]
enum NssStatus {
    TryAgain,
    Unavail,
    NotFound,
    Success,
}

impl From<NssStatus> for libc::c_int {
    fn from(status: NssStatus) -> libc::c_int {
        match status {
            NssStatus::TryAgain => -2,
            NssStatus::Unavail => -1,
            NssStatus::NotFound => 0,
            NssStatus::Success => 1,
        }
    }
}

fn string_from(cstrptr: *const libc::c_char) -> String {
    let cstr: &CStr = unsafe { CStr::from_ptr(cstrptr) };
    String::from(cstr.to_str().unwrap())
}

macro_rules! succeed {
    ($ret_struct_p:ident,$ret_struct:ident) => {{
        unsafe { *$ret_struct_p = $ret_struct };
        return libc::c_int::from(NssStatus::Success);
    }};
    ($ret_struct_p:ident,$ret_struct:ident,$finalize:expr) => {{
        $finalize;
        unsafe { *$ret_struct_p = $ret_struct };
        return libc::c_int::from(NssStatus::Success);
    }}
}

macro_rules! fail {
    ($ret_struct_p:ident, $return_val:expr) => {{
        unsafe { *$ret_struct_p = std::ptr::null_mut() };
        return $return_val;
    }}
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getpwnam_r(cnameptr: *const libc::c_char, pwptr: *mut Passwd, buf: *mut libc::c_char,
                                         buflen: libc::size_t, pwptrp: *mut *mut Passwd)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    let name = string_from(cnameptr);
    for sector in CLIENT.get_sectors() {
        if let Some(member) = sector.members.get(&name) {
            match unsafe {
                      (*pwptr).pack_args(&mut buffer,
                                         &member.login,
                                         member.id,
                                         sector.get_gid(),
                                         &CONFIG)
                  } {
                Ok(_) => succeed!(pwptrp, pwptr),
                Err(_) => fail!(pwptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(pwptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getpwuid_r(uid: libc::uid_t, pwptr: *mut Passwd, buf: *mut libc::c_char,
                                         buflen: libc::size_t, pwptrp: *mut *mut Passwd)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    for sector in CLIENT.get_sectors() {
        for member in sector.members.values() {
            if uid == member.id as libc::uid_t {
                match unsafe {
                          (*pwptr).pack_args(&mut buffer,
                                             &member.login,
                                             member.id,
                                             sector.get_gid(),
                                             &CONFIG)
                      } {
                    Ok(_) => succeed!(pwptrp, pwptr),
                    Err(_) => fail!(pwptrp, nix::Errno::ERANGE as libc::c_int),
                }
            }
        }
    }
    fail!(pwptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_setpwent() -> libc::c_int {
    let mut list_file = match runfiles::create() {
        Ok(ret) => ret,
        Err(_) => return libc::c_int::from(NssStatus::Success),
    };
    for sector in CLIENT.get_sectors() {
        for member in sector.members.values() {
            list_file.write(format!("{}\t{}\t{}\n", member.login, member.id, sector.get_gid()).as_bytes())
                     .unwrap();
        }
    }
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getpwent_r(pwptr: *mut Passwd, buf: *mut libc::c_char, buflen: libc::size_t,
                                         pwptrp: *mut *mut Passwd)
                                         -> libc::c_int {
    let (idx, idx_file, list) = match runfiles::open() {
        Ok(ret) => ret,
        Err(_) => fail!(pwptrp, libc::c_int::from(NssStatus::Unavail)),
    };
    if let Some(Ok(line)) = list.lines().nth(idx) {
        let mut buffer = Buffer::new(buf, buflen);
        let words: Vec<&str> = line.split("\t").collect();
        let id = words[1].parse::<u64>().unwrap();
        let gid = words[2].parse::<u64>().unwrap();
        match unsafe { (*pwptr).pack_args(&mut buffer, words[0], id, gid, &CONFIG) } {
            Ok(_) => succeed!(pwptrp, pwptr, runfiles::increment(idx, idx_file)),
            Err(_) => fail!(pwptrp, nix::Errno::ERANGE as libc::c_int),
        }
    }
    fail!(pwptrp, libc::c_int::from(NssStatus::Unavail))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_endpwent() -> libc::c_int {
    runfiles::cleanup().unwrap_or(());
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getspnam_r(cnameptr: *const libc::c_char, spptr: *mut Spwd, buf: *mut libc::c_char,
                                         buflen: libc::size_t, spptrp: *mut *mut Spwd)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    let name = string_from(cnameptr);
    for sector in CLIENT.get_sectors() {
        if let Some(member) = sector.members.get(&name) {
            match unsafe { (*spptr).pack_args(&mut buffer, &member.login, &CONFIG) } {
                Ok(_) => succeed!(spptrp, spptr),
                Err(_) => fail!(spptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(spptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_setspent() -> libc::c_int {
    let mut list_file = match runfiles::create() {
        Ok(ret) => ret,
        Err(_) => return libc::c_int::from(NssStatus::Success),
    };
    for sector in CLIENT.get_sectors() {
        for member in sector.members.values() {
            list_file.write(format!("{}\t{}\n", member.login, member.id).as_bytes())
                     .unwrap();
        }
    }
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getspent_r(spptr: *mut Spwd, buf: *mut libc::c_char, buflen: libc::size_t,
                                         spptrp: *mut *mut Spwd)
                                         -> libc::c_int {
    let (idx, idx_file, list) = match runfiles::open() {
        Ok(ret) => ret,
        Err(_) => fail!(spptrp, libc::c_int::from(NssStatus::Unavail)),
    };
    if let Some(Ok(line)) = list.lines().nth(idx) {
        let mut buffer = Buffer::new(buf, buflen);
        let words: Vec<&str> = line.split("\t").collect();
        match unsafe { (*spptr).pack_args(&mut buffer, words[0], &CONFIG) } {
            Ok(_) => succeed!(spptrp, spptr, runfiles::increment(idx, idx_file)),
            Err(_) => fail!(spptrp, nix::Errno::ERANGE as libc::c_int),
        }
    }
    fail!(spptrp, libc::c_int::from(NssStatus::Unavail))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_endspent() -> libc::c_int {
    runfiles::cleanup().unwrap_or(());
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getgrgid_r(gid: libc::gid_t, grptr: *mut Group, buf: *mut libc::c_char,
                                         buflen: libc::size_t, grptrp: *mut *mut Group)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    for sector in CLIENT.get_sectors() {
        let members: Vec<&str> = sector.members.values().map(|m| m.login.as_str()).collect();
        if gid as u64 == sector.get_gid() {
            match unsafe { (*grptr).pack_args(&mut buffer, &sector.get_group(), gid as u64, &members) } {
                Ok(_) => succeed!(grptrp, grptr),
                Err(_) => fail!(grptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(grptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getgrnam_r(cnameptr: *const libc::c_char, grptr: *mut Group, buf: *mut libc::c_char,
                                         buflen: libc::size_t, grptrp: *mut *mut Group)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    let name = string_from(cnameptr);
    for sector in CLIENT.get_sectors() {
        let members: Vec<&str> = sector.members.values().map(|m| m.login.as_str()).collect();
        if name == sector.get_group() {
            match unsafe { (*grptr).pack_args(&mut buffer, &sector.get_group(), sector.get_gid(), &members) } {
                Ok(_) => succeed!(grptrp, grptr),
                Err(_) => fail!(grptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(grptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_setgrent() -> libc::c_int {
    let mut list_file = match runfiles::create() {
        Ok(ret) => ret,
        Err(_) => return libc::c_int::from(NssStatus::Success),
    };
    for sector in CLIENT.get_sectors() {
        let member_names = sector.members
                                 .values()
                                 .map(|x| x.login.as_str())
                                 .collect::<Vec<&str>>()
                                 .join(" ");
        list_file
            .write(
                format!(
                    "{}\t{}\t{}\n",
                    sector.get_group(),
                    sector.get_gid(),
                    member_names
                ).as_bytes(),
            )
            .unwrap();
    }
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getgrent_r(grptr: *mut Group, buf: *mut libc::c_char, buflen: libc::size_t,
                                         grptrp: *mut *mut Group)
                                         -> libc::c_int {
    let (idx, idx_file, list) = match runfiles::open() {
        Ok(ret) => ret,
        Err(_) => fail!(grptrp, libc::c_int::from(NssStatus::Unavail)),
    };
    if let Some(Ok(line)) = list.lines().nth(idx) {
        let mut buffer = Buffer::new(buf, buflen);
        let words: Vec<&str> = line.split("\t").collect();
        let member_names: Vec<&str> = words[2].split(" ").collect();
        let gid = words[1].parse::<u64>().unwrap();
        match unsafe { (*grptr).pack_args(&mut buffer, words[0], gid, &member_names) } {
            Ok(_) => succeed!(grptrp, grptr, runfiles::increment(idx, idx_file)),
            Err(_) => fail!(grptrp, nix::Errno::ERANGE as libc::c_int),
        }
    }
    fail!(grptrp, libc::c_int::from(NssStatus::Unavail))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_endgrent() -> libc::c_int {
    runfiles::cleanup().unwrap_or(());
    libc::c_int::from(NssStatus::Success)
}
<commit_msg>Avoid using unwrap<commit_after>extern crate glob;
extern crate nix;
extern crate reqwest;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate toml;

#[macro_use]
extern crate lazy_static;

use std::ffi::CStr;
use std::io::{BufRead, Write};
extern crate libc;

mod structs;
use structs::Config;
mod ghclient;
mod buffer;
use buffer::Buffer;
mod cstructs;
use cstructs::{Group, Passwd, Spwd};
mod runfiles;
mod statics;
use statics::{CLIENT, CONFIG};

#[allow(dead_code)]
enum NssStatus {
    TryAgain,
    Unavail,
    NotFound,
    Success,
}

impl From<NssStatus> for libc::c_int {
    fn from(status: NssStatus) -> libc::c_int {
        match status {
            NssStatus::TryAgain => -2,
            NssStatus::Unavail => -1,
            NssStatus::NotFound => 0,
            NssStatus::Success => 1,
        }
    }
}

fn string_from(cstrptr: *const libc::c_char) -> String {
    let cstr: &CStr = unsafe { CStr::from_ptr(cstrptr) };
    String::from(cstr.to_str().unwrap_or(""))
}

macro_rules! succeed {
    ($ret_struct_p:ident,$ret_struct:ident) => {{
        unsafe { *$ret_struct_p = $ret_struct };
        return libc::c_int::from(NssStatus::Success);
    }};
    ($ret_struct_p:ident,$ret_struct:ident,$finalize:expr) => {{
        $finalize;
        unsafe { *$ret_struct_p = $ret_struct };
        return libc::c_int::from(NssStatus::Success);
    }}
}

macro_rules! fail {
    ($ret_struct_p:ident, $return_val:expr) => {{
        unsafe { *$ret_struct_p = std::ptr::null_mut() };
        return $return_val;
    }}
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getpwnam_r(cnameptr: *const libc::c_char, pwptr: *mut Passwd, buf: *mut libc::c_char,
                                         buflen: libc::size_t, pwptrp: *mut *mut Passwd)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    let name = string_from(cnameptr);
    for sector in CLIENT.get_sectors() {
        if let Some(member) = sector.members.get(&name) {
            match unsafe {
                      (*pwptr).pack_args(&mut buffer,
                                         &member.login,
                                         member.id,
                                         sector.get_gid(),
                                         &CONFIG)
                  } {
                Ok(_) => succeed!(pwptrp, pwptr),
                Err(_) => fail!(pwptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(pwptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getpwuid_r(uid: libc::uid_t, pwptr: *mut Passwd, buf: *mut libc::c_char,
                                         buflen: libc::size_t, pwptrp: *mut *mut Passwd)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    for sector in CLIENT.get_sectors() {
        for member in sector.members.values() {
            if uid == member.id as libc::uid_t {
                match unsafe {
                          (*pwptr).pack_args(&mut buffer,
                                             &member.login,
                                             member.id,
                                             sector.get_gid(),
                                             &CONFIG)
                      } {
                    Ok(_) => succeed!(pwptrp, pwptr),
                    Err(_) => fail!(pwptrp, nix::Errno::ERANGE as libc::c_int),
                }
            }
        }
    }
    fail!(pwptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_setpwent() -> libc::c_int {
    let mut list_file = match runfiles::create() {
        Ok(ret) => ret,
        Err(_) => return libc::c_int::from(NssStatus::Success),
    };
    for sector in CLIENT.get_sectors() {
        for member in sector.members.values() {
            list_file.write(format!("{}\t{}\t{}\n", member.login, member.id, sector.get_gid()).as_bytes())
                     .unwrap();
        }
    }
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getpwent_r(pwptr: *mut Passwd, buf: *mut libc::c_char, buflen: libc::size_t,
                                         pwptrp: *mut *mut Passwd)
                                         -> libc::c_int {
    let (idx, idx_file, list) = match runfiles::open() {
        Ok(ret) => ret,
        Err(_) => fail!(pwptrp, libc::c_int::from(NssStatus::Unavail)),
    };
    if let Some(Ok(line)) = list.lines().nth(idx) {
        let mut buffer = Buffer::new(buf, buflen);
        let words: Vec<&str> = line.split("\t").collect();
        let id = words[1].parse::<u64>().unwrap();
        let gid = words[2].parse::<u64>().unwrap();
        match unsafe { (*pwptr).pack_args(&mut buffer, words[0], id, gid, &CONFIG) } {
            Ok(_) => succeed!(pwptrp, pwptr, runfiles::increment(idx, idx_file)),
            Err(_) => fail!(pwptrp, nix::Errno::ERANGE as libc::c_int),
        }
    }
    fail!(pwptrp, libc::c_int::from(NssStatus::Unavail))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_endpwent() -> libc::c_int {
    runfiles::cleanup().unwrap_or(());
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getspnam_r(cnameptr: *const libc::c_char, spptr: *mut Spwd, buf: *mut libc::c_char,
                                         buflen: libc::size_t, spptrp: *mut *mut Spwd)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    let name = string_from(cnameptr);
    for sector in CLIENT.get_sectors() {
        if let Some(member) = sector.members.get(&name) {
            match unsafe { (*spptr).pack_args(&mut buffer, &member.login, &CONFIG) } {
                Ok(_) => succeed!(spptrp, spptr),
                Err(_) => fail!(spptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(spptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_setspent() -> libc::c_int {
    let mut list_file = match runfiles::create() {
        Ok(ret) => ret,
        Err(_) => return libc::c_int::from(NssStatus::Success),
    };
    for sector in CLIENT.get_sectors() {
        for member in sector.members.values() {
            list_file.write(format!("{}\t{}\n", member.login, member.id).as_bytes())
                     .unwrap();
        }
    }
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getspent_r(spptr: *mut Spwd, buf: *mut libc::c_char, buflen: libc::size_t,
                                         spptrp: *mut *mut Spwd)
                                         -> libc::c_int {
    let (idx, idx_file, list) = match runfiles::open() {
        Ok(ret) => ret,
        Err(_) => fail!(spptrp, libc::c_int::from(NssStatus::Unavail)),
    };
    if let Some(Ok(line)) = list.lines().nth(idx) {
        let mut buffer = Buffer::new(buf, buflen);
        let words: Vec<&str> = line.split("\t").collect();
        match unsafe { (*spptr).pack_args(&mut buffer, words[0], &CONFIG) } {
            Ok(_) => succeed!(spptrp, spptr, runfiles::increment(idx, idx_file)),
            Err(_) => fail!(spptrp, nix::Errno::ERANGE as libc::c_int),
        }
    }
    fail!(spptrp, libc::c_int::from(NssStatus::Unavail))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_endspent() -> libc::c_int {
    runfiles::cleanup().unwrap_or(());
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getgrgid_r(gid: libc::gid_t, grptr: *mut Group, buf: *mut libc::c_char,
                                         buflen: libc::size_t, grptrp: *mut *mut Group)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    for sector in CLIENT.get_sectors() {
        let members: Vec<&str> = sector.members.values().map(|m| m.login.as_str()).collect();
        if gid as u64 == sector.get_gid() {
            match unsafe { (*grptr).pack_args(&mut buffer, &sector.get_group(), gid as u64, &members) } {
                Ok(_) => succeed!(grptrp, grptr),
                Err(_) => fail!(grptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(grptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getgrnam_r(cnameptr: *const libc::c_char, grptr: *mut Group, buf: *mut libc::c_char,
                                         buflen: libc::size_t, grptrp: *mut *mut Group)
                                         -> libc::c_int {
    let mut buffer = Buffer::new(buf, buflen);
    let name = string_from(cnameptr);
    for sector in CLIENT.get_sectors() {
        let members: Vec<&str> = sector.members.values().map(|m| m.login.as_str()).collect();
        if name == sector.get_group() {
            match unsafe { (*grptr).pack_args(&mut buffer, &sector.get_group(), sector.get_gid(), &members) } {
                Ok(_) => succeed!(grptrp, grptr),
                Err(_) => fail!(grptrp, nix::Errno::ERANGE as libc::c_int),
            }
        }
    }
    fail!(grptrp, libc::c_int::from(NssStatus::NotFound))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_setgrent() -> libc::c_int {
    let mut list_file = match runfiles::create() {
        Ok(ret) => ret,
        Err(_) => return libc::c_int::from(NssStatus::Success),
    };
    for sector in CLIENT.get_sectors() {
        let member_names = sector.members
                                 .values()
                                 .map(|x| x.login.as_str())
                                 .collect::<Vec<&str>>()
                                 .join(" ");
        list_file
            .write(
                format!(
                    "{}\t{}\t{}\n",
                    sector.get_group(),
                    sector.get_gid(),
                    member_names
                ).as_bytes(),
            )
            .unwrap();
    }
    libc::c_int::from(NssStatus::Success)
}

#[no_mangle]
pub extern "C" fn _nss_sectora_getgrent_r(grptr: *mut Group, buf: *mut libc::c_char, buflen: libc::size_t,
                                         grptrp: *mut *mut Group)
                                         -> libc::c_int {
    let (idx, idx_file, list) = match runfiles::open() {
        Ok(ret) => ret,
        Err(_) => fail!(grptrp, libc::c_int::from(NssStatus::Unavail)),
    };
    if let Some(Ok(line)) = list.lines().nth(idx) {
        let mut buffer = Buffer::new(buf, buflen);
        let words: Vec<&str> = line.split("\t").collect();
        let member_names: Vec<&str> = words[2].split(" ").collect();
        let gid = words[1].parse::<u64>().unwrap();
        match unsafe { (*grptr).pack_args(&mut buffer, words[0], gid, &member_names) } {
            Ok(_) => succeed!(grptrp, grptr, runfiles::increment(idx, idx_file)),
            Err(_) => fail!(grptrp, nix::Errno::ERANGE as libc::c_int),
        }
    }
    fail!(grptrp, libc::c_int::from(NssStatus::Unavail))
}

#[no_mangle]
pub extern "C" fn _nss_sectora_endgrent() -> libc::c_int {
    runfiles::cleanup().unwrap_or(());
    libc::c_int::from(NssStatus::Success)
}
<|endoftext|>


<commit_before>//#![warn(missing_doc)]
#![forbid(non_camel_case_types)]
#![feature(collections,core,hash,io)]

//! This crate currently provides almost XML 1.0/1.1-compliant pull parser.

extern crate core;

#[macro_use]
extern crate bitflags;

pub use reader::EventReader;

pub mod macros;
pub mod name;
pub mod attribute;
pub mod common;
pub mod escape;
pub mod namespace;
pub mod reader;
pub mod writer;
pub mod util;
<commit_msg>Fixed more warnings<commit_after>//#![warn(missing_doc)]
#![forbid(non_camel_case_types)]
#![feature(collections, core, hash, io, std_misc)]

//! This crate currently provides almost XML 1.0/1.1-compliant pull parser.

extern crate core;

#[macro_use]
extern crate bitflags;

pub use reader::EventReader;

pub mod macros;
pub mod name;
pub mod attribute;
pub mod common;
pub mod escape;
pub mod namespace;
pub mod reader;
pub mod writer;
pub mod util;
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

enum Object<'a> {
    Entity(u64),
    Literal(Literal<'a>)
}

enum Literal<'a> {
    LangLiteral(&'a str, LangTag<'a>),
    StringLiteral(&'a str),
    BooleanLiteral(bool),
    LongLiteral(i64),
    DoubleLiteral(f64),
}

struct LangTag<'a> {
    langTag: &'a str
}

struct Predicate<'a> {
    predicate: &'a str,
}

enum Range {
    LangLiteralRange(Literal::LangLiteral, Literal::LangLiteral),
    StringLiteralRange(Literal::StringLiteral, Literal::StringLiteral),
    LongLiteralRange(Literal::LongLiteral, Literal::LongLiteral),
    DoubleLiteralRange(Literal::DoubleLiteral, Literal::DoubleLiteral),
}

struct Statement<'a> {
    subject: Entity,
    predicate: Predicate<'a>,
    object: Object<'a>,
    context: Entity,
}

pub const A: Predicate = Predicate("_a");
pub const DEFAULT: Entity = Object::Entity(0);

struct CollectionName<'a> {
    name: &'a str
}

trait LigatureStore {
    fn readTx() -> ReadTx;
    fn writeTx() -> WriteTx;
//     fn <T>compute(fun: suspend (ReadTx) -> T): T {
// val readTx = this.readTx()
// try {
// return fn(readTx)
// } finally {
// if (readTx.is_open()) {
// readTx.cancel()
// }
// }
//}

// fn write(fn: suspend (WriteTx) -> Unit) {
// val writeTx = this.writeTx()
// try {
// return fn(writeTx)
// } finally {
// if (writeTx.is_open()) {
// writeTx.commit()
// }
// }
// }

    /**
     * Close connection with the Store.
     */
    fn close();

    fn isOpen() -> bool;
}

trait ReadTx {
    /**
     * Returns a Flow of all existing collections.
     */
    fn collections() -> Stream<CollectionName>;

    /**
     * Returns a Flow of all existing collections that start with the given prefix.
     */
    fn collections_prefix(prefix: CollectionName) -> Flow<CollectionName>

    /**
     * Returns a Flow of all existing collections that are within the given range.
     * `from` is inclusive and `to` is exclusive.
     */
    fn collections_range(from: CollectionName, to: CollectionName) -> Flow<CollectionName>

    /**
     * Accepts nothing but returns a Flow of all Statements in the Collection.
     */
    fn all_statements(collection: CollectionName) -> Flow<Statement>

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements(collection: CollectionName, subject: Entity? = null, predicate: Predicate? = null, `object`: Object? = null, context: Entity? = null) -> Flow<Statement>

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements_range(collection: CollectionName, subject: Entity? = null, predicate: Predicate? = null, range: Range<*>, context: Entity? = null) -> Flow<Statement>

    /**
     * Cancels this transaction.
     */
    fn cancel();

    fn is_open() -> bool;
}

trait WriteTx {
    /**
     * Creates a collection with the given name or does nothing if the collection already exists.
     * Only useful for creating an empty collection.
     */
    fn create_collection(collection: CollectionName);

    /**
     * Deletes the collection of the name given and does nothing if the collection doesn't exist.
     */
    fn delete_collection(collection: CollectionName);

    /**
     * Returns a new, unique to this collection identifier in the form _:NUMBER
     */
    fn new_entity(collection: CollectionName) -> Entity;
    fn add_statement(collection: CollectionName, statement: Statement);
    fn remove_statement(collection: CollectionName, statement: Statement);

    /**
     * Commits this transaction.
     */
    fn commit();

    /**
     * Cancels this transaction.
     */
    fn cancel();

    fn is_open() -> bool;
}

/**
 * Accepts a String representing an identifier and returns true or false depending on if it is valid.
 */
fn valid_predicate(identifier: String) -> bool {
    return "[a-zA-Z_][^\\s\\(\\)\\[\\]\\{\\}'\"`<>\\\\]*".toRegex().matches(identifier)
}

/**
 * Accepts a String representing a lang tag and returns true or false depending on if it is valid.
 */
fn valid_lang_tag(langTag: String) -> bool {
    return "[a-zA-Z]+(-[a-zA-Z0-9]+)*".toRegex().matches(langTag)
}

#[cfg(test)]
mod tests {
    #[test]
    fn valid_identifier_tests() {
        assert_eq(valid_predicate(""), false);
        assert_eq(valid_predicate("http://localhost/people/7"), true);
        assert_eq(valid_predicate("http://localhost(/people/7"), false);
        assert_eq(valid_predicate("http://localhost /people/7"), false);
        assert_eq(valid_predicate("hello"), true);
        assert_eq(valid_predicate("_:"), true);
        assert_eq(valid_predicate("_:valid"), true);
        assert_eq(valid_predicate("_:1"), true);
        assert_eq(valid_predicate("_:1344"), true);
    }

    #[test]
    fn valid_lang_tag_tests() {
        assert_eq(valid_lang_tag(""), false);
        assert_eq(valid_lang_tag("en"), true);
        assert_eq(valid_lang_tag("en-"), false);
        assert_eq(valid_lang_tag("en-fr"), true);
        assert_eq(valid_lang_tag("en-fr-"), false);
        assert_eq(valid_lang_tag("en-fr-sp"), true);
        assert_eq(valid_lang_tag("ennnenefnk-dkfjkjfl-dfakjelfkjalkf-fakjeflkajlkfj"), true);
        assert_eq(valid_lang_tag("en-fr-ef "), false);
    }
}
<commit_msg>cleaning up names some more and types, #100<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

enum Object<'a> {
    Entity(u64),
    Literal(Literal<'a>)
}

enum Literal<'a> {
    LangLiteral(&'a str, LangTag<'a>),
    StringLiteral(&'a str),
    BooleanLiteral(bool),
    LongLiteral(i64),
    DoubleLiteral(f64),
}

struct LangTag<'a> {
    lang_tag: &'a str
}

struct Predicate<'a> {
    predicate: &'a str,
}

enum Range {
    LangLiteralRange(Literal::LangLiteral, Literal::LangLiteral),
    StringLiteralRange(Literal::StringLiteral, Literal::StringLiteral),
    LongLiteralRange(Literal::LongLiteral, Literal::LongLiteral),
    DoubleLiteralRange(Literal::DoubleLiteral, Literal::DoubleLiteral),
}

struct Statement<'a> {
    subject: Entity,
    predicate: Predicate<'a>,
    object: Object<'a>,
    context: Entity,
}

pub const A: Predicate = Predicate("_a");
pub const DEFAULT: Entity = Object::Entity(0);

struct CollectionName<'a> {
    name: &'a str
}

trait LigatureStore {
    fn read_tx() -> dyn ReadTx;
    fn write_tx() -> dyn WriteTx;
//     fn <T>compute(fun: suspend (ReadTx) -> T): T {
// val readTx = this.readTx()
// try {
// return fn(readTx)
// } finally {
// if (readTx.is_open()) {
// readTx.cancel()
// }
// }
//}

// fn write(fn: suspend (WriteTx) -> Unit) {
// val writeTx = this.writeTx()
// try {
// return fn(writeTx)
// } finally {
// if (writeTx.is_open()) {
// writeTx.commit()
// }
// }
// }

    /**
     * Close connection with the Store.
     */
    fn close();

    fn is_open() -> bool;
}

trait ReadTx {
    /**
     * Returns a Flow of all existing collections.
     */
    fn collections() -> Stream<CollectionName>;

    /**
     * Returns a Flow of all existing collections that start with the given prefix.
     */
    fn collections_prefix(prefix: CollectionName) -> Flow<CollectionName>

    /**
     * Returns a Flow of all existing collections that are within the given range.
     * `from` is inclusive and `to` is exclusive.
     */
    fn collections_range(from: CollectionName, to: CollectionName) -> Flow<CollectionName>

    /**
     * Accepts nothing but returns a Flow of all Statements in the Collection.
     */
    fn all_statements(collection: CollectionName) -> Flow<Statement>

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements(collection: CollectionName, subject: Option<Entity>, predicate: Option<Predicate>, object: Option<Object>, context: Option<Entity>) -> Stream<Statement>

    /**
     * Is passed a pattern and returns a seq with all matching Statements.
     */
    fn match_statements_range(collection: CollectionName, subject: Option<Entity>, predicate: Option<Predicate>, range: Option<Range>, context: Option<Entity>) -> Stream<Statement>

    /**
     * Cancels this transaction.
     */
    fn cancel();

    fn is_open() -> bool;
}

trait WriteTx {
    /**
     * Creates a collection with the given name or does nothing if the collection already exists.
     * Only useful for creating an empty collection.
     */
    fn create_collection(collection: CollectionName);

    /**
     * Deletes the collection of the name given and does nothing if the collection doesn't exist.
     */
    fn delete_collection(collection: CollectionName);

    /**
     * Returns a new, unique to this collection identifier in the form _:NUMBER
     */
    fn new_entity(collection: CollectionName) -> Entity;
    fn add_statement(collection: CollectionName, statement: Statement);
    fn remove_statement(collection: CollectionName, statement: Statement);

    /**
     * Commits this transaction.
     */
    fn commit();

    /**
     * Cancels this transaction.
     */
    fn cancel();

    fn is_open() -> bool;
}

/**
 * Accepts a String representing an identifier and returns true or false depending on if it is valid.
 */
fn valid_predicate(identifier: String) -> bool {
    return "[a-zA-Z_][^\\s\\(\\)\\[\\]\\{\\}'\"`<>\\\\]*".toRegex().matches(identifier)
}

/**
 * Accepts a String representing a lang tag and returns true or false depending on if it is valid.
 */
fn valid_lang_tag(lang_tag: String) -> bool {
    return "[a-zA-Z]+(-[a-zA-Z0-9]+)*".toRegex().matches(langTag)
}

#[cfg(test)]
mod tests {
    #[test]
    fn valid_identifier_tests() {
        assert_eq(valid_predicate(""), false);
        assert_eq(valid_predicate("http://localhost/people/7"), true);
        assert_eq(valid_predicate("http://localhost(/people/7"), false);
        assert_eq(valid_predicate("http://localhost /people/7"), false);
        assert_eq(valid_predicate("hello"), true);
        assert_eq(valid_predicate("_:"), true);
        assert_eq(valid_predicate("_:valid"), true);
        assert_eq(valid_predicate("_:1"), true);
        assert_eq(valid_predicate("_:1344"), true);
    }

    #[test]
    fn valid_lang_tag_tests() {
        assert_eq(valid_lang_tag(""), false);
        assert_eq(valid_lang_tag("en"), true);
        assert_eq(valid_lang_tag("en-"), false);
        assert_eq(valid_lang_tag("en-fr"), true);
        assert_eq(valid_lang_tag("en-fr-"), false);
        assert_eq(valid_lang_tag("en-fr-sp"), true);
        assert_eq(valid_lang_tag("ennnenefnk-dkfjkjfl-dfakjelfkjalkf-fakjeflkajlkfj"), true);
        assert_eq(valid_lang_tag("en-fr-ef "), false);
    }
}
<|endoftext|>


<commit_before>//! Implementation of the `Synth` struct for basic polyphonic, multi-oscillator envelope synthesis.

extern crate envelope as envelope_lib;
extern crate gaussian;
pub extern crate instrument;
extern crate panning;
extern crate pitch_calc as pitch;
extern crate time_calc as time;
extern crate rand;
extern crate sample;
extern crate utils;

pub use dynamic::Synth as Dynamic;
pub use envelope::{Envelope, Point};
pub use envelope::Trait as EnvelopeTrait;
pub use oscillator::{AmpEnvelope, FreqEnvelope, Oscillator, Waveform};
pub use synth::Synth;

pub mod dynamic;
pub mod envelope;
pub mod oscillator;
mod synth;

#[cfg(feature="dsp-chain")]
mod dsp_node;

#[cfg(feature="serde_serialization")]
mod serde;
<commit_msg>included `synth::Frames` in pub use so it is accessible for users<commit_after>//! Implementation of the `Synth` struct for basic polyphonic, multi-oscillator envelope synthesis.

extern crate envelope as envelope_lib;
extern crate gaussian;
pub extern crate instrument;
extern crate panning;
extern crate pitch_calc as pitch;
extern crate time_calc as time;
extern crate rand;
extern crate sample;
extern crate utils;

pub use dynamic::Synth as Dynamic;
pub use envelope::{Envelope, Point};
pub use envelope::Trait as EnvelopeTrait;
pub use oscillator::{AmpEnvelope, FreqEnvelope, Oscillator, Waveform};
pub use synth::{Synth, Frames};

pub mod dynamic;
pub mod envelope;
pub mod oscillator;
mod synth;

#[cfg(feature="dsp-chain")]
mod dsp_node;

#[cfg(feature="serde_serialization")]
mod serde;
<|endoftext|>


<commit_before>//! libc - Raw FFI bindings to platforms' system libraries
//!
//! [Documentation for other platforms][pd].
//!
//! [pd]: https://rust-lang.github.io/libc/#platform-specific-documentation
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![allow(
    renamed_and_removed_lints, // Keep this order.
    unknown_lints, // Keep this order.
    bad_style,
    overflowing_literals,
    improper_ctypes,
    // This lint is renamed but we run CI for old stable rustc so should be here.
    redundant_semicolon,
    redundant_semicolons
)]
#![cfg_attr(libc_deny_warnings, deny(warnings))]
// Attributes needed when building as part of the standard library
#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg, no_core))]
#![cfg_attr(libc_thread_local, feature(thread_local))]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
#![cfg_attr(
    any(feature = "rustc-dep-of-std", target_os = "redox"),
    feature(static_nobundle)
)]
#![cfg_attr(libc_const_extern_fn, feature(const_extern_fn))]

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::ops;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod switch;
        pub use switch::*;
    } else if #[cfg(target_os = "psp")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod psp;
        pub use psp::*;
    } else if #[cfg(target_os = "vxworks")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod vxworks;
        pub use vxworks::*;
    } else if #[cfg(target_os = "solid-asp3")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod solid;
        pub use solid::*;
    } else if #[cfg(unix)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod unix;
        pub use unix::*;
    } else if #[cfg(target_os = "hermit")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod hermit;
        pub use hermit::*;
    } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod sgx;
        pub use sgx::*;
    } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod wasi;
        pub use wasi::*;
    } else {
        // non-supported targets: empty...
    }
}
<commit_msg>kmc-solid: Change `target_os` to `solid_asp3`<commit_after>//! libc - Raw FFI bindings to platforms' system libraries
//!
//! [Documentation for other platforms][pd].
//!
//! [pd]: https://rust-lang.github.io/libc/#platform-specific-documentation
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![allow(
    renamed_and_removed_lints, // Keep this order.
    unknown_lints, // Keep this order.
    bad_style,
    overflowing_literals,
    improper_ctypes,
    // This lint is renamed but we run CI for old stable rustc so should be here.
    redundant_semicolon,
    redundant_semicolons
)]
#![cfg_attr(libc_deny_warnings, deny(warnings))]
// Attributes needed when building as part of the standard library
#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg, no_core))]
#![cfg_attr(libc_thread_local, feature(thread_local))]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
#![cfg_attr(
    any(feature = "rustc-dep-of-std", target_os = "redox"),
    feature(static_nobundle)
)]
#![cfg_attr(libc_const_extern_fn, feature(const_extern_fn))]

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::ops;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod switch;
        pub use switch::*;
    } else if #[cfg(target_os = "psp")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod psp;
        pub use psp::*;
    } else if #[cfg(target_os = "vxworks")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod vxworks;
        pub use vxworks::*;
    } else if #[cfg(target_os = "solid_asp3")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod solid;
        pub use solid::*;
    } else if #[cfg(unix)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod unix;
        pub use unix::*;
    } else if #[cfg(target_os = "hermit")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod hermit;
        pub use hermit::*;
    } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod sgx;
        pub use sgx::*;
    } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod wasi;
        pub use wasi::*;
    } else {
        // non-supported targets: empty...
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::num;
use std::str::FromStr;

#[derive(Debug)]
pub enum XYZError {
    IO(io::Error),
    IllegalState(String),
    Parse(num::ParseFloatError),
}

impl From<io::Error> for XYZError {
    fn from(err: io::Error) -> XYZError {
        XYZError::IO(err)
    }
}

impl From<num::ParseFloatError> for XYZError {
    fn from(err: num::ParseFloatError) -> XYZError {
        XYZError::Parse(err)
    }
}

pub struct Coordinate {
    pub x: f32,
    pub y: f32,
    pub z: f32
}

impl Coordinate {
    fn new(x: f32, y: f32, z: f32) -> Self {
        Coordinate{ x: x, y: y, z: z }
    }
}

pub struct Atom {
    pub serial: String,
    pub coordinate: Coordinate
}

impl Atom {
    fn new(serial: &str, coordinate: Coordinate) -> Self {
        Atom{ serial: String::from(serial), coordinate: coordinate }
    }
}

impl FromStr for Atom {
    type Err = XYZError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let splitted: Vec<&str> = s.split_whitespace().collect();
        if splitted.len() != 4 {
            return Err(XYZError::IllegalState(String::from("")));
        }
        let coordinate = try!(parse_coord(splitted[1], splitted[2], splitted[3]));
        Ok(Atom::new(splitted[0], coordinate))
    }
}

pub type Snapshot = (String, Vec<Atom>);

fn parse_coord(x_str: &str, y_str: &str, z_str: &str) -> Result<Coordinate, XYZError> {
    let x = try!(x_str.parse::<f32>());
    let y = try!(y_str.parse::<f32>());
    let z = try!(z_str.parse::<f32>());

    Ok(Coordinate::new(x,y,z))
}

pub fn read_xyz_line<R: io::BufRead>(reader: &mut R) -> Result<Atom, XYZError> {
    let mut buffer = String::new();
    try!(reader.read_line(&mut buffer));
    buffer.parse::<Atom>()
}

// fn collect_xyz<R: io::BufRead>(reader: &mut R, num: i32) -> Result<Vec<Atom>, XYZError> {
//     let mut vec = Vec::new();
//     for _ in 0..num {
//         match read_xyz_line(reader) {
//             Some(x) => vec.push(x),
//             _ => ()
//         };
//     }
//     vec
// }

// pub fn read_snapshot<R: io::BufRead>(mut reader: &mut R) -> Snapshot {
//     let mut buffer = String::new();
//     try!(reader.read_line(&mut buffer));
//     let num = i32::from_str(&buffer).unwrap(); // TODO try
//     reader.read_line(&mut buffer); // TODO try
//     (buffer.clone(), collect_xyz(reader, num))
// }

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Add a tiny test<commit_after>use std::io;
use std::num;
use std::str::FromStr;

#[derive(Debug)]
pub enum XYZError {
    IO(io::Error),
    IllegalState(String),
    Parse(num::ParseFloatError),
}

impl From<io::Error> for XYZError {
    fn from(err: io::Error) -> XYZError {
        XYZError::IO(err)
    }
}

impl From<num::ParseFloatError> for XYZError {
    fn from(err: num::ParseFloatError) -> XYZError {
        XYZError::Parse(err)
    }
}

#[derive(Debug, PartialEq)]
pub struct Coordinate {
    pub x: f32,
    pub y: f32,
    pub z: f32
}

impl Coordinate {
    fn new(x: f32, y: f32, z: f32) -> Self {
        Coordinate{ x: x, y: y, z: z }
    }
}

#[derive(Debug, PartialEq)]
pub struct Atom {
    pub serial: String,
    pub coordinate: Coordinate
}

impl Atom {
    fn new(serial: &str, coordinate: Coordinate) -> Self {
        Atom{ serial: String::from(serial), coordinate: coordinate }
    }
}

impl FromStr for Atom {
    type Err = XYZError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let splitted: Vec<&str> = s.split_whitespace().collect();
        if splitted.len() != 4 {
            return Err(XYZError::IllegalState(String::from("")));
        }
        let coordinate = try!(parse_coord(splitted[1], splitted[2], splitted[3]));
        Ok(Atom::new(splitted[0], coordinate))
    }
}

pub type Snapshot = (String, Vec<Atom>);

fn parse_coord(x_str: &str, y_str: &str, z_str: &str) -> Result<Coordinate, XYZError> {
    let x = try!(x_str.parse::<f32>());
    let y = try!(y_str.parse::<f32>());
    let z = try!(z_str.parse::<f32>());

    Ok(Coordinate::new(x,y,z))
}

pub fn read_xyz_line<R: io::BufRead>(reader: &mut R) -> Result<Atom, XYZError> {
    let mut buffer = String::new();
    try!(reader.read_line(&mut buffer));
    buffer.parse::<Atom>()
}

// fn collect_xyz<R: io::BufRead>(reader: &mut R, num: i32) -> Result<Vec<Atom>, XYZError> {
//     let mut vec = Vec::new();
//     for _ in 0..num {
//         match read_xyz_line(reader) {
//             Some(x) => vec.push(x),
//             _ => ()
//         };
//     }
//     vec
// }

// pub fn read_snapshot<R: io::BufRead>(mut reader: &mut R) -> Snapshot {
//     let mut buffer = String::new();
//     try!(reader.read_line(&mut buffer));
//     let num = i32::from_str(&buffer).unwrap(); // TODO try
//     reader.read_line(&mut buffer); // TODO try
//     (buffer.clone(), collect_xyz(reader, num))
// }

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

    #[test]
    fn test_parse_atom() {
        let success = "C 10.0 11.0 12.0".parse::<Atom>();
        assert!(success.is_ok());
        assert_eq!(
            Atom::new("C", Coordinate::new(10.0, 11.0, 12.0)),
            success.unwrap());

        let failure = "C 1.0 2.0 a".parse::<Atom>();
        assert!(failure.is_err());
    }
}
<|endoftext|>