<commit_before>use neb::ram::types;
use neb::ram::chunk;

pub const CHUNK_SIZE: usize = 2048;

macro_rules! test_nums {
    (
        $t:ident, $io:ident
    ) => (
        mod $t {
            use neb::ram::types;
            use neb::ram::chunk;
            use std;
            use rand;
            use super::CHUNK_SIZE;
            #[test]
            fn test () {
                let rand_num = rand::random::<$t>();
                let test_data = vec![std::$t::MIN, std::$t::MAX, rand_num, 0 as $t, 1 as $t, 2 as $t, 127 as $t];
                let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
                let counts = CHUNK_SIZE / types::$io::size(0) as usize;
                for d in test_data {
                    for i in 0..counts {
                        let addr = chunk.addr + i * types::$io::size(0);
                        types::$io::write(d, addr);
                        assert!(types::$io::read(addr) == d);
                    }
                    for i in 0..counts {
                        let addr = chunk.addr + i * types::$io::size(0);
                        assert!(types::$io::read(addr) == d);
                    }
                }
            }
        }
    );
}

test_nums!(i8, i8_io);
test_nums!(i16, i16_io);
test_nums!(i32, i32_io);
test_nums!(i64, i64_io);

test_nums!(u8, u8_io);
test_nums!(u16, u16_io);
test_nums!(u32, u32_io);
test_nums!(u64, u64_io);

test_nums!(isize, isize_io);
test_nums!(usize, usize_io);
test_nums!(f32, f32_io);
test_nums!(f64, f64_io);

mod pos2d32 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos2d32 {x: std::f32::MIN, y: std::f32::MAX},
            types::pos2d32 {x: rand::random::<f32>(), y: rand::random::<f32>()}
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        for d in test_data {
            types::pos2d32_io::write(&d, chunk.addr);
            assert!(types::pos2d32_io::read(chunk.addr) == d);
        }
    }
}

mod pos2d64 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos2d64 {x: std::f64::MIN, y: std::f64::MAX},
            types::pos2d64 {x: rand::random::<f64>(), y: rand::random::<f64>()}
        ];
        let chunk = &chunk::init(1, 2048).list[0];
        for d in test_data {
            types::pos2d64_io::write(&d, chunk.addr);
            assert!(types::pos2d64_io::read(chunk.addr) == d);
        }
    }
}

mod pos3d32 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos3d32 {x: std::f32::MIN, y: std::f32::MAX, z: rand::random::<f32>()},
            types::pos3d32 {x: rand::random::<f32>(), y: rand::random::<f32>(), z: rand::random::<f32>()}
        ];
        let chunk = &chunk::init(1, 2048).list[0];
        for d in test_data {
            types::pos3d32_io::write(&d, chunk.addr);
            assert!(types::pos3d32_io::read(chunk.addr) == d);
        }
    }
}

mod pos3d64 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos3d64 {x: std::f64::MIN, y: std::f64::MAX, z: rand::random::<f64>()},
            types::pos3d64 {x: rand::random::<f64>(), y: rand::random::<f64>(), z: rand::random::<f64>()}
        ];
        let chunk = &chunk::init(1, 2048).list[0];
        for d in test_data {
            types::pos3d64_io::write(&d, chunk.addr);
            assert!(types::pos3d64_io::read(chunk.addr) == d);
        }
    }
}

mod uuid {
    use neb::ram::types;
    use neb::ram::chunk;
    use uuid::Uuid;
    use uuid;
    #[test]
    fn test () {
        let test_data = vec![
            Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(),
            Uuid::new_v4(),
            Uuid::new_v5(&uuid::NAMESPACE_DNS, "foo")
        ];
        let chunk = &chunk::init(1, 2048).list[0];
        for d in test_data {
            types::uuid_io::write(&d, chunk.addr);
            assert!(types::uuid_io::read(chunk.addr) == d);
        }
    }
}

mod string {
    use neb::ram::types;
    use neb::ram::chunk;
    use std::string::String;
    #[test]
    fn test () {
        let test_data = vec![
            "", "ಬಾ ಇಲ್ಲಿ ಸಂಭವಿಸ", "中文测试文本", "Hello Test", "💖"
        ];
        let chunk = &chunk::init(1, 2048).list[0];
        for d in test_data {
            let test_str = String::from(d);
            types::string_io::write(&test_str, chunk.addr);
            assert!(types::string_io::read(chunk.addr) == test_str);
        }
    }
}<commit_msg>layout tests for compound types<commit_after>use neb::ram::types;
use neb::ram::chunk;

pub const CHUNK_SIZE: usize = 2048;

macro_rules! test_nums {
    (
        $t:ident, $io:ident
    ) => (
        mod $t {
            use neb::ram::types;
            use neb::ram::chunk;
            use std;
            use rand;
            use super::CHUNK_SIZE;
            #[test]
            fn test () {
                let rand_num = rand::random::<$t>();
                let test_data = vec![std::$t::MIN, std::$t::MAX, rand_num, 0 as $t, 1 as $t, 2 as $t, 127 as $t];
                let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
                let counts = CHUNK_SIZE / types::$io::size(0) as usize;
                for d in test_data {
                    for i in 0..counts {
                        let addr = chunk.addr + i * types::$io::size(0);
                        types::$io::write(d, addr);
                        assert!(types::$io::read(addr) == d);
                    }
                    for i in 0..counts {
                        let addr = chunk.addr + i * types::$io::size(0);
                        assert!(types::$io::read(addr) == d);
                    }
                }
            }
        }
    );
}

test_nums!(i8, i8_io);
test_nums!(i16, i16_io);
test_nums!(i32, i32_io);
test_nums!(i64, i64_io);

test_nums!(u8, u8_io);
test_nums!(u16, u16_io);
test_nums!(u32, u32_io);
test_nums!(u64, u64_io);

test_nums!(isize, isize_io);
test_nums!(usize, usize_io);
test_nums!(f32, f32_io);
test_nums!(f64, f64_io);

mod pos2d32 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos2d32 {x: std::f32::MIN, y: std::f32::MAX},
            types::pos2d32 {x: rand::random::<f32>(), y: rand::random::<f32>()}
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        let counts = CHUNK_SIZE / types::pos2d32_io::size(0) as usize;
        for d in test_data {
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos2d32_io::size(0);
                types::pos2d32_io::write(&d, addr);
                assert!(types::pos2d32_io::read(addr) == d);
            }
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos2d32_io::size(0);
                assert!(types::pos2d32_io::read(addr) == d);
            }
        }
    }
}

mod pos2d64 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos2d64 {x: std::f64::MIN, y: std::f64::MAX},
            types::pos2d64 {x: rand::random::<f64>(), y: rand::random::<f64>()}
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        let counts = CHUNK_SIZE / types::pos2d64_io::size(0) as usize;
        for d in test_data {
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos2d64_io::size(0);
                types::pos2d64_io::write(&d, addr);
                assert!(types::pos2d64_io::read(addr) == d);
            }
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos2d64_io::size(0);
                assert!(types::pos2d64_io::read(addr) == d);
            }
        }
    }
}

mod pos3d32 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos3d32 {x: std::f32::MIN, y: std::f32::MAX, z: rand::random::<f32>()},
            types::pos3d32 {x: rand::random::<f32>(), y: rand::random::<f32>(), z: rand::random::<f32>()}
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        let counts = CHUNK_SIZE / types::pos3d32_io::size(0) as usize;
        for d in test_data {
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos3d32_io::size(0);
                types::pos3d32_io::write(&d, addr);
                assert!(types::pos3d32_io::read(addr) == d);
            }
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos3d32_io::size(0);
                assert!(types::pos3d32_io::read(addr) == d);
            }
        }
    }
}

mod pos3d64 {
    use neb::ram::types;
    use neb::ram::chunk;
    use std;
    use rand;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            types::pos3d64 {x: std::f64::MIN, y: std::f64::MAX, z: rand::random::<f64>()},
            types::pos3d64 {x: rand::random::<f64>(), y: rand::random::<f64>(), z: rand::random::<f64>()}
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        let counts = CHUNK_SIZE / types::pos3d64_io::size(0) as usize;
        for d in test_data {
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos3d64_io::size(0);
                types::pos3d64_io::write(&d, addr);
                assert!(types::pos3d64_io::read(addr) == d);
            }
            for i in 0..counts {
                let addr = chunk.addr + i * types::pos3d64_io::size(0);
                assert!(types::pos3d64_io::read(addr) == d);
            }
        }
    }
}

mod uuid {
    use neb::ram::types;
    use neb::ram::chunk;
    use uuid::Uuid;
    use uuid;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(),
            Uuid::new_v4(),
            Uuid::new_v5(&uuid::NAMESPACE_DNS, "foo")
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        for d in test_data {
            types::uuid_io::write(&d, chunk.addr);
            assert!(types::uuid_io::read(chunk.addr) == d);
        }
    }
}

mod string {
    use neb::ram::types;
    use neb::ram::chunk;
    use std::string::String;
    use super::CHUNK_SIZE;
    #[test]
    fn test () {
        let test_data = vec![
            "", "ಬಾ ಇಲ್ಲಿ ಸಂಭವಿಸ", "中文测试文本", "Hello Test", "💖"
        ];
        let chunk = &chunk::init(1, CHUNK_SIZE).list[0];
        for d in test_data {
            let test_str = String::from(d);
            types::string_io::write(&test_str, chunk.addr);
            assert!(types::string_io::read(chunk.addr) == test_str);
        }
    }
}<|endoftext|>


<commit_before>use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::values::*;

///
/// Used to help decode tree nodes into other types
///
struct TreeNodeDecoder {
    current_node: Rc<TreeNode>
}

#[derive(Debug)]
pub enum TreeNodeDecodingError {
    UnsupportedType,
    NodeHasInvalidType,
    ValueOutOfRange,
    GenericError(String)
}

impl TreeNodeDecoder {
    fn read_current(&self) -> &TreeValue {
        self.current_node.get_value()
    }
}

impl Decoder for TreeNodeDecoder {
    type Error = TreeNodeDecodingError;

    fn read_nil(&mut self) -> Result<(), Self::Error> {
        match *self.read_current() {
            TreeValue::Nothing  => Ok(()),
            _                   => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_i32(&mut self) -> Result<i32, Self::Error> {
        match *self.read_current() {
            TreeValue::Int(ref x)   => Ok(*x),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_i16(&mut self) -> Result<i16, Self::Error> {
        match *self.read_current() {
            TreeValue::Int(ref x)   => if (*x >= i16::min_value() as i32) && (*x <= i16::max_value() as i32) { Ok(*x as i16) } else { Err(TreeNodeDecodingError::ValueOutOfRange) },
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_i8(&mut self) -> Result<i8, Self::Error> {
        match *self.read_current() {
            TreeValue::Int(ref x)   => if (*x >= i8::min_value() as i32) && (*x <= i8::max_value() as i32) { Ok(*x as i8) } else { Err(TreeNodeDecodingError::ValueOutOfRange) },
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_str(&mut self) -> Result<String, Self::Error> {
        match *self.read_current() {
            TreeValue::String(ref x)    => Ok(x.to_owned()),
            _                           => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_bool(&mut self) -> Result<bool, Self::Error> {
        match *self.read_current() {
            TreeValue::Bool(ref x)  => Ok(*x),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_f64(&mut self) -> Result<f64, Self::Error> {
        match *self.read_current() {
            TreeValue::Real(ref x)  => Ok(*x),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_f32(&mut self) -> Result<f32, Self::Error> {
        match *self.read_current() {
            TreeValue::Real(ref x)  => Ok(*x as f32),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_usize(&mut self) -> Result<usize, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u64(&mut self) -> Result<u64, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u32(&mut self) -> Result<u32, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u16(&mut self) -> Result<u16, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u8(&mut self) -> Result<u8, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_isize(&mut self) -> Result<isize, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_i64(&mut self) -> Result<i64, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_char(&mut self) -> Result<char, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum<T, F>(&mut self, name: &str, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_variant_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_struct_variant_field<T, F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_struct<T, F>(&mut self, s_name: &str, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_struct_field<T, F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple<T, F>(&mut self, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple_struct<T, F>(&mut self, s_name: &str, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_option<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, bool) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_seq_elt<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn error(&mut self, err: &str) -> Self::Error {
        TreeNodeDecodingError::GenericError(err.to_string())
    }
}
<commit_msg>Add the ability to read structures<commit_after>use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::values::*;

///
/// Used to help decode tree nodes into other types
///
struct TreeNodeDecoder {
    current_node: Rc<TreeNode>
}

#[derive(Debug)]
pub enum TreeNodeDecodingError {
    UnsupportedType,
    NodeHasInvalidType,
    ValueOutOfRange,
    MissingField,
    GenericError(String)
}

impl TreeNodeDecoder {
    fn read_current(&self) -> &TreeValue {
        self.current_node.get_value()
    }
}

impl Decoder for TreeNodeDecoder {
    type Error = TreeNodeDecodingError;

    fn read_nil(&mut self) -> Result<(), Self::Error> {
        match *self.read_current() {
            TreeValue::Nothing  => Ok(()),
            _                   => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_i32(&mut self) -> Result<i32, Self::Error> {
        match *self.read_current() {
            TreeValue::Int(ref x)   => Ok(*x),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_i16(&mut self) -> Result<i16, Self::Error> {
        match *self.read_current() {
            TreeValue::Int(ref x)   => if (*x >= i16::min_value() as i32) && (*x <= i16::max_value() as i32) { Ok(*x as i16) } else { Err(TreeNodeDecodingError::ValueOutOfRange) },
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_i8(&mut self) -> Result<i8, Self::Error> {
        match *self.read_current() {
            TreeValue::Int(ref x)   => if (*x >= i8::min_value() as i32) && (*x <= i8::max_value() as i32) { Ok(*x as i8) } else { Err(TreeNodeDecodingError::ValueOutOfRange) },
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_str(&mut self) -> Result<String, Self::Error> {
        match *self.read_current() {
            TreeValue::String(ref x)    => Ok(x.to_owned()),
            _                           => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_bool(&mut self) -> Result<bool, Self::Error> {
        match *self.read_current() {
            TreeValue::Bool(ref x)  => Ok(*x),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_f64(&mut self) -> Result<f64, Self::Error> {
        match *self.read_current() {
            TreeValue::Real(ref x)  => Ok(*x),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_f32(&mut self) -> Result<f32, Self::Error> {
        match *self.read_current() {
            TreeValue::Real(ref x)  => Ok(*x as f32),
            _                       => Err(TreeNodeDecodingError::NodeHasInvalidType)
        }
    }

    fn read_struct<T, F>(&mut self, s_name: &str, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        f(self)
    }

    fn read_struct_field<T, F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        // Look up the field
        // TODO: could hash the field names to avoid doing a linear search every time (not clear if there are substantial benefits for this given the small number of fields in most structures)
        let field = self.current_node.get_child_ref_at(f_name);

        match field {
            None        => Err(TreeNodeDecodingError::MissingField),
            Some(ref x) => {
                // Move into the field node
                let previous_node = self.current_node.to_owned();
                self.current_node = x.to_owned();

                // Decode it
                let result = f(self);

                // Move back out
                self.current_node = previous_node.to_owned();

                result
            }
        }
    }

    fn read_usize(&mut self) -> Result<usize, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u64(&mut self) -> Result<u64, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u32(&mut self) -> Result<u32, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u16(&mut self) -> Result<u16, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_u8(&mut self) -> Result<u8, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_isize(&mut self) -> Result<isize, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_i64(&mut self) -> Result<i64, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_char(&mut self) -> Result<char, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum<T, F>(&mut self, name: &str, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_variant_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_enum_struct_variant_field<T, F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple<T, F>(&mut self, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple_struct<T, F>(&mut self, s_name: &str, len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_option<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, bool) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_seq_elt<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        Err(TreeNodeDecodingError::UnsupportedType)
    }

    fn error(&mut self, err: &str) -> Self::Error {
        TreeNodeDecodingError::GenericError(err.to_string())
    }
}
<|endoftext|>


<commit_before>//! Support for the DMABuf type

use wayland_sys::server::wl_display as wl_server_display;
use wlroots_sys::{wl_display, wlr_renderer, wlr_linux_dmabuf_v1,
    wlr_linux_dmabuf_v1_create, wlr_linux_dmabuf_v1_destroy};

#[derive(Debug)]
pub struct Dmabuf {
    dmabuf: *mut wlr_linux_dmabuf_v1
}

impl Dmabuf {
    pub(crate) unsafe fn new(display: *mut wl_server_display, renderer: *mut wlr_renderer) -> Option<Self> {
        let dmabuf_raw = wlr_linux_dmabuf_v1_create(display as *mut wl_display, renderer);
        if !dmabuf_raw.is_null() {
            Some(Dmabuf { dmabuf: dmabuf_raw })
        } else {
            None
        }
    }
}

impl Drop for Dmabuf {
    fn drop(&mut self) {
        unsafe { wlr_linux_dmabuf_v1_destroy(self.dmabuf) }
    }
}
<commit_msg>initial attempt at compositor reference<commit_after>//! Support for the DMABuf type

use wlroots_sys::{wl_display, wlr_linux_dmabuf_v1, wlr_linux_dmabuf_v1_create,
                wlr_linux_dmabuf_v1_destroy};
use {compositor::Compositor,
    render::GenericRenderer};

#[derive(Debug)]
pub struct Dmabuf {
    dmabuf: *mut wlr_linux_dmabuf_v1
}

impl Dmabuf {
    pub fn new(compositor: &Compositor) -> Option<Self> {
        unsafe {
            // Get the renderer from compositor
            let renderer: Option<GenericRenderer> = compositor.renderer;
            // Unwrap it and check if it's null
            let renderer_raw = renderer.unwrap().as_ptr();
            if !renderer_raw.is_null() {
                // We found a renderer
                let dmabuf_raw = wlr_linux_dmabuf_v1_create(compositor.display as *mut wl_display, renderer_raw);
                if !dmabuf_raw.is_null() {
                    Some(Dmabuf { dmabuf: dmabuf_raw })
                } else {
                    None
                }
            }
            else {
                 // No renderer found so return none
                None
            }
        }
    }
    // TODO wrap rest of dmabuf
}

impl Drop for Dmabuf {
    fn drop(&mut self) {
        unsafe { wlr_linux_dmabuf_v1_destroy(self.dmabuf) }
    }
}
<|endoftext|>


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

use parser::html::Expression as Expr;
use parser::html::Statement as Stmt;
use parser::html::Statement::{Store};
use util::join;
use super::Generator;
use super::ast::{Statement, Param, Expression};
use super::ast::Expression as E;
use super::ast::Statement as S;

fn attr<'x, S: AsRef<str>>(e: Expression, v: S) -> Expression {
    E::Attr(Box::new(e), v.as_ref().to_string())
}

impl<'a, W:Write+'a> Generator<'a, W> {

    fn compile_link(&self, expr: Expression,
        filter: &Option<Expr>, map: Option<&Expr>)
        -> Expression
    {
        let mut e = expr;
        if let Some(map) = map {
            let ev = Param { name: String::from("ev"), default_value: None };
            let func = E::Function(None, vec![ev], vec![
                S::Return(self.compile_expr(map))]);
            e = E::Call(Box::new(attr(e, "map")), vec![func]);
        }
        if let &Some(ref filt) = filter {
            let ev = Param { name: String::from("ev"), default_value: None };
            let func = E::Function(None, vec![ev], vec![
                S::Return(self.compile_expr(filt))]);
            e = E::Call(Box::new(attr(e, "filter")), vec![func]);
        }
        attr(e, "handle_event")
    }

    pub fn element(&self, name: &String,
        classes: &Vec<(String, Option<Expr>)>,
        attributes: &Vec<(String, Expr)>,
        key: Option<Expression>,
        body: &Vec<Stmt>)
        -> Expression
    {
        use parser::html::Link as L;
        use parser::html::LinkDest as D;

        let mut properties = vec![
                (String::from("tag"), Expression::Str(name.clone())),
        ];
        if let Some(key) = key {
            properties.push((String::from("key"), key));
        }
        let mut statements = vec![];
        let mut events = HashMap::new();
        for item in body.iter() {
            match item {
                &Stmt::Let(ref name, ref value) => {
                    statements.push(Statement::Var(name.clone(),
                        self.compile_expr(value)));
                }
                &Store(ref name, ref value) => {
                    let prop = String::from("store_") +name;
                    statements.push(Statement::Var(name.clone(),
                        E::Or(
                            Box::new(E::And(
                                Box::new(E::Name(String::from("old_node"))),
                                Box::new(E::Attr(Box::new(
                                        E::Name(String::from("old_node"))),
                                        prop.clone())))),
                            Box::new(self.compile_expr(value)))));
                    properties.push((prop, E::Name(name.clone())));
                    events.entry(String::from("$destroyed"))
                    .or_insert(vec!()).push(
                        E::Ternary(
                            Box::new(attr(E::Name(name.clone()),
                                "owner_destroyed")),
                            Box::new(attr(
                                attr(E::Name(name.clone()), "owner_destroyed"),
                                "handle_event")),
                            Box::new(E::Function(None, vec![], vec![])),
                        ));
                }
                &Stmt::Link(ref links) => {
                    for lnk in links {
                        match lnk {
                            &L::One(ref s, ref f, D::Stream(ref expr)) => {
                                events.entry(s.clone()).or_insert(vec!()).push(
                                    self.compile_link(
                                        self.compile_expr(expr),
                                        f, None));
                            }
                            &L::Multi(ref names, D::Stream(ref expr)) => {
                                let v = format!("_stream_{}",
                                    statements.len());
                                statements.push(Statement::Var(
                                    v.clone(),
                                    self.compile_expr(expr)));
                                for &(ref aname, ref flt, ref ename) in names {
                                    let ev = ename.as_ref()
                                             .unwrap_or(aname).clone();
                                    events.entry(ev.clone()).or_insert(vec!())
                                        .push(self.compile_link(
                                            attr(E::Name(v.clone()), &aname),
                                            flt, None));
                                }
                            }
                            &L::One(ref s, ref f, D::Mapping(ref val, ref dst))
                            => {
                                events.entry(s.clone()).or_insert(vec!()).push(
                                    self.compile_link(
                                        self.compile_expr(dst), f, Some(val)));
                            }
                            &L::Multi(ref names, D::Mapping(ref val, ref dest))
                            => {
                                let v = format!("_stream_{}",
                                    statements.len());
                                statements.push(Statement::Var(
                                    v.clone(),
                                    self.compile_expr(dest)));
                                for &(ref aname, ref flt, ref event) in names {
                                    let ename = event.as_ref()
                                             .unwrap_or(aname).clone();
                                    events.entry(ename).or_insert(vec!()).push(
                                        self.compile_link(
                                            attr(E::Name(v.clone()), aname),
                                            flt, Some(val)));
                                }
                            }
                        }
                    }
                }
                _ => {}
            }
        }
        if classes.len() > 0 || attributes.len() > 0 {
            properties.push(
                (String::from("attrs"),
                    self.attrs(name, classes, attributes)));
        }
        if body.len() > 0 {
            properties.push(
                (String::from("children"), self.fragment(&body, None)));
        }
        if events.len() > 0 {
            properties.push( (String::from("events"), Expression::Object(
                events.into_iter().map(|(k, mut v)| {
                    if v.len() == 1 {
                        (k, v.pop().unwrap())
                    } else {
                        (k, Expression::List(v))
                    }
                }).collect()
            )));
        }
        if statements.len() > 0 {
            statements.push(
                Statement::Return(Expression::Object(properties)));
            return Expression::Function(None,
                vec![Param {
                    name: String::from("old_node"),
                    default_value: None,
                }],
                statements);
        } else {
            return Expression::Object(properties);
        }
    }

    fn attrs(&self, name: &String, cls: &Vec<(String, Option<Expr>)>,
        attrs: &Vec<(String, Expr)>)
        -> Expression
    {
        let mut class_literals = vec!();
        let mut class_expr = vec!();
        if cls.len() > 0 || self.bare_element_names.contains(name) {
            class_literals.push(self.block_name.to_string());
        }
        for &(ref cname, ref opt_cond) in cls {
            if let &Some(ref cond) = opt_cond {
                class_expr.push(Expression::Ternary(
                    Box::new(self.compile_expr(cond)),
                    Box::new(Expression::Str(cname.clone())),
                    Box::new(Expression::Str(String::from("")))));
            } else {
                class_literals.push(cname.clone());
            }
        }
        let mut rattrs = vec!();
        for &(ref name, ref value) in attrs {
            if &name[..] == "class" {
                class_expr.push(self.compile_expr(value));
            } else {
                rattrs.push((name.clone(), self.compile_expr(value)));
            }
        }
        if class_literals.len() > 0 {
            class_expr.insert(0,
                Expression::Str(join(class_literals.iter(), " ")));
        }
        if class_expr.len() > 0 {
            let first = class_expr.remove(0);
            rattrs.push((String::from("class"), class_expr.into_iter()
                .fold(first, |acc, val|
                    Expression::Add(Box::new(
                        Expression::Add(
                            Box::new(acc),
                            Box::new(Expression::Str(String::from(" "))))),
                        Box::new(val)))));
        }
        Expression::Object(rattrs)
    }

}
<commit_msg>Turn element into fragment if it requires key and is rendered as function, to overcome limitation of cito.js<commit_after>use std::io::Write;
use std::collections::HashMap;

use parser::html::Expression as Expr;
use parser::html::Statement as Stmt;
use parser::html::Statement::{Store};
use util::join;
use super::Generator;
use super::ast::{Statement, Param, Expression};
use super::ast::Expression as E;
use super::ast::Statement as S;

fn attr<'x, S: AsRef<str>>(e: Expression, v: S) -> Expression {
    E::Attr(Box::new(e), v.as_ref().to_string())
}

impl<'a, W:Write+'a> Generator<'a, W> {

    fn compile_link(&self, expr: Expression,
        filter: &Option<Expr>, map: Option<&Expr>)
        -> Expression
    {
        let mut e = expr;
        if let Some(map) = map {
            let ev = Param { name: String::from("ev"), default_value: None };
            let func = E::Function(None, vec![ev], vec![
                S::Return(self.compile_expr(map))]);
            e = E::Call(Box::new(attr(e, "map")), vec![func]);
        }
        if let &Some(ref filt) = filter {
            let ev = Param { name: String::from("ev"), default_value: None };
            let func = E::Function(None, vec![ev], vec![
                S::Return(self.compile_expr(filt))]);
            e = E::Call(Box::new(attr(e, "filter")), vec![func]);
        }
        attr(e, "handle_event")
    }

    pub fn element(&self, name: &String,
        classes: &Vec<(String, Option<Expr>)>,
        attributes: &Vec<(String, Expr)>,
        key: Option<Expression>,
        body: &Vec<Stmt>)
        -> Expression
    {
        use parser::html::Link as L;
        use parser::html::LinkDest as D;

        let mut properties = vec![
                (String::from("tag"), Expression::Str(name.clone())),
        ];
        let mut statements = vec![];
        let mut events = HashMap::new();
        for item in body.iter() {
            match item {
                &Stmt::Let(ref name, ref value) => {
                    statements.push(Statement::Var(name.clone(),
                        self.compile_expr(value)));
                }
                &Store(ref name, ref value) => {
                    let prop = String::from("store_") +name;
                    statements.push(Statement::Var(name.clone(),
                        E::Or(
                            Box::new(E::And(
                                Box::new(E::Name(String::from("old_node"))),
                                Box::new(E::Attr(Box::new(
                                        E::Name(String::from("old_node"))),
                                        prop.clone())))),
                            Box::new(self.compile_expr(value)))));
                    properties.push((prop, E::Name(name.clone())));
                    events.entry(String::from("$destroyed"))
                    .or_insert(vec!()).push(
                        E::Ternary(
                            Box::new(attr(E::Name(name.clone()),
                                "owner_destroyed")),
                            Box::new(attr(
                                attr(E::Name(name.clone()), "owner_destroyed"),
                                "handle_event")),
                            Box::new(E::Function(None, vec![], vec![])),
                        ));
                }
                &Stmt::Link(ref links) => {
                    for lnk in links {
                        match lnk {
                            &L::One(ref s, ref f, D::Stream(ref expr)) => {
                                events.entry(s.clone()).or_insert(vec!()).push(
                                    self.compile_link(
                                        self.compile_expr(expr),
                                        f, None));
                            }
                            &L::Multi(ref names, D::Stream(ref expr)) => {
                                let v = format!("_stream_{}",
                                    statements.len());
                                statements.push(Statement::Var(
                                    v.clone(),
                                    self.compile_expr(expr)));
                                for &(ref aname, ref flt, ref ename) in names {
                                    let ev = ename.as_ref()
                                             .unwrap_or(aname).clone();
                                    events.entry(ev.clone()).or_insert(vec!())
                                        .push(self.compile_link(
                                            attr(E::Name(v.clone()), &aname),
                                            flt, None));
                                }
                            }
                            &L::One(ref s, ref f, D::Mapping(ref val, ref dst))
                            => {
                                events.entry(s.clone()).or_insert(vec!()).push(
                                    self.compile_link(
                                        self.compile_expr(dst), f, Some(val)));
                            }
                            &L::Multi(ref names, D::Mapping(ref val, ref dest))
                            => {
                                let v = format!("_stream_{}",
                                    statements.len());
                                statements.push(Statement::Var(
                                    v.clone(),
                                    self.compile_expr(dest)));
                                for &(ref aname, ref flt, ref event) in names {
                                    let ename = event.as_ref()
                                             .unwrap_or(aname).clone();
                                    events.entry(ename).or_insert(vec!()).push(
                                        self.compile_link(
                                            attr(E::Name(v.clone()), aname),
                                            flt, Some(val)));
                                }
                            }
                        }
                    }
                }
                _ => {}
            }
        }
        if classes.len() > 0 || attributes.len() > 0 {
            properties.push(
                (String::from("attrs"),
                    self.attrs(name, classes, attributes)));
        }
        if body.len() > 0 {
            properties.push(
                (String::from("children"), self.fragment(&body, None)));
        }
        if events.len() > 0 {
            properties.push( (String::from("events"), Expression::Object(
                events.into_iter().map(|(k, mut v)| {
                    if v.len() == 1 {
                        (k, v.pop().unwrap())
                    } else {
                        (k, Expression::List(v))
                    }
                }).collect()
            )));
        }
        if statements.len() > 0 {
            statements.push(
                Statement::Return(Expression::Object(properties)));
            let func = Expression::Function(None,
                vec![Param {
                    name: String::from("old_node"),
                    default_value: None,
                }],
                statements);
            if let Some(key) = key {
                // If there is a key, we must turn function into fragment,
                // because it's impossible to find out old_node before knowing
                // the key
                return Expression::Object(vec![
                    ("key".to_string(), key),
                    ("children".to_string(), func),
                    ].into_iter().collect())
            } else {
                return func
            }
        } else {
            if let Some(key) = key {
                properties.push((String::from("key"), key));
            }
            return Expression::Object(properties);
        }
    }

    fn attrs(&self, name: &String, cls: &Vec<(String, Option<Expr>)>,
        attrs: &Vec<(String, Expr)>)
        -> Expression
    {
        let mut class_literals = vec!();
        let mut class_expr = vec!();
        if cls.len() > 0 || self.bare_element_names.contains(name) {
            class_literals.push(self.block_name.to_string());
        }
        for &(ref cname, ref opt_cond) in cls {
            if let &Some(ref cond) = opt_cond {
                class_expr.push(Expression::Ternary(
                    Box::new(self.compile_expr(cond)),
                    Box::new(Expression::Str(cname.clone())),
                    Box::new(Expression::Str(String::from("")))));
            } else {
                class_literals.push(cname.clone());
            }
        }
        let mut rattrs = vec!();
        for &(ref name, ref value) in attrs {
            if &name[..] == "class" {
                class_expr.push(self.compile_expr(value));
            } else {
                rattrs.push((name.clone(), self.compile_expr(value)));
            }
        }
        if class_literals.len() > 0 {
            class_expr.insert(0,
                Expression::Str(join(class_literals.iter(), " ")));
        }
        if class_expr.len() > 0 {
            let first = class_expr.remove(0);
            rattrs.push((String::from("class"), class_expr.into_iter()
                .fold(first, |acc, val|
                    Expression::Add(Box::new(
                        Expression::Add(
                            Box::new(acc),
                            Box::new(Expression::Str(String::from(" "))))),
                        Box::new(val)))));
        }
        Expression::Object(rattrs)
    }

}
<|endoftext|>


<commit_before>extern crate ws;

use self::ws::{Handler, Sender, Result, Message, Handshake, CloseCode, Error, Settings};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

use std::rc::Rc;
use std::cell::Cell;

struct Server {
    clients:Arc<Mutex<HashMap<u32, Sender>>>,
    out: Sender,
    count: Rc<Cell<u32>>,
    id : u32,
}
trait HasBroadcast {
	fn broadcast(&self, msg: Message)->Result<()>;
}
impl HasBroadcast for Server {
	fn broadcast(&self, msg:Message)->Result<()> {
        for (key, client) in self.clients.lock().unwrap().iter(){
        	if *key != self.id {
	        	// println!("{:?} {:?}", *key, self.id);
	        	client.send(msg.clone());
	        	client.send(format!("hello {} from {}",key, &self.id));
       		}
        }
        return Ok(());
	}
}

pub fn create() {

  println!("0.0.0.0:3012");
  let count = Rc::new(Cell::new(0));
  let uuid = Rc::new(Cell::new(100));
  let map:HashMap<u32, Sender> = HashMap::new();
  let mutex_map = Arc::new(Mutex::new(map));
  ws::Settings.max_connections = 200;
  let ws = ws::listen("0.0.0.0:3012", |out| {
  	uuid.set(uuid.get()+1);
    let id = uuid.get();

  	 Server { out: out, count: count.clone(), clients:mutex_map.clone(), id:id }
  }).unwrap();

}

impl Handler for Server {

    fn on_open(&mut self, _: Handshake) -> Result<()> {
        self.clients.lock().unwrap().insert(self.id.clone(), self.out.clone());

        Ok(self.count.set(self.count.get() + 1))
    }

    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("The number of live connections is {}", self.count.get());
        self.broadcast(msg)?;
        return Ok(())
//        self.out.send(msg)
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        self.clients.lock().unwrap().remove(&self.id.clone());

        match code {
            CloseCode::Normal => println!("The client is done with the connection."),
            CloseCode::Away   => println!("The client is leaving the site."),
            CloseCode::Abnormal => println!(
                "Closing handshake failed! Unable to obtain closing status from client."),
            _ => println!("The client encountered an error: {}", reason),
        }

        // The connection is going down, so we need to decrement the count
        self.count.set(self.count.get() - 1)
    }

    fn on_error(&mut self, err: Error) {
        println!("The server encountered an error: {:?}", err);
    }
}
<commit_msg>clean up warnings<commit_after>extern crate ws;

use self::ws::{Handler, Sender, Result, Message, Handshake, CloseCode, Error};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;

use std::rc::Rc;
use std::cell::Cell;

struct Server {
    clients:Arc<Mutex<HashMap<u32, Sender>>>,
    out: Sender,
    count: Rc<Cell<u32>>,
    id : u32,
}
trait HasBroadcast {
	fn broadcast(&self, msg: Message)->Result<()>;
}
impl HasBroadcast for Server {
	fn broadcast(&self, msg:Message)->Result<()> {
        for (key, client) in self.clients.lock().unwrap().iter(){
        	if *key != self.id {
	        	// println!("{:?} {:?}", *key, self.id);
	        	client.send(msg.clone()).unwrap();
	        	client.send(format!("hello {} from {}",key, &self.id)).unwrap();
       		}
        }
        return Ok(());
	}
}

pub fn create() {

  println!("0.0.0.0:3012");
  let count = Rc::new(Cell::new(0));
  let uuid = Rc::new(Cell::new(100));
  let map:HashMap<u32, Sender> = HashMap::new();
  let mutex_map = Arc::new(Mutex::new(map));

  let ws = ws::listen("0.0.0.0:3012", |out| {
  	uuid.set(uuid.get()+1);
    let id = uuid.get();

  	 Server { out: out, count: count.clone(), clients:mutex_map.clone(), id:id }
  }).unwrap();
  return ws;
}

impl Handler for Server {

    fn on_open(&mut self, _: Handshake) -> Result<()> {
        self.clients.lock().unwrap().insert(self.id.clone(), self.out.clone());

        Ok(self.count.set(self.count.get() + 1))
    }

    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("The number of live connections is {}", self.count.get());
        self.broadcast(msg)?;
        return Ok(())
//        self.out.send(msg)
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        self.clients.lock().unwrap().remove(&self.id.clone());

        match code {
            CloseCode::Normal => println!("The client is done with the connection."),
            CloseCode::Away   => println!("The client is leaving the site."),
            CloseCode::Abnormal => println!(
                "Closing handshake failed! Unable to obtain closing status from client."),
            _ => println!("The client encountered an error: {}", reason),
        }

        // The connection is going down, so we need to decrement the count
        self.count.set(self.count.get() - 1)
    }

    fn on_error(&mut self, err: Error) {
        println!("The server encountered an error: {:?}", err);
    }
}
<|endoftext|>


<commit_before>use winapi;

use self::winapi::ctypes::c_int;
use self::winapi::um::winuser::*;

use crate::win::keycodes::*;
use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};
use std::mem::*;

/// The main struct for handling the event emitting
#[derive(Default)]
pub struct Enigo;

fn mouse_event(flags: u32, data: u32, dx: i32, dy: i32) {
    let mut input = INPUT {
        type_: INPUT_MOUSE,
        u: unsafe {
            transmute(MOUSEINPUT {
                dx,
                dy,
                mouseData: data,
                dwFlags: flags,
                time: 0,
                dwExtraInfo: 0,
            })
        },
    };
    unsafe { SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int) };
}

fn keybd_event(flags: u32, vk: u16, scan: u16) {
    let mut input = INPUT {
        type_: INPUT_KEYBOARD,
        u: unsafe {
            transmute_copy(&KEYBDINPUT {
                wVk: vk,
                wScan: scan,
                dwFlags: flags,
                time: 0,
                dwExtraInfo: 0,
            })
        },
    };
    unsafe { SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int) };
}

impl MouseControllable for Enigo {
    fn mouse_move_to(&mut self, x: i32, y: i32) {
        mouse_event(
            MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
            0,
            x * 65335 / unsafe { GetSystemMetrics(78) },
            y * 65335 / unsafe { GetSystemMetrics(79) },
        );
    }

    fn mouse_move_relative(&mut self, x: i32, y: i32) {
        mouse_event(MOUSEEVENTF_MOVE, 0, x, y);
    }

    fn mouse_down(&mut self, button: MouseButton) {
        mouse_event(
            match button {
                MouseButton::Left => MOUSEEVENTF_LEFTDOWN,
                MouseButton::Middle => MOUSEEVENTF_MIDDLEDOWN,
                MouseButton::Right => MOUSEEVENTF_RIGHTDOWN,
                _ => unimplemented!(),
            },
            0,
            0,
            0,
        );
    }

    fn mouse_up(&mut self, button: MouseButton) {
        mouse_event(
            match button {
                MouseButton::Left => MOUSEEVENTF_LEFTUP,
                MouseButton::Middle => MOUSEEVENTF_MIDDLEUP,
                MouseButton::Right => MOUSEEVENTF_RIGHTUP,
                _ => unimplemented!(),
            },
            0,
            0,
            0,
        );
    }

    fn mouse_click(&mut self, button: MouseButton) {
        self.mouse_down(button);
        self.mouse_up(button);
    }

    fn mouse_scroll_x(&mut self, length: i32) {
        mouse_event(MOUSEEVENTF_HWHEEL, unsafe { transmute(length * 120) }, 0, 0);
    }

    fn mouse_scroll_y(&mut self, length: i32) {
        mouse_event(MOUSEEVENTF_WHEEL, unsafe { transmute(length * 120) }, 0, 0);
    }
}

impl KeyboardControllable for Enigo {
    fn key_sequence(&mut self, sequence: &str) {
        let mut buffer = [0; 2];

        for c in sequence.chars() {
            // Windows uses uft-16 encoding. We need to check
            // for variable length characters. As such some
            // characters can be 32 bit long and those are
            // encoded in such called hight and low surrogates
            // each 16 bit wide that needs to be send after
            // another to the SendInput function without
            // being interrupted by "keyup"
            let result = c.encode_utf16(&mut buffer);
            if result.len() == 1 {
                self.unicode_key_click(result[0]);
            } else {
                for utf16_surrogate in result {
                    self.unicode_key_down(utf16_surrogate.clone());
                }
                // do i need to produce a keyup?
                // self.unicode_key_up(0);
            }
        }
    }

    fn key_click(&mut self, key: Key) {
        let scancode = self.key_to_scancode(key);
        use std::{thread, time};
        keybd_event(KEYEVENTF_SCANCODE, 0, scancode);
        thread::sleep(time::Duration::from_millis(20));
        keybd_event(KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE, 0, scancode);
    }

    fn key_down(&mut self, key: Key) {
        keybd_event(KEYEVENTF_SCANCODE, 0, self.key_to_scancode(key));
    }

    fn key_up(&mut self, key: Key) {
        keybd_event(
            KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE,
            0,
            self.key_to_scancode(key),
        );
    }
}

impl Enigo {
    fn unicode_key_click(&self, unicode_char: u16) {
        use std::{thread, time};
        self.unicode_key_down(unicode_char);
        thread::sleep(time::Duration::from_millis(20));
        self.unicode_key_up(unicode_char);
    }

    fn unicode_key_down(&self, unicode_char: u16) {
        keybd_event(KEYEVENTF_UNICODE, 0, unicode_char);
    }

    fn unicode_key_up(&self, unicode_char: u16) {
        keybd_event(KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, 0, unicode_char);
    }

    fn key_to_keycode(&self, key: Key) -> u16 {
        // do not use the codes from crate winapi they're
        // wrongly typed with i32 instead of i16 use the
        // ones provided by win/keycodes.rs that are prefixed
        // with an 'E' infront of the original name
        #[allow(deprecated)]
        // I mean duh, we still need to support deprecated keys until they're removed
        match key {
            Key::Alt => EVK_MENU,
            Key::Backspace => EVK_BACK,
            Key::CapsLock => EVK_CAPITAL,
            Key::Control => EVK_LCONTROL,
            Key::Delete => EVK_DELETE,
            Key::DownArrow => EVK_DOWN,
            Key::End => EVK_END,
            Key::Escape => EVK_ESCAPE,
            Key::F1 => EVK_F1,
            Key::F10 => EVK_F10,
            Key::F11 => EVK_F11,
            Key::F12 => EVK_F12,
            Key::F2 => EVK_F2,
            Key::F3 => EVK_F3,
            Key::F4 => EVK_F4,
            Key::F5 => EVK_F5,
            Key::F6 => EVK_F6,
            Key::F7 => EVK_F7,
            Key::F8 => EVK_F8,
            Key::F9 => EVK_F9,
            Key::Home => EVK_HOME,
            Key::LeftArrow => EVK_LEFT,
            Key::Option => EVK_MENU,
            Key::PageDown => EVK_NEXT,
            Key::PageUp => EVK_PRIOR,
            Key::Return => EVK_RETURN,
            Key::RightArrow => EVK_RIGHT,
            Key::Shift => EVK_SHIFT,
            Key::Space => EVK_SPACE,
            Key::Tab => EVK_TAB,
            Key::UpArrow => EVK_UP,

            Key::Raw(raw_keycode) => raw_keycode,
            Key::Layout(c) => self.get_layoutdependent_keycode(c.to_string()),
            //_ => 0,
            Key::Super | Key::Command | Key::Windows | Key::Meta => EVK_LWIN,
        }
    }

    fn key_to_scancode(&self, key: Key) -> u16 {
        let keycode = self.key_to_keycode(key);
        unsafe { MapVirtualKeyW(keycode as u32, 0) as u16 }
    }

    fn get_layoutdependent_keycode(&self, string: String) -> u16 {
        let mut buffer = [0; 2];
        // get the first char from the string ignore the rest
        // ensure its not a multybyte char
        let utf16 = string
            .chars()
            .nth(0)
            .expect("no valid input") //TODO(dustin): no panic here make an error
            .encode_utf16(&mut buffer);
        if utf16.len() != 1 {
            // TODO(dustin) don't panic here use an apropriate errors
            panic!("this char is not allowd");
        }
        // NOTE VkKeyScanW uses the current keyboard layout
        // to specify a layout use VkKeyScanExW and GetKeyboardLayout
        // or load one with LoadKeyboardLayoutW
        let keycode_and_shiftstate = unsafe { VkKeyScanW(utf16[0]) };
        // 0x41 as u16 //key that has the letter 'a' on it on english like keylayout
        keycode_and_shiftstate as u16
    }
}
<commit_msg>resolve conflicts with master<commit_after>use winapi;

use self::winapi::shared::windef::POINT;
use self::winapi::ctypes::c_int;
use self::winapi::um::winuser::*;

use crate::win::keycodes::*;
use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};
use std::mem::*;

/// The main struct for handling the event emitting
#[derive(Default)]
pub struct Enigo;

fn mouse_event(flags: u32, data: u32, dx: i32, dy: i32) {
    let mut input = INPUT {
        type_: INPUT_MOUSE,
        u: unsafe {
            transmute(MOUSEINPUT {
                dx,
                dy,
                mouseData: data,
                dwFlags: flags,
                time: 0,
                dwExtraInfo: 0,
            })
        },
    };
    unsafe { SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int) };
}

fn keybd_event(flags: u32, vk: u16, scan: u16) {
    let mut input = INPUT {
        type_: INPUT_KEYBOARD,
        u: unsafe {
            transmute_copy(&KEYBDINPUT {
                wVk: vk,
                wScan: scan,
                dwFlags: flags,
                time: 0,
                dwExtraInfo: 0,
            })
        },
    };
    unsafe { SendInput(1, &mut input as LPINPUT, size_of::<INPUT>() as c_int) };
}

impl MouseControllable for Enigo {
    fn mouse_move_to(&mut self, x: i32, y: i32) {
        mouse_event(
            MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
            0,
            x * 65335 / unsafe { GetSystemMetrics(78) },
            y * 65335 / unsafe { GetSystemMetrics(79) },
        );
    }

    fn mouse_move_relative(&mut self, x: i32, y: i32) {
        mouse_event(MOUSEEVENTF_MOVE, 0, x, y);
    }

    fn mouse_down(&mut self, button: MouseButton) {
        mouse_event(
            match button {
                MouseButton::Left => MOUSEEVENTF_LEFTDOWN,
                MouseButton::Middle => MOUSEEVENTF_MIDDLEDOWN,
                MouseButton::Right => MOUSEEVENTF_RIGHTDOWN,
                _ => unimplemented!(),
            },
            0,
            0,
            0,
        );
    }

    fn mouse_up(&mut self, button: MouseButton) {
        mouse_event(
            match button {
                MouseButton::Left => MOUSEEVENTF_LEFTUP,
                MouseButton::Middle => MOUSEEVENTF_MIDDLEUP,
                MouseButton::Right => MOUSEEVENTF_RIGHTUP,
                _ => unimplemented!(),
            },
            0,
            0,
            0,
        );
    }

    fn mouse_click(&mut self, button: MouseButton) {
        self.mouse_down(button);
        self.mouse_up(button);
    }

    fn mouse_scroll_x(&mut self, length: i32) {
        mouse_event(MOUSEEVENTF_HWHEEL, unsafe { transmute(length * 120) }, 0, 0);
    }

    fn mouse_scroll_y(&mut self, length: i32) {
        mouse_event(MOUSEEVENTF_WHEEL, unsafe { transmute(length * 120) }, 0, 0);
    }
}

impl KeyboardControllable for Enigo {
    fn key_sequence(&mut self, sequence: &str) {
        let mut buffer = [0; 2];

        for c in sequence.chars() {
            // Windows uses uft-16 encoding. We need to check
            // for variable length characters. As such some
            // characters can be 32 bit long and those are
            // encoded in such called hight and low surrogates
            // each 16 bit wide that needs to be send after
            // another to the SendInput function without
            // being interrupted by "keyup"
            let result = c.encode_utf16(&mut buffer);
            if result.len() == 1 {
                self.unicode_key_click(result[0]);
            } else {
                for utf16_surrogate in result {
                    self.unicode_key_down(utf16_surrogate.clone());
                }
                // do i need to produce a keyup?
                // self.unicode_key_up(0);
            }
        }
    }

    fn key_click(&mut self, key: Key) {
        let scancode = self.key_to_scancode(key);
        use std::{thread, time};
        keybd_event(KEYEVENTF_SCANCODE, 0, scancode);
        thread::sleep(time::Duration::from_millis(20));
        keybd_event(KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE, 0, scancode);
    }

    fn key_down(&mut self, key: Key) {
        keybd_event(KEYEVENTF_SCANCODE, 0, self.key_to_scancode(key));
    }

    fn key_up(&mut self, key: Key) {
        keybd_event(
            KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE,
            0,
            self.key_to_scancode(key),
        );
    }
}

impl Enigo {
    /// Gets the (width, height) of the main display in screen coordinates (pixels).
    ///
    /// # Example
    ///
    /// ```no_run
    /// use enigo::*;
    /// let mut size = Enigo::main_display_size();
    /// ```
    pub fn main_display_size() -> (usize, usize) {
      let w = unsafe { GetSystemMetrics(SM_CXSCREEN) as usize };
      let h = unsafe { GetSystemMetrics(SM_CYSCREEN) as usize };
      (w, h)
    }

    /// Gets the location of mouse in screen coordinates (pixels).
    ///
    /// # Example
    ///
    /// ```no_run
    /// use enigo::*;
    /// let mut location = Enigo::mouse_location();
    /// ```
    pub fn mouse_location() -> (i32, i32) {
        let mut point = POINT { x: 0, y: 0 };
        let result = unsafe { GetCursorPos(&mut point) };
        if result != 0 {
          (point.x, point.y)
        } else {
          (0, 0)
        }
    }

    fn unicode_key_click(&self, unicode_char: u16) {
        use std::{thread, time};
        self.unicode_key_down(unicode_char);
        thread::sleep(time::Duration::from_millis(20));
        self.unicode_key_up(unicode_char);
    }

    fn unicode_key_down(&self, unicode_char: u16) {
        keybd_event(KEYEVENTF_UNICODE, 0, unicode_char);
    }

    fn unicode_key_up(&self, unicode_char: u16) {
        keybd_event(KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, 0, unicode_char);
    }

    fn key_to_keycode(&self, key: Key) -> u16 {
        // do not use the codes from crate winapi they're
        // wrongly typed with i32 instead of i16 use the
        // ones provided by win/keycodes.rs that are prefixed
        // with an 'E' infront of the original name
        #[allow(deprecated)]
        // I mean duh, we still need to support deprecated keys until they're removed
        match key {
            Key::Alt => EVK_MENU,
            Key::Backspace => EVK_BACK,
            Key::CapsLock => EVK_CAPITAL,
            Key::Control => EVK_LCONTROL,
            Key::Delete => EVK_DELETE,
            Key::DownArrow => EVK_DOWN,
            Key::End => EVK_END,
            Key::Escape => EVK_ESCAPE,
            Key::F1 => EVK_F1,
            Key::F10 => EVK_F10,
            Key::F11 => EVK_F11,
            Key::F12 => EVK_F12,
            Key::F2 => EVK_F2,
            Key::F3 => EVK_F3,
            Key::F4 => EVK_F4,
            Key::F5 => EVK_F5,
            Key::F6 => EVK_F6,
            Key::F7 => EVK_F7,
            Key::F8 => EVK_F8,
            Key::F9 => EVK_F9,
            Key::Home => EVK_HOME,
            Key::LeftArrow => EVK_LEFT,
            Key::Option => EVK_MENU,
            Key::PageDown => EVK_NEXT,
            Key::PageUp => EVK_PRIOR,
            Key::Return => EVK_RETURN,
            Key::RightArrow => EVK_RIGHT,
            Key::Shift => EVK_SHIFT,
            Key::Space => EVK_SPACE,
            Key::Tab => EVK_TAB,
            Key::UpArrow => EVK_UP,

            Key::Raw(raw_keycode) => raw_keycode,
            Key::Layout(c) => self.get_layoutdependent_keycode(c.to_string()),
            //_ => 0,
            Key::Super | Key::Command | Key::Windows | Key::Meta => EVK_LWIN,
        }
    }

    fn key_to_scancode(&self, key: Key) -> u16 {
        let keycode = self.key_to_keycode(key);
        unsafe { MapVirtualKeyW(keycode as u32, 0) as u16 }
    }

    fn get_layoutdependent_keycode(&self, string: String) -> u16 {
        let mut buffer = [0; 2];
        // get the first char from the string ignore the rest
        // ensure its not a multybyte char
        let utf16 = string
            .chars()
            .nth(0)
            .expect("no valid input") //TODO(dustin): no panic here make an error
            .encode_utf16(&mut buffer);
        if utf16.len() != 1 {
            // TODO(dustin) don't panic here use an apropriate errors
            panic!("this char is not allowd");
        }
        // NOTE VkKeyScanW uses the current keyboard layout
        // to specify a layout use VkKeyScanExW and GetKeyboardLayout
        // or load one with LoadKeyboardLayoutW
        let keycode_and_shiftstate = unsafe { VkKeyScanW(utf16[0]) };
        // 0x41 as u16 //key that has the letter 'a' on it on english like keylayout
        keycode_and_shiftstate as u16
    }
}
<|endoftext|>


<commit_before>use rand::distributions::Alphanumeric;
use rand::Rng;
use vergen::{generate_cargo_keys, ConstantsFlags};

fn main() {
    let mut flags = ConstantsFlags::all();
    flags.toggle(ConstantsFlags::REBUILD_ON_HEAD_CHANGE);
    generate_cargo_keys(ConstantsFlags::all()).expect("Unable to generate the cargo keys!");

    let build_id: String = rand::thread_rng()
        .sample_iter(Alphanumeric)
        .take(8)
        .map(char::from)
        .collect();

    println!("cargo:rustc-env=LIBRESPOT_BUILD_ID={}", build_id);
}
<commit_msg>Allow to override build_id with SOURCE_DATE_EPOCH<commit_after>use rand::distributions::Alphanumeric;
use rand::Rng;
use std::env;
use vergen::{generate_cargo_keys, ConstantsFlags};

fn main() {
    let mut flags = ConstantsFlags::all();
    flags.toggle(ConstantsFlags::REBUILD_ON_HEAD_CHANGE);
    generate_cargo_keys(ConstantsFlags::all()).expect("Unable to generate the cargo keys!");

    let build_id: String;
    match env::var("SOURCE_DATE_EPOCH") {
        Ok(val) => build_id = val,
        Err(_) => {
            build_id = rand::thread_rng()
                .sample_iter(Alphanumeric)
                .take(8)
                .map(char::from)
                .collect()
        }
    }

    println!("cargo:rustc-env=LIBRESPOT_BUILD_ID={}", build_id);
}
<|endoftext|>


<commit_before>extern crate url;

use crate::config::{Config, EnvConfig};
use crate::error::{Error, Result};
use crate::github_api;

#[derive(PartialEq, Debug)]
pub enum Page {
    Existing {
        url: String,
    },
    New {
        author: String,
        repo: String,
        default_branch: String,
        branch: String,
    },
}

fn find_github_pr_url_for_branch<B: AsRef<str>>(
    branch: B,
    endpoint: &str,
    author: &str,
    repo: &str,
    env: &EnvConfig,
) -> Result<Page> {
    let branch = branch.as_ref();
    let token = if endpoint == "api.github.com" {
        &env.github_token
    } else {
        if env.ghe_token.is_none() {
            return Err(Error::GheTokenRequired);
        }
        &env.ghe_token
    };
    let client = github_api::Client::build(endpoint, token.as_ref(), &env.https_proxy)?;

    // Note: Search pull request URL in the case where the repository is an original, not a fork.
    // Author should not be set since original repository's owner may be different from current
    // user (e.g. organization name). And multiple branches which has the same name cannot exist
    // in one repository.
    if let Some(url) = client.find_pr_url(branch, author, repo, None)? {
        return Ok(Page::Existing { url });
    }

    let fetched_repo = client.repo(author, repo)?;
    if let Some(parent) = fetched_repo.parent {
        let owner = parent.owner.login;
        let repo = parent.name;

        // Note: Search pull request URL in the case where the repository was forked from original.
        // Author should be set since other person may create another pull request with the same branch name.
        if let Some(url) =
            client.find_pr_url(branch, owner.as_str(), repo.as_str(), Some(author))?
        {
            Ok(Page::Existing { url })
        } else {
            Ok(Page::New {
                author: owner,
                repo,
                default_branch: parent.default_branch,
                branch: branch.to_string(),
            })
        }
    } else {
        Ok(Page::New {
            author: author.to_string(),
            repo: repo.to_string(),
            default_branch: fetched_repo.default_branch,
            branch: branch.to_string(),
        })
    }
}

pub fn find_page(endpoint: &str, author: &str, repo: &str, cfg: &Config) -> Result<Page> {
    match cfg.branch {
        Some(ref b) => find_github_pr_url_for_branch(b, endpoint, author, repo, &cfg.env),
        None => {
            if let Some(git) = cfg.git() {
                find_github_pr_url_for_branch(
                    git.current_branch()?,
                    endpoint,
                    author,
                    repo,
                    &cfg.env,
                )
            } else {
                Err(Error::NoLocalRepoFound {
                    operation: "opening a pull request without specifying branch".to_string(),
                })
            }
        }
    }
}
<commit_msg>use std::borrow::Cow to handle String and &str<commit_after>extern crate url;

use crate::config::{Config, EnvConfig};
use crate::error::{Error, Result};
use crate::github_api;
use std::borrow::Cow;

#[derive(PartialEq, Debug)]
pub enum Page<'a, 'b> {
    Existing {
        url: String,
    },
    New {
        author: Cow<'a, str>,
        repo: Cow<'b, str>,
        default_branch: String,
        branch: String,
    },
}

fn find_github_pr_url_for_branch<'a, 'b, B: AsRef<str>>(
    branch: B,
    endpoint: &str,
    author: &'a str,
    repo: &'b str,
    env: &EnvConfig,
) -> Result<Page<'a, 'b>> {
    let branch = branch.as_ref();
    let token = if endpoint == "api.github.com" {
        &env.github_token
    } else {
        if env.ghe_token.is_none() {
            return Err(Error::GheTokenRequired);
        }
        &env.ghe_token
    };
    let client = github_api::Client::build(endpoint, token.as_ref(), &env.https_proxy)?;

    // Note: Search pull request URL in the case where the repository is an original, not a fork.
    // Author should not be set since original repository's owner may be different from current
    // user (e.g. organization name). And multiple branches which has the same name cannot exist
    // in one repository.
    if let Some(url) = client.find_pr_url(branch, author, repo, None)? {
        return Ok(Page::Existing { url });
    }

    let fetched_repo = client.repo(author, repo)?;
    if let Some(parent) = fetched_repo.parent {
        let owner = parent.owner.login;
        let repo = parent.name;

        // Note: Search pull request URL in the case where the repository was forked from original.
        // Author should be set since other person may create another pull request with the same branch name.
        if let Some(url) =
            client.find_pr_url(branch, owner.as_str(), repo.as_str(), Some(author))?
        {
            Ok(Page::Existing { url })
        } else {
            Ok(Page::New {
                author: Cow::Owned(owner),
                repo: Cow::Owned(repo),
                default_branch: parent.default_branch,
                branch: branch.to_string(),
            })
        }
    } else {
        Ok(Page::New {
            author: Cow::Borrowed(author),
            repo: Cow::Borrowed(repo),
            default_branch: fetched_repo.default_branch,
            branch: branch.to_string(),
        })
    }
}

pub fn find_page<'a, 'b>(
    endpoint: &str,
    author: &'a str,
    repo: &'b str,
    cfg: &Config,
) -> Result<Page<'a, 'b>> {
    match cfg.branch {
        Some(ref b) => find_github_pr_url_for_branch(b, endpoint, author, repo, &cfg.env),
        None => {
            if let Some(git) = cfg.git() {
                find_github_pr_url_for_branch(
                    git.current_branch()?,
                    endpoint,
                    author,
                    repo,
                    &cfg.env,
                )
            } else {
                Err(Error::NoLocalRepoFound {
                    operation: "opening a pull request without specifying branch".to_string(),
                })
            }
        }
    }
}
<|endoftext|>


<commit_before>use ray::{Ray, RayCast, RayIntersection};
use geom::Mesh;
use math::Scalar;

#[cfg(dim3)]
use nalgebra::na::Vec2;
#[cfg(dim3)]
use ray;
#[cfg(dim3)]
use std::num::Zero;
#[cfg(dim3)]
use nalgebra::na::Norm;
#[cfg(dim3)]
use nalgebra::na;
#[cfg(dim3)]
use math::Vect;

impl RayCast for Mesh {
    fn toi_with_ray(&self, ray: &Ray, _: bool) -> Option<Scalar> {
        self.bvt().cast_ray(
                ray,
                &mut |b, r| self.element_at(*b).toi_with_ray(r, true).map(|t| (t.clone(), t))
            ).map(|(_, res, _)| res)
    }

    fn toi_and_normal_with_ray(&self, ray: &Ray, _: bool) -> Option<RayIntersection> {
        self.bvt().cast_ray(
            ray,
            &mut |b, r| self.element_at(*b).toi_and_normal_with_ray(r, true).map(
                |inter| (inter.toi.clone(), inter))).map(
                    |(_, res, _)| res)
    }

    #[cfg(dim3)]
    fn toi_and_normal_and_uv_with_ray(&self, ray: &Ray, _: bool) -> Option<RayIntersection> {
        if !self.margin().is_zero() || self.uvs().is_none() {
            return self.toi_and_normal_with_ray(ray, true);
        }

        let cast = self.bvt().cast_ray(
            ray,
            &mut |b, r| {
                let vs: &[Vect] = self.vertices().as_slice();
                let i           = *b * 3;
                let is          = self.indices().slice(i, i + 3);

                ray::triangle_ray_intersection(&vs[is[0]], &vs[is[1]], &vs[is[2]], r).map(|inter|
                    (inter.ref0().toi.clone(), inter))
            });

        match cast {
            None                   => None,
            Some((_, inter, best)) => {
                let toi = inter.ref0().toi;
                let n   = inter.ref0().normal;
                let uv  = inter.val1(); // barycentric coordinates to compute the exact uvs.

                let ibest = *best * 3;
                let is    = self.indices().slice(ibest, ibest + 3);
                let uvs   = self.uvs().as_ref().unwrap();

                let uv1 = uvs.get(is[0]).clone();
                let uv2 = uvs.get(is[1]).clone();
                let uv3 = uvs.get(is[2]).clone();

                let uvx = uv1.x * uv.x + uv2.x * uv.y + uv3.x * uv.z;
                let uvy = uv1.y * uv.x + uv2.y * uv.y + uv3.y * uv.z;

                // XXX: this interpolation should be done on the two other ray cast too!
                match *self.normals() {
                    None         => {
                        Some(RayIntersection::new_with_uvs(toi, n, Some(Vec2::new(uvx, uvy))))
                    },
                    Some(ref ns) => {
                        let n1 = ns.get(is[0]);
                        let n2 = ns.get(is[1]);
                        let n3 = ns.get(is[2]);

                        let mut n123 = n1 * uv.x + n2 * uv.y + n3 * uv.z;

                        if n123.normalize().is_zero() {
                            Some(RayIntersection::new_with_uvs(toi, n, Some(Vec2::new(uvx, uvy))))
                        }
                        else {
                            if na::dot(&n123, &ray.dir) > na::zero() {
                                Some(RayIntersection::new_with_uvs(toi, -n123, Some(Vec2::new(uvx, uvy))))
                            }
                            else {
                                Some(RayIntersection::new_with_uvs(toi, n123, Some(Vec2::new(uvx, uvy))))
                            }
                        }
                    }
                }
            }
        }
    }
}
<commit_msg>Correctly forward the `solid` argument for a ray-cast against a mesh with a not-zero margin.<commit_after>use std::num::Zero;
use ray::{Ray, RayCast, RayIntersection};
use geom::Mesh;
use math::Scalar;

#[cfg(dim3)]
use nalgebra::na::Vec2;
#[cfg(dim3)]
use ray;
#[cfg(dim3)]
use std::num::Zero;
#[cfg(dim3)]
use nalgebra::na::Norm;
#[cfg(dim3)]
use nalgebra::na;
#[cfg(dim3)]
use math::Vect;

impl RayCast for Mesh {
    fn toi_with_ray(&self, ray: &Ray, solid: bool) -> Option<Scalar> {
        let solid = solid || self.margin().is_zero(); // The `solid` flag is useless if we have no margin.

        self.bvt().cast_ray(
                ray,
                &mut |b, r| self.element_at(*b).toi_with_ray(r, solid).map(|t| (t.clone(), t))
            ).map(|(_, res, _)| res)
    }

    fn toi_and_normal_with_ray(&self, ray: &Ray, solid: bool) -> Option<RayIntersection> {
        let solid = solid || self.margin().is_zero();

        self.bvt().cast_ray(
            ray,
            &mut |b, r| self.element_at(*b).toi_and_normal_with_ray(r, solid).map(
                |inter| (inter.toi.clone(), inter))).map(
                    |(_, res, _)| res)
    }

    #[cfg(dim3)]
    fn toi_and_normal_and_uv_with_ray(&self, ray: &Ray, solid: bool) -> Option<RayIntersection> {
        if !self.margin().is_zero() || self.uvs().is_none() {
            return self.toi_and_normal_with_ray(ray, solid);
        }

        let cast = self.bvt().cast_ray(
            ray,
            &mut |b, r| {
                let vs: &[Vect] = self.vertices().as_slice();
                let i           = *b * 3;
                let is          = self.indices().slice(i, i + 3);

                ray::triangle_ray_intersection(&vs[is[0]], &vs[is[1]], &vs[is[2]], r).map(|inter|
                    (inter.ref0().toi.clone(), inter))
            });

        match cast {
            None                   => None,
            Some((_, inter, best)) => {
                let toi = inter.ref0().toi;
                let n   = inter.ref0().normal;
                let uv  = inter.val1(); // barycentric coordinates to compute the exact uvs.

                let ibest = *best * 3;
                let is    = self.indices().slice(ibest, ibest + 3);
                let uvs   = self.uvs().as_ref().unwrap();

                let uv1 = uvs.get(is[0]).clone();
                let uv2 = uvs.get(is[1]).clone();
                let uv3 = uvs.get(is[2]).clone();

                let uvx = uv1.x * uv.x + uv2.x * uv.y + uv3.x * uv.z;
                let uvy = uv1.y * uv.x + uv2.y * uv.y + uv3.y * uv.z;

                // XXX: this interpolation should be done on the two other ray cast too!
                match *self.normals() {
                    None         => {
                        Some(RayIntersection::new_with_uvs(toi, n, Some(Vec2::new(uvx, uvy))))
                    },
                    Some(ref ns) => {
                        let n1 = ns.get(is[0]);
                        let n2 = ns.get(is[1]);
                        let n3 = ns.get(is[2]);

                        let mut n123 = n1 * uv.x + n2 * uv.y + n3 * uv.z;

                        if n123.normalize().is_zero() {
                            Some(RayIntersection::new_with_uvs(toi, n, Some(Vec2::new(uvx, uvy))))
                        }
                        else {
                            if na::dot(&n123, &ray.dir) > na::zero() {
                                Some(RayIntersection::new_with_uvs(toi, -n123, Some(Vec2::new(uvx, uvy))))
                            }
                            else {
                                Some(RayIntersection::new_with_uvs(toi, n123, Some(Vec2::new(uvx, uvy))))
                            }
                        }
                    }
                }
            }
        }
    }
}
<|endoftext|>


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

use std::collections::BTreeMap;
use std::io;
use inflections::Inflect;

use CodeGenerator;
use specs::Constant;

pub struct FrameEnumWriter<'a> {
    frame_types: &'a BTreeMap<&'static str,  Constant>,
}

impl<'a> FrameEnumWriter<'a> {
    pub fn new(frame_types: &'a BTreeMap<&'static str, Constant>) -> Self {
        FrameEnumWriter {
            frame_types: frame_types,
        }
    }
}

impl<'a> CodeGenerator for FrameEnumWriter<'a> {
    fn write_rust_to<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.frame_types.is_empty() {
            return Ok(())
        }

        try!(writeln!(writer, "enum Frame {{"));
        for frame_type in self.frame_types.keys() {
            let name_start = if frame_type.starts_with("frame-") { 6 } else { 0 };
            let pascal_case = (&frame_type[name_start..]).to_pascal_case();
            try!(writeln!(writer, "{},", pascal_case));
        }
        try!(writeln!(writer, "}}"));

        Ok(())
    }
}<commit_msg>[primitives] Make the spec `Frame` public<commit_after>// Copyright 2016 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::BTreeMap;
use std::io;
use inflections::Inflect;

use CodeGenerator;
use specs::Constant;

pub struct FrameEnumWriter<'a> {
    frame_types: &'a BTreeMap<&'static str,  Constant>,
}

impl<'a> FrameEnumWriter<'a> {
    pub fn new(frame_types: &'a BTreeMap<&'static str, Constant>) -> Self {
        FrameEnumWriter {
            frame_types: frame_types,
        }
    }
}

impl<'a> CodeGenerator for FrameEnumWriter<'a> {
    fn write_rust_to<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.frame_types.is_empty() {
            return Ok(())
        }

        try!(writeln!(writer, "pub enum Frame {{"));
        for frame_type in self.frame_types.keys() {
            let name_start = if frame_type.starts_with("frame-") { 6 } else { 0 };
            let pascal_case = (&frame_type[name_start..]).to_pascal_case();
            try!(writeln!(writer, "{},", pascal_case));
        }
        try!(writeln!(writer, "}}"));

        Ok(())
    }
}<|endoftext|>


<commit_before>use std;

// enum
export addr_family;
export socket_type;
export protocol_type;

// fn
export accept;
export bind_;
export close;
export connect;
export inet_addr;
export listen;
export new_sockaddr_in;
export new_socket;
export new_tcp_socket;
export recv;
export send;
export send_str;

import core::ctypes::*;
import core::result::{ok, err};

import const_from_enum::*;

mod const_from_enum {
    #[cfg(target_os = "macos")]
    fn AF_(af: addr_family) -> c_int {
        ret alt af {
            af_inet { 2 }
            af_inet6 { 30 }
        } as c_int;
    }

    #[cfg(target_os = "linux")]
    fn AF_(af: addr_family) -> c_int {
        ret alt af {
            af_inet { 2 }
            af_inet6 { 10 }
        } as c_int;
    }

    fn SOCK_(st: socket_type) -> c_int {
        ret alt st {
            sock_stream { 1 }
            sock_dgram { 2 }
        } as c_int;
    }

    fn IPPROTO_(pt: protocol_type) -> c_int {
        ret alt pt {
            ipproto_ip { 0 }
        } as c_int;
    }
}

// FIXME: fill missing enums

#[cfg(target_os = "macos")]
enum addr_family {
    af_inet = 2,
    af_inet6 = 26,
}

#[cfg(target_os = "linux")]
enum addr_family {
    af_inet = 2,
    af_inet6 = 10,
}

enum socket_type {
    sock_stream = 1,
    sock_dgram = 2,
}

enum protocol_type {
    ipproto_ip = 0,
}

type in_addr = {
    s_addr: u32,
};

type sockaddr_in = {
    mutable sin_len: u8,
    mutable sin_family: i8,
    mutable sin_port: u16,
    mutable sin_addr: in_addr,
    mutable sin_zero: u64,
};

#[cfg(target_os = "linux")] // untested
#[cfg(target_os = "macos")]
#[nolink]
#[abi = "cdecl"]
native mod libc {
    fn accept(socket: c_int, address: *mutable sockaddr_in, address_len: *mutable uint32_t) -> c_int;
    fn bind(socket: c_int, address: *sockaddr_in, address_len: uint32_t) -> c_int;
    fn close(socket: c_int);
    fn connect(socket: c_int, address: *sockaddr_in, address_len: uint32_t) -> c_int;
    fn socket(af: c_int, type_: c_int, protocol: c_int) -> c_int;
    fn htons(host: u16) -> u16;
    fn inet_addr(cp: *u8) -> u32;
    fn listen(socket: c_int, backlog: c_int) -> c_int;
    fn recv(socket: c_int, buffer: uintptr_t, length: size_t, flags: c_int) -> ssize_t;
    fn send(socket: c_int, buffer: uintptr_t, length: size_t, flags: c_int) -> ssize_t;
}

resource socket(s: c_int) {
    libc::close(s);
}

fn new_socket(af: addr_family, st: socket_type, pt: protocol_type) -> socket {
    ret _new_socket(af, st, pt);

    #[cfg(target_os = "linux")] // untested
    #[cfg(target_os = "macos")]
    fn _new_socket(af: addr_family, st: socket_type, pt: protocol_type) -> socket {
        let s = libc::socket(af as c_int, st as c_int, pt as c_int);
        ret socket(s);
    }
}

fn new_tcp_socket() -> socket {
    ret new_socket(af_inet, sock_stream, ipproto_ip);
}

fn new_udp_socket() -> socket {
    ret new_socket(af_inet, sock_dgram, ipproto_ip);
}

fn new_sockaddr_in(af: addr_family, addr: u32, port: u16) -> sockaddr_in {
    ret _new_sockaddr_in(af, addr, port);

    fn _new_sockaddr_in(af: addr_family, addr: u32, port: u16) -> sockaddr_in {
        ret {
            mutable sin_len: 16 as u8,
            mutable sin_family: af as i8,
            mutable sin_port: libc::htons(port),
            mutable sin_addr: {s_addr: addr},
            mutable sin_zero: 0u64,
        };
    }
}

fn connect(s: socket, +a: sockaddr_in) -> result::t<int, int> {
    let c_sock = *s;
    let r = libc::connect(c_sock, ptr::addr_of(a), 16 as uint32_t) as int;
    ret alt r { 0 { ok(r) } _ { err(r) } };
}

fn bind_(s: socket, +a: sockaddr_in) -> result::t<int, int> {
    let c_sock = *s;
    let r = libc::bind(c_sock, ptr::addr_of(a), 16 as uint32_t) as int;
    ret alt r { 0 { ok(r) } _ { err(r) } };
}

fn listen(s: socket, backlog: int) -> int {
    ret libc::listen(*s, backlog as c_int) as int;
}

fn accept(s: socket, &a: sockaddr_in) -> socket {
    let addr_len = 0 as uint32_t;
    let c_sock = libc::accept(*s, ptr::mut_addr_of(a), ptr::mut_addr_of(addr_len));
    ret socket(c_sock);
}

// FIXME: rename to inet_aton() ?
fn inet_addr(str_addr: str) -> u32 {
    ret str::as_buf(str_addr) {|a| libc::inet_addr(a) };
}

// FIXME: take size
fn send(s: socket, buf: [const u8], flags: uint) -> int unsafe {
    let sz = libc::send(*s,
                        vec::unsafe::to_ptr(buf) as uintptr_t,
                        vec::len(buf),
                        flags as c_int);
    ret sz as int;
}

fn send_str(s: socket, buf: str, flags: uint) -> int unsafe {
    let saddr = ptr::addr_of(buf);
    let vaddr: *[u8] = ::unsafe::reinterpret_cast(saddr);
    ret send(s, *vaddr, flags);
}

fn recv(s: socket, &buf: [mutable u8], flags: uint) -> int unsafe {
    let sz = libc::recv(*s,
                        vec::unsafe::to_ptr(buf) as uintptr_t,
                        vec::len(buf),
                        flags as c_int);
    ret sz as int;
}

// FIXME: This may not be used
fn close(s: socket) {
    libc::close(*s);
}
<commit_msg>const_from_enum no longer needed<commit_after>use std;

// enum
export addr_family;
export socket_type;
export protocol_type;

// fn
export accept;
export bind_;
export close;
export connect;
export inet_addr;
export listen;
export new_sockaddr_in;
export new_socket;
export new_tcp_socket;
export recv;
export send;
export send_str;

import core::ctypes::*;
import core::result::{ok, err};

// FIXME: fill missing enums

#[cfg(target_os = "macos")]
enum addr_family {
    af_inet = 2,
    af_inet6 = 26,
}

#[cfg(target_os = "linux")]
enum addr_family {
    af_inet = 2,
    af_inet6 = 10,
}

enum socket_type {
    sock_stream = 1,
    sock_dgram = 2,
}

enum protocol_type {
    ipproto_ip = 0,
}

type in_addr = {
    s_addr: u32,
};

type sockaddr_in = {
    mutable sin_len: u8,
    mutable sin_family: i8,
    mutable sin_port: u16,
    mutable sin_addr: in_addr,
    mutable sin_zero: u64,
};

#[cfg(target_os = "linux")] // untested
#[cfg(target_os = "macos")]
#[nolink]
#[abi = "cdecl"]
native mod libc {
    fn accept(socket: c_int, address: *mutable sockaddr_in, address_len: *mutable uint32_t) -> c_int;
    fn bind(socket: c_int, address: *sockaddr_in, address_len: uint32_t) -> c_int;
    fn close(socket: c_int);
    fn connect(socket: c_int, address: *sockaddr_in, address_len: uint32_t) -> c_int;
    fn socket(af: c_int, type_: c_int, protocol: c_int) -> c_int;
    fn htons(host: u16) -> u16;
    fn inet_addr(cp: *u8) -> u32;
    fn listen(socket: c_int, backlog: c_int) -> c_int;
    fn recv(socket: c_int, buffer: uintptr_t, length: size_t, flags: c_int) -> ssize_t;
    fn send(socket: c_int, buffer: uintptr_t, length: size_t, flags: c_int) -> ssize_t;
}

resource socket(s: c_int) {
    libc::close(s);
}

fn new_socket(af: addr_family, st: socket_type, pt: protocol_type) -> socket {
    ret _new_socket(af, st, pt);

    #[cfg(target_os = "linux")] // untested
    #[cfg(target_os = "macos")]
    fn _new_socket(af: addr_family, st: socket_type, pt: protocol_type) -> socket {
        let s = libc::socket(af as c_int, st as c_int, pt as c_int);
        ret socket(s);
    }
}

fn new_tcp_socket() -> socket {
    ret new_socket(af_inet, sock_stream, ipproto_ip);
}

fn new_udp_socket() -> socket {
    ret new_socket(af_inet, sock_dgram, ipproto_ip);
}

fn new_sockaddr_in(af: addr_family, addr: u32, port: u16) -> sockaddr_in {
    ret _new_sockaddr_in(af, addr, port);

    fn _new_sockaddr_in(af: addr_family, addr: u32, port: u16) -> sockaddr_in {
        ret {
            mutable sin_len: 16 as u8,
            mutable sin_family: af as i8,
            mutable sin_port: libc::htons(port),
            mutable sin_addr: {s_addr: addr},
            mutable sin_zero: 0u64,
        };
    }
}

fn connect(s: socket, +a: sockaddr_in) -> result::t<int, int> {
    let c_sock = *s;
    let r = libc::connect(c_sock, ptr::addr_of(a), 16 as uint32_t) as int;
    ret alt r { 0 { ok(r) } _ { err(r) } };
}

fn bind_(s: socket, +a: sockaddr_in) -> result::t<int, int> {
    let c_sock = *s;
    let r = libc::bind(c_sock, ptr::addr_of(a), 16 as uint32_t) as int;
    ret alt r { 0 { ok(r) } _ { err(r) } };
}

fn listen(s: socket, backlog: int) -> int {
    ret libc::listen(*s, backlog as c_int) as int;
}

fn accept(s: socket, &a: sockaddr_in) -> socket {
    let addr_len = 0 as uint32_t;
    let c_sock = libc::accept(*s, ptr::mut_addr_of(a), ptr::mut_addr_of(addr_len));
    ret socket(c_sock);
}

// FIXME: rename to inet_aton() ?
fn inet_addr(str_addr: str) -> u32 {
    ret str::as_buf(str_addr) {|a| libc::inet_addr(a) };
}

// FIXME: take size
fn send(s: socket, buf: [const u8], flags: uint) -> int unsafe {
    let sz = libc::send(*s,
                        vec::unsafe::to_ptr(buf) as uintptr_t,
                        vec::len(buf),
                        flags as c_int);
    ret sz as int;
}

fn send_str(s: socket, buf: str, flags: uint) -> int unsafe {
    let saddr = ptr::addr_of(buf);
    let vaddr: *[u8] = ::unsafe::reinterpret_cast(saddr);
    ret send(s, *vaddr, flags);
}

fn recv(s: socket, &buf: [mutable u8], flags: uint) -> int unsafe {
    let sz = libc::recv(*s,
                        vec::unsafe::to_ptr(buf) as uintptr_t,
                        vec::len(buf),
                        flags as c_int);
    ret sz as int;
}

// FIXME: This may not be used
fn close(s: socket) {
    libc::close(*s);
}
<|endoftext|>


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

// Some unusual code minimized from
// https://github.com/sile/handy_async/tree/7b619b762c06544fc67792c8ff8ebc24a88fdb98

pub trait Pattern {
    type Value;
}

pub struct Constrain<A, B = A, C = A>(A, B, C);

impl<A, B, C> Pattern for Constrain<A, B, C>
    where A: Pattern,
          B: Pattern<Value = A::Value>,
          C: Pattern<Value = A::Value>,
{
    type Value = A::Value;
}

pub struct Wrapper<T>(T);

impl<T> Pattern for Wrapper<T> {
    type Value = T;
}

// @has self_referential/struct.WriteAndThen.html
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<P1> Send for \
// WriteAndThen<P1>  where  <P1 as Pattern>::Value: Send"
pub struct WriteAndThen<P1>(pub P1::Value, pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
    where P1: Pattern;

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

// Some unusual code minimized from
// https://github.com/sile/handy_async/tree/7b619b762c06544fc67792c8ff8ebc24a88fdb98

pub trait Pattern {
    type Value;
}

pub struct Constrain<A, B = A, C = A>(A, B, C);

impl<A, B, C> Pattern for Constrain<A, B, C>
    where A: Pattern,
          B: Pattern<Value = A::Value>,
          C: Pattern<Value = A::Value>,
{
    type Value = A::Value;
}

pub struct Wrapper<T>(T);

impl<T> Pattern for Wrapper<T> {
    type Value = T;
}

// @has self_referential/struct.WriteAndThen.html
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<P1> Send for \
// WriteAndThen<P1>  where  <P1 as Pattern>::Value: Send"
pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
    where P1: Pattern;

<|endoftext|>