<commit_before>
/// Trait for fixed size arrays.
///
/// This trait is implemented for some specific array sizes, see
/// the implementor list below. At the current state of Rust we can't
/// make this fully general for every array size.
///
/// The following crate features add more array sizes (and they are not
/// enabled by default due to their impact on compliation speed).
///
/// - `array-sizes-33-128`: All sizes 33 to 128 are implemented
///   (a few in this range are included by default).
/// - `array-sizes-129-255`: All sizes 129 to 255 are implemented
///   (a few in this range are included by default).
pub unsafe trait Array {
    /// The array’s element type
    type Item;
    /// The smallest type that can index and tell the length of the array.
    #[doc(hidden)]
    type Index: Index;
    /// The array's element capacity
    const CAPACITY: usize;
    #[doc(hidden)]
    fn as_ptr(&self) -> *const Self::Item;
    #[doc(hidden)]
    fn as_mut_ptr(&mut self) -> *mut Self::Item;
    #[doc(hidden)]
    fn capacity() -> usize;
}

pub trait Index : PartialEq + Copy {
    fn to_usize(self) -> usize;
    fn from(usize) -> Self;
}

use std::slice::{from_raw_parts};

pub trait ArrayExt : Array {
    #[inline(always)]
    fn as_slice(&self) -> &[Self::Item] {
        unsafe {
            from_raw_parts(self.as_ptr(), Self::capacity())
        }
    }
}

impl<A> ArrayExt for A where A: Array { }

impl Index for () {
    #[inline(always)]
    fn to_usize(self) -> usize { 0 }
    #[inline(always)]
    fn from(_ix: usize) ->  Self { () }
}

impl Index for bool {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix != 0 }
}

impl Index for u8 {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix as u8 }
}

impl Index for u16 {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix as u16 }
}

impl Index for u32 {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix as u32 }
}

impl Index for usize {
    #[inline(always)]
    fn to_usize(self) -> usize { self }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix }
}

macro_rules! fix_array_impl {
    ($index_type:ty, $len:expr ) => (
        unsafe impl<T> Array for [T; $len] {
            type Item = T;
            type Index = $index_type;
            const CAPACITY: usize = $len;
            #[doc(hidden)]
            #[inline(always)]
            fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
            #[doc(hidden)]
            #[inline(always)]
            fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
            #[doc(hidden)]
            #[inline(always)]
            fn capacity() -> usize { $len }
        }
    )
}

macro_rules! fix_array_impl_recursive {
    ($index_type:ty, ) => ();
    ($index_type:ty, $($len:expr,)*) => (
        $(fix_array_impl!($index_type, $len);)*
    );
}

fix_array_impl_recursive!((), 0,);
fix_array_impl_recursive!(bool, 1,);
fix_array_impl_recursive!(u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                          15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
                          28, 29, 30, 31, );

#[cfg(not(feature="array-sizes-33-128"))]
fix_array_impl_recursive!(u8, 32, 40, 48, 50, 56, 64, 72, 96, 100, 128, );

#[cfg(feature="array-sizes-33-128")]
fix_array_impl_recursive!(u8,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
125, 126, 127, 128,
);

#[cfg(not(feature="array-sizes-129-255"))]
fix_array_impl_recursive!(u8, 160, 192, 200, 224,);

#[cfg(feature="array-sizes-129-255")]
fix_array_impl_recursive!(u8,
129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
253, 254, 255,
);

fix_array_impl_recursive!(u16, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,);
// This array size doesn't exist on 16-bit
#[cfg(any(target_pointer_width="32", target_pointer_width="64"))]
fix_array_impl_recursive!(u32, 1 << 16,);

<commit_msg>FIX: Remove unused .as_mut_ptr() on the Array trait<commit_after>
/// Trait for fixed size arrays.
///
/// This trait is implemented for some specific array sizes, see
/// the implementor list below. At the current state of Rust we can't
/// make this fully general for every array size.
///
/// The following crate features add more array sizes (and they are not
/// enabled by default due to their impact on compliation speed).
///
/// - `array-sizes-33-128`: All sizes 33 to 128 are implemented
///   (a few in this range are included by default).
/// - `array-sizes-129-255`: All sizes 129 to 255 are implemented
///   (a few in this range are included by default).
pub unsafe trait Array {
    /// The array’s element type
    type Item;
    /// The smallest type that can index and tell the length of the array.
    #[doc(hidden)]
    type Index: Index;
    /// The array's element capacity
    const CAPACITY: usize;
    #[doc(hidden)]
    fn as_ptr(&self) -> *const Self::Item;
    #[doc(hidden)]
    fn capacity() -> usize;
}

pub trait Index : PartialEq + Copy {
    fn to_usize(self) -> usize;
    fn from(usize) -> Self;
}

use std::slice::{from_raw_parts};

pub trait ArrayExt : Array {
    #[inline(always)]
    fn as_slice(&self) -> &[Self::Item] {
        unsafe {
            from_raw_parts(self.as_ptr(), Self::capacity())
        }
    }
}

impl<A> ArrayExt for A where A: Array { }

impl Index for () {
    #[inline(always)]
    fn to_usize(self) -> usize { 0 }
    #[inline(always)]
    fn from(_ix: usize) ->  Self { () }
}

impl Index for bool {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix != 0 }
}

impl Index for u8 {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix as u8 }
}

impl Index for u16 {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix as u16 }
}

impl Index for u32 {
    #[inline(always)]
    fn to_usize(self) -> usize { self as usize }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix as u32 }
}

impl Index for usize {
    #[inline(always)]
    fn to_usize(self) -> usize { self }
    #[inline(always)]
    fn from(ix: usize) ->  Self { ix }
}

macro_rules! fix_array_impl {
    ($index_type:ty, $len:expr ) => (
        unsafe impl<T> Array for [T; $len] {
            type Item = T;
            type Index = $index_type;
            const CAPACITY: usize = $len;
            #[doc(hidden)]
            #[inline(always)]
            fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
            #[doc(hidden)]
            #[inline(always)]
            fn capacity() -> usize { $len }
        }
    )
}

macro_rules! fix_array_impl_recursive {
    ($index_type:ty, ) => ();
    ($index_type:ty, $($len:expr,)*) => (
        $(fix_array_impl!($index_type, $len);)*
    );
}

fix_array_impl_recursive!((), 0,);
fix_array_impl_recursive!(bool, 1,);
fix_array_impl_recursive!(u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                          15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
                          28, 29, 30, 31, );

#[cfg(not(feature="array-sizes-33-128"))]
fix_array_impl_recursive!(u8, 32, 40, 48, 50, 56, 64, 72, 96, 100, 128, );

#[cfg(feature="array-sizes-33-128")]
fix_array_impl_recursive!(u8,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
125, 126, 127, 128,
);

#[cfg(not(feature="array-sizes-129-255"))]
fix_array_impl_recursive!(u8, 160, 192, 200, 224,);

#[cfg(feature="array-sizes-129-255")]
fix_array_impl_recursive!(u8,
129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
253, 254, 255,
);

fix_array_impl_recursive!(u16, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,);
// This array size doesn't exist on 16-bit
#[cfg(any(target_pointer_width="32", target_pointer_width="64"))]
fix_array_impl_recursive!(u32, 1 << 16,);

<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::io::{Error, ErrorKind, Read, Seek, SeekFrom};

use byteorder::{BigEndian, ReadBytesExt};

/// The usage information for an `IndexEntry`.
#[derive(Debug)]
pub enum Usage {
    /// Indentifier: 'Pict'.
    /// Indicates the resource is an image.
    Pict,

    /// Indentifier: 'Snd '.
    /// Indicates the resource is a sound.
    Snd,

    /// Indentifier: 'Data'.
    /// Indicates the resource is some data.
    Data,

    /// Indentifier: 'Exec'.
    /// Indicates the resource is an executable.
    Exec,
}

/// Contains the usage information for an entry, the resource number of
/// the entry, and where in the blob the entry starts.
#[derive(Debug)]
pub struct IndexEntry {
    pub usage: Usage,
    pub num: u32,
    start: u32,
}

/// Container for list of resource index entries.
#[derive(Debug)]
pub struct ResourceIndex {
    pub entries: HashMap<usize, IndexEntry>,
}

/// Container for chunk metadata. Used for identifying a chunk without
/// loading the full chunk into memory.
#[derive(Debug)]
pub struct ChunkData {
    pub id: String,
    len: u32,
}

/// Representation for loaded blorb chunks
pub enum Chunk {

    /// Chunk returned when the loaded chunk type is unable to be
    /// identified. Per Specification, the machine must ignore unknown
    /// chunks, and this type will be used to do so when necessary.
    Unknown{meta: ChunkData, data: Vec<u8>},

    /// Identifier: 'RIdx'.
    /// Contains a resource index for the IF.
    /// This chunk is mandatory and must be the first chunk in the form.
    ResourceIndex{index: ResourceIndex},

    /// Identifier: 'IFmd',
    /// Contains xml metadata content for the IF.
    Metadata{info: String},

    /// Identifier: 'Fspec',
    /// Contains a reference to a frontispiece image.
    /// This chunk is optional.
    Frontispiece{num: u32},

    /// Identifier: 'GLUL',
    /// Contains Glulx executable
    /// This is a executable resource chunk.
    Glulx{code: Vec<u8>},

    /// Identifier: 'PNG ',
    /// Contains a PNG image
    /// This is a picture resource chunk.
    Png{data: Vec<u8>},

    /// Identifier: 'JPEG',
    /// Contains a JPEG image
    /// This is a picture resource chunk.
    Jpeg{data: Vec<u8>},
}

pub struct Blorb<R: Read + Seek> {
    pub form: String,
    pub len: u32,
    index: ResourceIndex,
    file: R,
}

impl<R: Read + Seek> Blorb<R> {

    /// Creates a new Blorb from a file. The code goes through the
    /// given game file, validates the file type, and extracts the
    /// basic game objects for the blorb.
    pub fn from_file(file: R) -> Result<Blorb<R>, Error> {
        let mut file = file;

        // Check that the first byte is the word "FORM"
        let tag = try!(Blorb::load_4bw(&mut file));
        assert_eq!(&tag, "FORM");

        // Get the length of the blorb
        let len = try!(file.read_u32::<BigEndian>());

        // Check that the form type is IFRS
        let form = try!(Blorb::load_4bw(&mut file));
        assert_eq!(&form, "IFRS");

        let index = if let Chunk::ResourceIndex{index} =
                try!(Blorb::load_chunk(&mut file)) {
            index
        } else {
            panic!("corrupt file -- first chunk not resource index");
        };

        Ok(Blorb{
            form: form,
            len: len,
            index: index,
            file: file,
        })
    }

    /// loads a resource using the given index entry.
    pub fn load_resource(&mut self, num: usize) -> Result<Chunk, Error> {
        let entry = match self.index.entries.get(&num) {
            Some(entry) => entry,
            None => {
                return Err(Error::new(
                    ErrorKind::NotFound,
                    "resource not found"
                ))
            },
        };
        try!(self.file.seek(SeekFrom::Start(entry.start as u64)));

        Blorb::load_chunk(&mut self.file)
    }

    fn load_chunk(file: &mut R) -> Result<Chunk, Error> {
        let meta = try!(Blorb::load_chunk_data(file));

        match meta.id.as_ref() {
            "RIdx" => {
                let num = try!(file.read_u32::<BigEndian>());
                let mut entries = HashMap::with_capacity(num as usize);
                for _ in 0..num {
                    let entry = try!(Blorb::load_index_entry(file));
                    entries.insert(entry.num as usize, entry);
                }

                Ok(Chunk::ResourceIndex{index: ResourceIndex{entries:entries}})
            },
            "GLUL" => {
                let mut data = Vec::with_capacity(meta.len as usize);
                try!(file.take(meta.len as u64).read_to_end(&mut data));
                Ok(Chunk::Glulx{code: data})
            },
            _ => {
                let mut data = Vec::with_capacity(meta.len as usize);
                try!(file.take(meta.len as u64).read_to_end(&mut data));
                Ok(Chunk::Unknown{meta: meta, data: data})
            },
        }
    }

    fn load_index_entry(file: &mut R) -> Result<IndexEntry, Error> {
        let usage = try!(Blorb::load_4bw(file));
        let num = try!(file.read_u32::<BigEndian>());
        let start = try!(file.read_u32::<BigEndian>());

        let usage = match usage.as_ref() {
            "Pict" => Usage::Pict,
            "Snd " => Usage::Snd,
            "Data" => Usage::Data,
            "Exec" => Usage::Exec,
            _ => panic!("unrecognized usage type")
        };

        Ok(IndexEntry{usage: usage, num: num, start: start})
    }

    fn load_chunk_data(file: &mut R) -> Result<ChunkData, Error> {
        let id = try!(Blorb::load_4bw(file));
        let len = try!(file.read_u32::<BigEndian>());
        Ok(ChunkData{id: id, len: len})
    }

    /// Load a 4 byte ASCII word from the file
    fn load_4bw(file: &mut R) -> Result<String, Error> {
        let mut id = String::with_capacity(0x4);
        try!(file.take(4).read_to_string(&mut id));
        Ok(id)
    }
}
<commit_msg>removed remaining panics from code<commit_after>use std::collections::HashMap;
use std::io::{Error, ErrorKind, Read, Seek, SeekFrom};

use byteorder::{BigEndian, ReadBytesExt};

/// The usage information for an `IndexEntry`.
#[derive(Debug)]
pub enum Usage {
    /// Indentifier: 'Pict'.
    /// Indicates the resource is an image.
    Pict,

    /// Indentifier: 'Snd '.
    /// Indicates the resource is a sound.
    Snd,

    /// Indentifier: 'Data'.
    /// Indicates the resource is some data.
    Data,

    /// Indentifier: 'Exec'.
    /// Indicates the resource is an executable.
    Exec,
}

/// Contains the usage information for an entry, the resource number of
/// the entry, and where in the blob the entry starts.
#[derive(Debug)]
pub struct IndexEntry {
    pub usage: Usage,
    pub num: u32,
    start: u32,
}

/// Container for list of resource index entries.
#[derive(Debug)]
pub struct ResourceIndex {
    pub entries: HashMap<usize, IndexEntry>,
}

/// Container for chunk metadata. Used for identifying a chunk without
/// loading the full chunk into memory.
#[derive(Debug)]
pub struct ChunkData {
    pub id: String,
    len: u32,
}

/// Representation for loaded blorb chunks
pub enum Chunk {

    /// Chunk returned when the loaded chunk type is unable to be
    /// identified. Per Specification, the machine must ignore unknown
    /// chunks, and this type will be used to do so when necessary.
    Unknown{meta: ChunkData, data: Vec<u8>},

    /// Identifier: 'RIdx'.
    /// Contains a resource index for the IF.
    /// This chunk is mandatory and must be the first chunk in the form.
    ResourceIndex{index: ResourceIndex},

    /// Identifier: 'IFmd',
    /// Contains xml metadata content for the IF.
    Metadata{info: String},

    /// Identifier: 'Fspec',
    /// Contains a reference to a frontispiece image.
    /// This chunk is optional.
    Frontispiece{num: u32},

    /// Identifier: 'GLUL',
    /// Contains Glulx executable
    /// This is a executable resource chunk.
    Glulx{code: Vec<u8>},

    /// Identifier: 'PNG ',
    /// Contains a PNG image
    /// This is a picture resource chunk.
    Png{data: Vec<u8>},

    /// Identifier: 'JPEG',
    /// Contains a JPEG image
    /// This is a picture resource chunk.
    Jpeg{data: Vec<u8>},
}

pub struct Blorb<R: Read + Seek> {
    pub form: String,
    pub len: u32,
    index: ResourceIndex,
    file: R,
}

impl<R: Read + Seek> Blorb<R> {

    /// Creates a new Blorb from a file. The code goes through the
    /// given game file, validates the file type, and extracts the
    /// basic game objects for the blorb.
    pub fn from_file(file: R) -> Result<Blorb<R>, Error> {
        let mut file = file;

        // Check that the first byte is the word "FORM"
        let tag = try!(Blorb::load_4bw(&mut file));
        assert_eq!(&tag, "FORM");

        // Get the length of the blorb
        let len = try!(file.read_u32::<BigEndian>());

        // Check that the form type is IFRS
        let form = try!(Blorb::load_4bw(&mut file));
        assert_eq!(&form, "IFRS");

        let index = if let Chunk::ResourceIndex{index} =
                try!(Blorb::load_chunk(&mut file)) {
            index
        } else {
            return Err(Error::new(
                ErrorKind::InvalidInput,
                "could not locate index"
            ));
        };

        Ok(Blorb{
            form: form,
            len: len,
            index: index,
            file: file,
        })
    }

    /// loads a resource using the given index entry.
    pub fn load_resource(&mut self, num: usize) -> Result<Chunk, Error> {
        let entry = match self.index.entries.get(&num) {
            Some(entry) => entry,
            None => {
                return Err(Error::new(
                    ErrorKind::NotFound,
                    "resource not found"
                ))
            },
        };
        try!(self.file.seek(SeekFrom::Start(entry.start as u64)));

        Blorb::load_chunk(&mut self.file)
    }

    fn load_chunk(file: &mut R) -> Result<Chunk, Error> {
        let meta = try!(Blorb::load_chunk_data(file));

        match meta.id.as_ref() {
            "RIdx" => {
                let num = try!(file.read_u32::<BigEndian>());
                let mut entries = HashMap::with_capacity(num as usize);
                for _ in 0..num {
                    let entry = try!(Blorb::load_index_entry(file));
                    entries.insert(entry.num as usize, entry);
                }

                Ok(Chunk::ResourceIndex{index: ResourceIndex{entries:entries}})
            },
            "GLUL" => {
                let mut data = Vec::with_capacity(meta.len as usize);
                try!(file.take(meta.len as u64).read_to_end(&mut data));
                Ok(Chunk::Glulx{code: data})
            },
            _ => {
                let mut data = Vec::with_capacity(meta.len as usize);
                try!(file.take(meta.len as u64).read_to_end(&mut data));
                Ok(Chunk::Unknown{meta: meta, data: data})
            },
        }
    }

    fn load_index_entry(file: &mut R) -> Result<IndexEntry, Error> {
        let usage = try!(Blorb::load_4bw(file));
        let num = try!(file.read_u32::<BigEndian>());
        let start = try!(file.read_u32::<BigEndian>());

        let usage = match usage.as_ref() {
            "Pict" => Usage::Pict,
            "Snd " => Usage::Snd,
            "Data" => Usage::Data,
            "Exec" => Usage::Exec,
            _ => return Err(Error::new(
                ErrorKind::InvalidInput,
                "could not identify index entry usage"
            )),
        };

        Ok(IndexEntry{usage: usage, num: num, start: start})
    }

    fn load_chunk_data(file: &mut R) -> Result<ChunkData, Error> {
        let id = try!(Blorb::load_4bw(file));
        let len = try!(file.read_u32::<BigEndian>());
        Ok(ChunkData{id: id, len: len})
    }

    /// Load a 4 byte ASCII word from the file
    fn load_4bw(file: &mut R) -> Result<String, Error> {
        let mut id = String::with_capacity(0x4);
        try!(file.take(4).read_to_string(&mut id));
        Ok(id)
    }
}
<|endoftext|>


<commit_before>use std::ptr;
use std::sync::atomic::AtomicBool;

use gobject_subclass::object::*;

#[repr(C)]
pub struct ElementInstanceStruct<T: ObjectType> {
    _parent: T::GlibType,
    _imp: ptr::NonNull<T::ImplType>,

    _panicked: AtomicBool,
}

pub trait PanicPoison {
    fn panicked(&self) -> &AtomicBool;
}

impl<T: ObjectType> Instance<T> for ElementInstanceStruct<T> {
    fn parent(&self) -> &T::GlibType {
        &self._parent
    }

    fn get_impl(&self) -> &T::ImplType {
        unsafe { self._imp.as_ref() }
    }

    unsafe fn set_impl(&mut self, imp: ptr::NonNull<T::ImplType>) {
        self._imp = imp;
    }

    unsafe fn get_class(&self) -> *const ClassStruct<T> {
        *(self as *const _ as *const *const ClassStruct<T>)
    }
}

impl<T: ObjectType> PanicPoison for ElementInstanceStruct<T> {
    fn panicked(&self) -> &AtomicBool {
        &self._panicked
    }
}
<commit_msg>Use unsafe impl for the Instance trait impl<commit_after>use std::ptr;
use std::sync::atomic::AtomicBool;

use gobject_subclass::object::*;

#[repr(C)]
pub struct ElementInstanceStruct<T: ObjectType> {
    _parent: T::GlibType,
    _imp: ptr::NonNull<T::ImplType>,

    _panicked: AtomicBool,
}

pub trait PanicPoison {
    fn panicked(&self) -> &AtomicBool;
}

unsafe impl<T: ObjectType> Instance<T> for ElementInstanceStruct<T> {
    fn parent(&self) -> &T::GlibType {
        &self._parent
    }

    fn get_impl(&self) -> &T::ImplType {
        unsafe { self._imp.as_ref() }
    }

    unsafe fn set_impl(&mut self, imp: ptr::NonNull<T::ImplType>) {
        self._imp = imp;
    }

    unsafe fn get_class(&self) -> *const ClassStruct<T> {
        *(self as *const _ as *const *const ClassStruct<T>)
    }
}

impl<T: ObjectType> PanicPoison for ElementInstanceStruct<T> {
    fn panicked(&self) -> &AtomicBool {
        &self._panicked
    }
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::{cmp, str};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use spin::Mutex;
use syscall::{Error, EBADF, EINVAL, ENOENT, Result, Scheme, SEEK_CUR, SEEK_END, SEEK_SET};

use ahci::disk::Disk;

pub struct DiskScheme {
    disks: Box<[Arc<Mutex<Disk>>]>,
    handles: Mutex<BTreeMap<usize, (Arc<Mutex<Disk>>, usize)>>,
    next_id: AtomicUsize
}

impl DiskScheme {
    pub fn new(disks: Vec<Disk>) -> DiskScheme {
        let mut disk_arcs = vec![];
        for disk in disks {
            disk_arcs.push(Arc::new(Mutex::new(disk)));
        }

        DiskScheme {
            disks: disk_arcs.into_boxed_slice(),
            handles: Mutex::new(BTreeMap::new()),
            next_id: AtomicUsize::new(0)
        }
    }
}

impl Scheme for DiskScheme {
    fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
        let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;

        let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;

        if let Some(disk) = self.disks.get(i) {
            let id = self.next_id.fetch_add(1, Ordering::SeqCst);
            self.handles.lock().insert(id, (disk.clone(), 0));
            Ok(id)
        } else {
            Err(Error::new(ENOENT))
        }
    }

    fn dup(&self, id: usize) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let new_id = self.next_id.fetch_add(1, Ordering::SeqCst);
        self.handles.lock().insert(new_id, handle.clone());
        Ok(new_id)
    }

    fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let mut disk = handle.0.lock();
        let count = disk.read((handle.1 as u64)/512, buf)?;
        handle.1 += count;
        Ok(count)
    }

    fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let mut disk = handle.0.lock();
        let count = disk.write((handle.1 as u64)/512, buf)?;
        handle.1 += count;
        Ok(count)
    }

    fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let len = handle.0.lock().size() as usize;
        handle.1 = match whence {
            SEEK_SET => cmp::min(len, pos),
            SEEK_CUR => cmp::max(0, cmp::min(len as isize, handle.1 as isize + pos as isize)) as usize,
            SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
            _ => return Err(Error::new(EINVAL))
        };

        Ok(handle.1)
    }

    fn close(&self, id: usize) -> Result<usize> {
        let mut handles = self.handles.lock();
        handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
    }
}
<commit_msg>Fix dup deadlock, add stat<commit_after>use std::collections::BTreeMap;
use std::{cmp, str};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use spin::Mutex;
use syscall::{Error, EBADF, EINVAL, ENOENT, Result, Scheme, Stat, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};

use ahci::disk::Disk;

pub struct DiskScheme {
    disks: Box<[Arc<Mutex<Disk>>]>,
    handles: Mutex<BTreeMap<usize, (Arc<Mutex<Disk>>, usize)>>,
    next_id: AtomicUsize
}

impl DiskScheme {
    pub fn new(disks: Vec<Disk>) -> DiskScheme {
        let mut disk_arcs = vec![];
        for disk in disks {
            disk_arcs.push(Arc::new(Mutex::new(disk)));
        }

        DiskScheme {
            disks: disk_arcs.into_boxed_slice(),
            handles: Mutex::new(BTreeMap::new()),
            next_id: AtomicUsize::new(0)
        }
    }
}

impl Scheme for DiskScheme {
    fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
        let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;

        let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;

        if let Some(disk) = self.disks.get(i) {
            let id = self.next_id.fetch_add(1, Ordering::SeqCst);
            self.handles.lock().insert(id, (disk.clone(), 0));
            Ok(id)
        } else {
            Err(Error::new(ENOENT))
        }
    }

    fn dup(&self, id: usize) -> Result<usize> {
        let mut handles = self.handles.lock();
        let new_handle = {
            let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
            handle.clone()
        };

        let new_id = self.next_id.fetch_add(1, Ordering::SeqCst);
        handles.insert(new_id, new_handle);
        Ok(new_id)
    }

    fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
        let handles = self.handles.lock();
        let handle = handles.get(&id).ok_or(Error::new(EBADF))?;

        stat.st_mode = MODE_FILE;
        stat.st_size = handle.0.lock().size();
        Ok(0)
    }

    fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let mut disk = handle.0.lock();
        let count = disk.read((handle.1 as u64)/512, buf)?;
        handle.1 += count;
        Ok(count)
    }

    fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let mut disk = handle.0.lock();
        let count = disk.write((handle.1 as u64)/512, buf)?;
        handle.1 += count;
        Ok(count)
    }

    fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
        let mut handles = self.handles.lock();
        let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;

        let len = handle.0.lock().size() as usize;
        handle.1 = match whence {
            SEEK_SET => cmp::min(len, pos),
            SEEK_CUR => cmp::max(0, cmp::min(len as isize, handle.1 as isize + pos as isize)) as usize,
            SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
            _ => return Err(Error::new(EINVAL))
        };

        Ok(handle.1)
    }

    fn close(&self, id: usize) -> Result<usize> {
        let mut handles = self.handles.lock();
        handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
    }
}
<|endoftext|>


<commit_before>use gilrs::{Axis, Gilrs};
use winit::{
    event,
    event_loop::{ControlFlow, EventLoop},
};

fn compute_projection_matrix(width: f32, height: f32) -> cgmath::Matrix4<f32> {
    let aspect = width as f32 / height as f32;
    let f = 1.0 / (55.0f32.to_radians() / aspect).tan();
    let near = 0.1;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    cgmath::Matrix4::new(
        f / aspect, 0.0,  0.0,  0.0,
        0.0,          f,  0.0,  0.0,
        0.0,        0.0,  0.0, -1.0,
        0.0,        0.0, near,  0.0)
}

fn make_swapchain(
    device: &wgpu::Device,
    surface: &wgpu::Surface,
    width: u32,
    height: u32,
) -> wgpu::SwapChain {
    device.create_swap_chain(
        &surface,
        &wgpu::SwapChainDescriptor {
            usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
            format: wgpu::TextureFormat::Bgra8UnormSrgb,
            width,
            height,
            present_mode: wgpu::PresentMode::Vsync,
        },
    )
}
fn make_depth_buffer(device: &wgpu::Device, width: u32, height: u32) -> wgpu::TextureView {
    device
        .create_texture(&wgpu::TextureDescriptor {
            size: wgpu::Extent3d { width, height, depth: 1 },
            array_layer_count: 1,
            mip_level_count: 1,
            sample_count: 1,
            dimension: wgpu::TextureDimension::D2,
            format: wgpu::TextureFormat::Depth32Float,
            usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
        })
        .create_default_view()
}

fn main() {
    env_logger::init();

    let mut gilrs = Gilrs::new().unwrap();
    let mut current_gamepad = None;
    for (_id, gamepad) in gilrs.gamepads() {
        current_gamepad = Some(gamepad.id());
    }

    let event_loop = EventLoop::new();

    let (window, mut size, surface) = {
        let window = winit::window::Window::new(&event_loop).unwrap();

        for monitor in window.available_monitors() {
            if monitor.video_modes().any(|mode| mode.size().width == 1920.0) {
                window.set_fullscreen(Some(winit::window::Fullscreen::Borderless(monitor)));
                break;
            }
        }

        let size = window.inner_size().to_physical(window.hidpi_factor());

        let surface = wgpu::Surface::create(&window);
        (window, size, surface)
    };

    let adapter = wgpu::Adapter::request(
        &wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::Default },
        wgpu::BackendBit::PRIMARY,
    )
    .unwrap();

    let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
        extensions: wgpu::Extensions { anisotropic_filtering: false },
        limits: wgpu::Limits::default(),
    });

    let mapfile = terra::MapFileBuilder::new()
        .latitude(42)
        .longitude(-73)
        .vertex_quality(terra::VertexQuality::Medium)
        .texture_quality(terra::TextureQuality::High)
        .build()
        .unwrap();

    let mut terrain = terra::Terrain::new(&device, &mut queue, mapfile);

    let mut swap_chain =
        make_swapchain(&device, &surface, size.width.round() as u32, size.height.round() as u32);
    let mut depth_buffer =
        make_depth_buffer(&device, size.width.round() as u32, size.height.round() as u32);

    let proj = compute_projection_matrix(size.width as f32, size.height as f32);

    let mut angle = 3.14159f32;
    let mut eye = cgmath::Point3::new(0.0, 300.0, 0.0);

    event_loop.run(move |event, _, control_flow| {
        *control_flow = if cfg!(feature = "metal-auto-capture") {
            ControlFlow::Exit
        } else {
            ControlFlow::Poll
        };
        match event {
            event::Event::WindowEvent { event, .. } => match event {
                event::WindowEvent::CloseRequested => {
                    *control_flow = ControlFlow::Exit;
                }
                event::WindowEvent::KeyboardInput {
                    input:
                        event::KeyboardInput {
                            virtual_keycode: Some(keycode),
                            state: event::ElementState::Pressed,
                            ..
                        },
                    ..
                } => match keycode {
                    event::VirtualKeyCode::Escape => *control_flow = ControlFlow::Exit,
                    event::VirtualKeyCode::Space => eye.y += 0.01 * eye.y,
                    event::VirtualKeyCode::Semicolon => eye.y -= 0.01 * eye.y,
                    event::VirtualKeyCode::Left => eye.x -= 50.0,
                    event::VirtualKeyCode::Right => eye.x += 50.0,
                    event::VirtualKeyCode::Up => eye.z -= 50.0,
                    event::VirtualKeyCode::Down => eye.z += 50.0,
                    _ => {}
                },
                event::WindowEvent::Resized(new_size) => {
                    size = new_size.to_physical(window.hidpi_factor());
                    swap_chain = make_swapchain(
                        &device,
                        &surface,
                        size.width.round() as u32,
                        size.height.round() as u32,
                    );
                    depth_buffer = make_depth_buffer(
                        &device,
                        size.width.round() as u32,
                        size.height.round() as u32,
                    );
                }
                _ => {}
            },
            event::Event::EventsCleared => {
                let frame = swap_chain
                    .get_next_texture()
                    .expect("Timeout when acquiring next swap chain texture");

                let forward = cgmath::Vector3::new(angle.sin(), 0.0, angle.cos());
                let right = cgmath::Vector3::new(angle.cos(), 0.0, -angle.sin());

                while let Some(gilrs::Event { id, event: _, time: _ }) = gilrs.next_event() {
                    current_gamepad = Some(id);
                }
                if let Some(gamepad) = current_gamepad.map(|id| gilrs.gamepad(id)) {
                    if gamepad.value(Axis::LeftStickY).abs() > 0.1 {
                        eye += forward * gamepad.value(Axis::LeftStickY) * 50.0;
                    }
                    if gamepad.value(Axis::LeftStickX).abs() > 0.1 {
                        eye -= right * gamepad.value(Axis::LeftStickX) * 50.0;
                    }
                    if gamepad.value(Axis::RightZ).abs() > 0.025 {
                        angle -= gamepad.value(Axis::RightZ) * 0.1;
                    }
                }

                let view = cgmath::Matrix4::look_at(
                    cgmath::Point3::new(eye.x, eye.y, eye.z),
                    cgmath::Point3::new(
                        eye.x + 20000.0 * forward.x,
                        0.0,
                        eye.z + 20000.0 * forward.z,
                    ),
                    cgmath::Vector3::new(0.0, -1.0, 0.0),
                );

                let view_proj = proj * view;
                let view_proj = mint::ColumnMatrix4 {
                    x: view_proj.x.into(),
                    y: view_proj.y.into(),
                    z: view_proj.z.into(),
                    w: view_proj.w.into(),
                };

                terrain.render(
                    &device,
                    &mut queue,
                    &frame,
                    &depth_buffer,
                    (size.width.round() as u32, size.height.round() as u32),
                    view_proj,
                    eye.into(),
                );
            }
            _ => (),
        }
    });
}
<commit_msg>More control improvements<commit_after>use gilrs::{Axis, Button, Gilrs};
use winit::{
    event,
    event_loop::{ControlFlow, EventLoop},
};

fn compute_projection_matrix(width: f32, height: f32) -> cgmath::Matrix4<f32> {
    let aspect = width as f32 / height as f32;
    let f = 1.0 / (55.0f32.to_radians() / aspect).tan();
    let near = 0.1;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    cgmath::Matrix4::new(
        f / aspect, 0.0,  0.0,  0.0,
        0.0,          f,  0.0,  0.0,
        0.0,        0.0,  0.0, -1.0,
        0.0,        0.0, near,  0.0)
}

fn make_swapchain(
    device: &wgpu::Device,
    surface: &wgpu::Surface,
    width: u32,
    height: u32,
) -> wgpu::SwapChain {
    device.create_swap_chain(
        &surface,
        &wgpu::SwapChainDescriptor {
            usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
            format: wgpu::TextureFormat::Bgra8UnormSrgb,
            width,
            height,
            present_mode: wgpu::PresentMode::Vsync,
        },
    )
}
fn make_depth_buffer(device: &wgpu::Device, width: u32, height: u32) -> wgpu::TextureView {
    device
        .create_texture(&wgpu::TextureDescriptor {
            size: wgpu::Extent3d { width, height, depth: 1 },
            array_layer_count: 1,
            mip_level_count: 1,
            sample_count: 1,
            dimension: wgpu::TextureDimension::D2,
            format: wgpu::TextureFormat::Depth32Float,
            usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
        })
        .create_default_view()
}

fn main() {
    env_logger::init();

    let mut gilrs = Gilrs::new().unwrap();
    let mut current_gamepad = None;
    for (_id, gamepad) in gilrs.gamepads() {
        current_gamepad = Some(gamepad.id());
    }

    let event_loop = EventLoop::new();

    let (window, mut size, surface) = {
        let window = winit::window::Window::new(&event_loop).unwrap();

        for monitor in window.available_monitors() {
            if monitor.video_modes().any(|mode| mode.size().width == 1920.0) {
                window.set_fullscreen(Some(winit::window::Fullscreen::Borderless(monitor)));
                break;
            }
        }

        let size = window.inner_size().to_physical(window.hidpi_factor());

        let surface = wgpu::Surface::create(&window);
        (window, size, surface)
    };

    let adapter = wgpu::Adapter::request(
        &wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::Default },
        wgpu::BackendBit::PRIMARY,
    )
    .unwrap();

    let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
        extensions: wgpu::Extensions { anisotropic_filtering: false },
        limits: wgpu::Limits::default(),
    });

    let mapfile = terra::MapFileBuilder::new()
        .latitude(42)
        .longitude(-73)
        .vertex_quality(terra::VertexQuality::Medium)
        .texture_quality(terra::TextureQuality::High)
        .build()
        .unwrap();

    let mut terrain = terra::Terrain::new(&device, &mut queue, mapfile);

    let mut swap_chain =
        make_swapchain(&device, &surface, size.width.round() as u32, size.height.round() as u32);
    let mut depth_buffer =
        make_depth_buffer(&device, size.width.round() as u32, size.height.round() as u32);

    let proj = compute_projection_matrix(size.width as f32, size.height as f32);

    let mut angle = 3.14159f32;
    let mut eye = cgmath::Point3::new(0.0, 300.0, 0.0);

    event_loop.run(move |event, _, control_flow| {
        *control_flow = if cfg!(feature = "metal-auto-capture") {
            ControlFlow::Exit
        } else {
            ControlFlow::Poll
        };
        match event {
            event::Event::WindowEvent { event, .. } => match event {
                event::WindowEvent::CloseRequested => {
                    *control_flow = ControlFlow::Exit;
                }
                event::WindowEvent::KeyboardInput {
                    input:
                        event::KeyboardInput {
                            virtual_keycode: Some(keycode),
                            state: event::ElementState::Pressed,
                            ..
                        },
                    ..
                } => match keycode {
                    event::VirtualKeyCode::Escape => *control_flow = ControlFlow::Exit,
                    event::VirtualKeyCode::Space => eye.y += 0.01 * eye.y,
                    event::VirtualKeyCode::Semicolon => eye.y -= 0.01 * eye.y,
                    event::VirtualKeyCode::Left => eye.x -= 50.0,
                    event::VirtualKeyCode::Right => eye.x += 50.0,
                    event::VirtualKeyCode::Up => eye.z -= 50.0,
                    event::VirtualKeyCode::Down => eye.z += 50.0,
                    _ => {}
                },
                event::WindowEvent::Resized(new_size) => {
                    size = new_size.to_physical(window.hidpi_factor());
                    swap_chain = make_swapchain(
                        &device,
                        &surface,
                        size.width.round() as u32,
                        size.height.round() as u32,
                    );
                    depth_buffer = make_depth_buffer(
                        &device,
                        size.width.round() as u32,
                        size.height.round() as u32,
                    );
                }
                _ => {}
            },
            event::Event::EventsCleared => {
                let frame = swap_chain
                    .get_next_texture()
                    .expect("Timeout when acquiring next swap chain texture");

                let forward = cgmath::Vector3::new(angle.sin(), 0.0, angle.cos());
                let right = cgmath::Vector3::new(angle.cos(), 0.0, -angle.sin());

                while let Some(gilrs::Event { id, event: _event, time: _ }) = gilrs.next_event() {
                    current_gamepad = Some(id);
                }
                if let Some(gamepad) = current_gamepad.map(|id| gilrs.gamepad(id)) {
                    eye += forward * gamepad.value(Axis::LeftStickY) * 50.0;
                    eye -= right * gamepad.value(Axis::LeftStickX) * 50.0;
                    angle -= gamepad.value(Axis::RightZ) * 0.1;

                    if gamepad.is_pressed(Button::DPadUp) {
                        eye.y += 0.01 * eye.y;
                    }
                    if gamepad.is_pressed(Button::DPadDown) {
                        eye.y -= 0.01 * eye.y;
                    }
                }

                let view = cgmath::Matrix4::look_at(
                    cgmath::Point3::new(eye.x, eye.y, eye.z),
                    cgmath::Point3::new(
                        eye.x + 20000.0 * forward.x,
                        0.0,
                        eye.z + 20000.0 * forward.z,
                    ),
                    cgmath::Vector3::new(0.0, -1.0, 0.0),
                );

                let view_proj = proj * view;
                let view_proj = mint::ColumnMatrix4 {
                    x: view_proj.x.into(),
                    y: view_proj.y.into(),
                    z: view_proj.z.into(),
                    w: view_proj.w.into(),
                };

                terrain.render(
                    &device,
                    &mut queue,
                    &frame,
                    &depth_buffer,
                    (size.width.round() as u32, size.height.round() as u32),
                    view_proj,
                    eye.into(),
                );
            }
            _ => (),
        }
    });
}
<|endoftext|>


<commit_before>use rand::{thread_rng, Rng};

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Color {
    Red,
    Yellow,
    Blue,
    Green,
    Black,
}

impl Color {
    pub fn rand() -> Color {
        let mut rng = thread_rng();

        rng.choose(&[
            Color::Red,
            Color::Yellow,
            Color::Blue,
            Color::Green,
            Color::Black,
        ]).unwrap().clone()
    }

    pub fn as_rgba(&self) -> [f32; 4] {
        match *self {
            Color::Red => [0.8, 0.0, 0.0, 1.0],
            Color::Yellow => [1.0, 1.0, 0.5, 1.0],
            Color::Blue => [0.0, 0.5, 1.0, 1.0],
            Color::Green => [0.0, 0.5, 0.0, 1.0],
            Color::Black => [0.0, 0.0, 0.0, 1.0],
        }
    }
}

<commit_msg>adjust colors<commit_after>use rand::{thread_rng, Rng};

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Color {
    Red,
    Yellow,
    Blue,
    Green,
    Black,
}

impl Color {
    pub fn rand() -> Color {
        let mut rng = thread_rng();

        rng.choose(&[
            Color::Red,
            Color::Yellow,
            Color::Blue,
            Color::Green,
            Color::Black,
        ]).unwrap().clone()
    }

    pub fn as_rgba(&self) -> [f32; 4] {
        match *self {
            Color::Red => [0.6, 0.2, 0.2, 1.0],
            Color::Yellow => [0.7, 0.7, 0.25, 1.0],
            Color::Blue => [0.2, 0.4, 0.6, 1.0],
            Color::Green => [0.2, 0.6, 0.2, 1.0],
            Color::Black => [0.1, 0.1, 0.1, 1.0],
        }
    }
}

<|endoftext|>


<commit_before>use super::common::sha256_hex;
use super::ct::AddChainRequest;
use base64;
use hyper;
use serde_json;
use url;

pub fn build_chain_for_cert(http_client: &hyper::Client, cert: &[u8]) -> Vec<Vec<u8>> {
    let body = url::form_urlencoded::Serializer::new(String::new())
        .append_pair("b64cert", &base64::encode(cert))
        .finish();
    let body_bytes = body.as_bytes();
    let response = http_client
        .post("https://crt.sh/gen-add-chain")
        .header(hyper::header::ContentType::form_url_encoded())
        .body(hyper::client::Body::BufBody(body_bytes, body_bytes.len()))
        .send()
        .unwrap();

    let add_chain_request: AddChainRequest = serde_json::from_reader(response).unwrap();
    add_chain_request
        .chain
        .iter()
        .map(|c| base64::decode(c).unwrap())
        .collect()
}

pub fn is_cert_logged(http_client: &hyper::Client, cert: &[u8]) -> bool {
    let response = http_client
        .get(&format!("https://crt.sh/?d={}", sha256_hex(cert)))
        .send()
        .unwrap();
    return response.status == hyper::status::StatusCode::Ok;
}

pub fn url_for_cert(cert: &[u8]) -> String {
    format!("https://crt.sh?q={}", sha256_hex(cert).to_uppercase())
}
<commit_msg>clippy<commit_after>use super::common::sha256_hex;
use super::ct::AddChainRequest;
use base64;
use hyper;
use serde_json;
use url;

pub fn build_chain_for_cert(http_client: &hyper::Client, cert: &[u8]) -> Vec<Vec<u8>> {
    let body = url::form_urlencoded::Serializer::new(String::new())
        .append_pair("b64cert", &base64::encode(cert))
        .finish();
    let body_bytes = body.as_bytes();
    let response = http_client
        .post("https://crt.sh/gen-add-chain")
        .header(hyper::header::ContentType::form_url_encoded())
        .body(hyper::client::Body::BufBody(body_bytes, body_bytes.len()))
        .send()
        .unwrap();

    let add_chain_request: AddChainRequest = serde_json::from_reader(response).unwrap();
    add_chain_request
        .chain
        .iter()
        .map(|c| base64::decode(c).unwrap())
        .collect()
}

pub fn is_cert_logged(http_client: &hyper::Client, cert: &[u8]) -> bool {
    let response = http_client
        .get(&format!("https://crt.sh/?d={}", sha256_hex(cert)))
        .send()
        .unwrap();
    response.status == hyper::status::StatusCode::Ok
}

pub fn url_for_cert(cert: &[u8]) -> String {
    format!("https://crt.sh?q={}", sha256_hex(cert).to_uppercase())
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::Ordering;

pub fn single_night(file: &str) -> i64 {
    let input = File::open(file).expect("File open fail.");
    let reader = BufReader::new(input);

    #[derive(Debug, Eq, Ord, PartialOrd)]
    struct Node(String, i64);

    impl PartialEq for Node {
        fn eq(&self, other: &Node) -> bool {
            self.0.eq(&other.0)
        }
        fn ne(&self, other: &Node) -> bool {
            !self.0.eq(&other.0)
        }
    }

    impl Clone for Node {
        fn clone(&self) -> Self {
            Node(self.0.clone(), self.1)
        }
    }

    let mut nodes = Vec::new();
    let mut edges = Vec::new();
    for line in reader.lines() {
        let line = line.unwrap();
        // println!("{}", s);

        let words: Vec<&str> = line.split_whitespace().collect();
        let from = Node(String::from(words[0]), i64::max_value());
        let to = Node(String::from(words[2]), i64::max_value());
        let distance = words[4]
            .parse::<i64>()
            .expect("parse error");

        nodes.push(from.clone());
        nodes.push(to.clone());
        edges.push((from, to, distance));
    }
    // remove duplicate nodes
    nodes.sort_by(|a, b| a.0.cmp(&b.0));
    nodes.dedup();

    // make last node source
    let source = nodes.pop().unwrap();
    let source = Node(source.0, 0);
    nodes.push(source);

    println!("nodes");
    for node in nodes.clone() {
        println!("{:?}", node);
    }

    println!("calculating...");
    let mut out: Vec<Node> = Vec::new();
    loop {
        if nodes.is_empty() {
            let mut sum = 0;
            for node in out {
                sum += node.1;
                println!("{:?}", node);
            }
            return sum;
        }
        println!("sorted nodes");
        nodes.sort_by(|a, b| b.1.cmp(&a.1));
        for node in nodes.clone() {
            println!("{:?}", node);
        }

        let node = nodes.pop().unwrap();
        println!("pop min {:?}", node);

        // for each neighbor of n
        for edge in edges.iter() {
            let (ref from, ref to, ref dist) = *edge;
            if from == &node {
                println!("edge {:?} {:?} {:?}", from.0, to.0, dist);
                let alt = node.1 + *dist;
                if let Ok(neighbor_index) = nodes.binary_search(to) {
                    let mut neighbor = nodes.get_mut(neighbor_index).unwrap();
                    // assign new weight to neighbor
                    if alt < neighbor.1 {
                        println!("New weight {:?} {:?}", neighbor, alt);
                        *neighbor = Node(to.0.clone(), alt);
                    }
                }
            }
        }
        out.push(node);
    }
}
<commit_msg>Move dijkstra to function.<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;

pub fn single_night(file: &str) -> i64 {
    let input = File::open(file).expect("File open fail.");
    let reader = BufReader::new(input);

    let mut nodes = Vec::new();
    let mut edges = Vec::new();
    for line in reader.lines() {
        let line = line.unwrap();
        // println!("{}", s);

        let words: Vec<&str> = line.split_whitespace().collect();
        let from = Node(String::from(words[0]), i64::max_value());
        let to = Node(String::from(words[2]), i64::max_value());
        let distance = words[4]
            .parse::<i64>()
            .expect("parse error");

        nodes.push(from.clone());
        nodes.push(to.clone());
        edges.push((from.clone(), to.clone(), distance));
        edges.push((to, from, distance)); // bi-directional
    }
    // remove duplicate nodes
    nodes.sort_by(|a, b| a.0.cmp(&b.0));
    nodes.dedup();

    println!("nodes");
    for node in nodes.clone() {
        println!("{:?}", node);
    }

    let node_list = nodes.clone();
    let mut results = Vec::new();
    for n in node_list {
        // make n node source
        let mut nodes = nodes.clone();
        if let Ok(n_index) = nodes.binary_search(&n) {
            let mut node = nodes.get_mut(n_index).unwrap();
            *node = Node(n.0.clone(), 0);
        }
        println!("calculating next...");
        results.push(dijkstra(nodes, edges.clone()));
    }

    for result in results.clone() {
        let (route, _) = result;
        for node in route {
            println!("{:?}->", node);
        }
    }
    // sort reversed and pop min
    results.sort_by(|a, b| b.1.cmp(&a.1));
    let (_, min) = results.pop().unwrap();
    min
}

fn dijkstra(mut nodes: Vec<Node>, edges: Vec<(Node, Node, i64)>) -> (Vec<Node>, i64) {
    let mut out: Vec<Node> = Vec::new();
    loop {
        if nodes.is_empty() {
            let mut sum = 0;
            for node in out.clone() {
                sum += node.1;
                println!("{:?}", node);
            }
            return (out, sum);
        }
        println!("sorted nodes");
        nodes.sort_by(|a, b| b.1.cmp(&a.1));
        for node in nodes.clone() {
            println!("{:?}", node);
        }

        let node = nodes.pop().unwrap();
        println!("pop min {:?}", node);
        println!("edges length {:?}", edges.len());

        // for each neighbor of n
        for edge in edges.clone().iter() {
            let (ref from, ref to, ref dist) = *edge;
            if from == &node {
                if let Ok(neighbor_index) = nodes.binary_search(to) {
                    let mut neighbor = nodes.get_mut(neighbor_index).unwrap();
                    println!("edge {:?} {:?} {:?}", from.0, to.0, dist);
                    let alt = node.1 + *dist;
                    // assign new weight to neighbor
                    if alt < neighbor.1 {
                        println!("{:?} <- {:?}", neighbor.0, alt);
                        *neighbor = Node(to.0.clone(), alt);
                    }
                }
            }
        }
        out.push(node);
    }
}

#[derive(Debug, Eq, Ord, PartialOrd)]
struct Node(String, i64);

impl PartialEq for Node {
    fn eq(&self, other: &Node) -> bool {
        self.0.eq(&other.0)
    }
    fn ne(&self, other: &Node) -> bool {
        !self.0.eq(&other.0)
    }
}

impl Clone for Node {
    fn clone(&self) -> Self {
        Node(self.0.clone(), self.1)
    }
}

<|endoftext|>


<commit_before>use std::ops::{Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use std::cmp::Ordering;
use rand::{Rand, Rng};
use serde::{Serialize, Deserialize};

use super::Randomize;

// The field size.
const P: u128 = (1 << 127) - 1;

// A finite field element.
//
// It is consistent iff 0 <= self.0 <= P.
// Note that this implies that the zero element has two internal representations.
#[derive(Clone, Copy, Default, Debug)]
pub struct Fp(u128);

impl Serialize for Fp {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        use serde::ser::SerializeTuple;

        // TODO serde currently does not support u128 natively
        let (h, l) = as_limbs(u128::from(*self));
        let mut tup = serializer.serialize_tuple(2)?;
        tup.serialize_element(&h)?;
        tup.serialize_element(&l)?;
        tup.end()
    }
}

impl<'de> Deserialize<'de> for Fp {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Fp, D::Error>
        where D: ::serde::Deserializer<'de>
    {
        use serde::de;

        // TODO serde currently does not support u128 natively
        struct Visitor;
        impl<'de> ::serde::de::Visitor<'de> for Visitor {
            type Value = Fp;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a pair (h, l) of u64 representing an u128 x = h||l \
                                    such that 0 <= x < p where p = 2**127 - 1")
            }

            fn visit_seq<A>(self, mut a: A) -> Result<Fp, A::Error>
                where A: de::SeqAccess<'de>
            {
                let h: u64 = a.next_element()?.ok_or(de::Error::invalid_length(0, &self))?;
                let l: u64 = a.next_element()?.ok_or(de::Error::invalid_length(1, &self))?;
                let x = ((h as u128) << 64) | (l as u128);
                if x >= P {
                    let unexp_str = format!("the u128 with value {:x}", x);
                    let unexp = de::Unexpected::Other(&unexp_str);
                    return Err(de::Error::invalid_value(unexp, &self));
                }
                Ok(Fp::from_u127(x))
            }
        }

        deserializer.deserialize_tuple(2, Visitor { })
    }
}

#[inline]
fn as_limbs(x: u128) -> (u64, u64) {
    ((x >> 64) as u64, x as u64)
}

trait Reduce: Sized {
    fn reduce_once(self) -> u128;

    #[inline]
    fn reduce_once_assert(self) -> u128 {
        let red: u128 = self.reduce_once();
        debug_assert!(red <= P);
        red
    }
}

impl Reduce for u128 {
    #[inline]
    fn reduce_once(self) -> u128 {
        (self & P) + (self >> 127)
    }
}

impl Reduce for (u128, u128) {
    #[inline]
    fn reduce_once(self) -> u128 {
        let (h, l) = self;
        // shift = (h, l) >> 127
        let shift = (h << 1) | (l >> 127);
        (l & P) + shift
    }
}

impl Fp {
    #[inline]
    pub fn from_u127(x: u128) -> Self {
        // x == P is explicitly allowed.
        // This introduces a negligible bias towards the zero element
        // if x is uniformly random from {0,1}^127.
        debug_assert!(x <= P);
        Fp(x)
    }

    #[inline]
    pub fn from_u128_discard_msb(x: u128) -> Self {
        Self::from_u127(x & P)
    }

    #[inline]
    pub fn prime() -> u128 {
        P
    }
}

impl From<Fp> for u128 {
    #[inline]
    fn from(x: Fp) -> u128 {
        if x.0 == P { 0 } else { x.0 }
    }
}

impl Rand for Fp {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Self::from_u128_discard_msb(rng.gen::<u128>())
    }

}

impl Randomize for Fp {
    #[inline]
    fn randomize<R: Rng>(&mut self, rng: &mut R) {
        *self = Self::rand(rng)
    }

}

impl Neg for Fp {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self {
        Fp(P - self.0)
    }
}

impl Add for Fp {
    type Output = Self;
    #[inline]
    fn add(self, other: Self) -> Self {
        Fp((self.0 + other.0).reduce_once_assert())
    }
}

impl AddAssign for Fp {
    #[inline]
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl Sub for Fp {
    type Output = Self;
    #[inline]
    fn sub(self, other: Self) -> Self {
        self + (-other)
    }
}

impl SubAssign for Fp {
    #[inline]
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other
    }
}

impl Mul for Fp {
    type Output = Self;
    #[inline]
    fn mul(self, other: Self) -> Self {
        let (sh, sl) = as_limbs(self.0);
        let (oh, ol) = as_limbs(other.0);

        // (64 bits * 63 bits) + (64 bits * 63 bits) = 128 bits
        let m: u128 = (sh as u128 * ol as u128) + (oh as u128 * sl as u128);
        let (mh, ml) = as_limbs(m);

        // (64 bits * 64 bits) + 128 bits = 129 bits
        let (rl, carry) = (sl as u128 * ol as u128).overflowing_add((ml as u128) << 64);

        // (63 bits * 63 bits) + 64 bits + 1 bit = 127 bits
        let rh: u128 = (sh as u128 * oh as u128) + (mh as u128) + (carry as u128);

        Fp((rh, rl).reduce_once().reduce_once_assert())
    }
}

impl MulAssign for Fp {
    #[inline]
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other
    }
}

impl PartialEq for Fp {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        u128::from(*self) == u128::from(*other)
    }
}

impl Eq for Fp {}

impl PartialOrd for Fp {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        u128::from(*self).partial_cmp(&u128::from(*other))
    }
}

impl Ord for Fp {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(&other).unwrap()
    }
}

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

    #[test]
    fn neg() {
        assert_eq!(-Fp(0), Fp(0));
        assert_eq!(-Fp(5), Fp(P - 5));
    }

    #[test]
    fn add() {
        assert_eq!(Fp(7) + Fp(5), Fp(12));
        assert_eq!(Fp(P - 2) + Fp(5), Fp(3));
        assert_eq!(
            Fp(75661398932549814984099328258351945610) + Fp(154440289138086217180118920884960981429),
            Fp(59960504610166800432530945427428821312)
        );
    }

    #[test]
    fn sub() {
        assert_eq!(Fp(7) - Fp(5), Fp(2));
        assert_eq!(Fp(4) - Fp(8), Fp(P - 4));
    }

    #[test]
    fn mul() {
        assert_eq!(Fp(4) * Fp(3), Fp(12));
        assert_eq!(Fp(P) * Fp(291298091), Fp(0));
        assert_eq!(
            Fp(14766549069271113692204649107775507741) * Fp(153613967287097206589234951623852979690),
            Fp(113548737858505840193892055835373785352)
        );
        // Two reductions are necessary for the following example.
        assert_eq!(
            Fp(75661398932549814984099328258351945610) * Fp(154440289138086217180118920884960981429),
            Fp(109146875586984049909139102289297416971)
        );
    }

    #[test]
    fn eq() {
        assert_eq!(Fp(0), Fp(P));
        assert!(Fp(17) != Fp(4));
        assert!(Fp(0) != Fp(4));
        assert!(Fp(P) != Fp(17));
    }

    #[test]
    fn ord() {
        assert!(Fp(0) < Fp(1));
        assert!(Fp(17) > Fp(0));
        assert!(Fp(P) < Fp(1));
        assert!(Fp(23) > Fp(P));
    }

    #[test]
    fn assign() {
        let mut a = Fp(17);

        a += Fp(3);
        assert_eq!(a, Fp(20));

        a -= Fp(5);
        assert_eq!(a, Fp(15));

        a *= Fp(2);
        assert_eq!(a, Fp(30));
    }
}
<commit_msg>Use serde natively for u128<commit_after>use std::ops::{Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use std::cmp::Ordering;
use rand::{Rand, Rng};
use serde::{Serialize, Deserialize};

use super::Randomize;

// The field size.
const P: u128 = (1 << 127) - 1;

// A finite field element.
//
// It is consistent iff 0 <= self.0 <= P.
// Note that this implies that the zero element has two internal representations.
#[derive(Clone, Copy, Default, Debug)]
pub struct Fp(u128);

impl Serialize for Fp {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        let u = u128::from(*self);
        serializer.serialize_u128(u)
    }
}

impl<'de> Deserialize<'de> for Fp {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Fp, D::Error>
        where D: ::serde::Deserializer<'de>
    {
        use serde::de;

        struct Visitor;
        impl<'de> ::serde::de::Visitor<'de> for Visitor {
            type Value = Fp;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a u128 x such that 0 <= x < p where p = 2**127 - 1")
            }

            fn visit_u128<E>(self, x: u128) -> Result<Fp, E>
                where E: de::Error
            {
                if x >= P {
                    let unexp_str = format!("the u128 with value {:x} >= 2**127 - 1", x);
                    let unexp = de::Unexpected::Other(&unexp_str);
                    return Err(de::Error::invalid_value(unexp, &self))
                }
                Ok(Fp::from_u127(x))
            }
        }

        deserializer.deserialize_u128(Visitor { })
    }
}

#[inline]
fn as_limbs(x: u128) -> (u64, u64) {
    ((x >> 64) as u64, x as u64)
}

trait Reduce: Sized {
    fn reduce_once(self) -> u128;

    #[inline]
    fn reduce_once_assert(self) -> u128 {
        let red: u128 = self.reduce_once();
        debug_assert!(red <= P);
        red
    }
}

impl Reduce for u128 {
    #[inline]
    fn reduce_once(self) -> u128 {
        (self & P) + (self >> 127)
    }
}

impl Reduce for (u128, u128) {
    #[inline]
    fn reduce_once(self) -> u128 {
        let (h, l) = self;
        // shift = (h, l) >> 127
        let shift = (h << 1) | (l >> 127);
        (l & P) + shift
    }
}

impl Fp {
    #[inline]
    pub fn from_u127(x: u128) -> Self {
        // x == P is explicitly allowed.
        // This introduces a negligible bias towards the zero element
        // if x is uniformly random from {0,1}^127.
        debug_assert!(x <= P);
        Fp(x)
    }

    #[inline]
    pub fn from_u128_discard_msb(x: u128) -> Self {
        Self::from_u127(x & P)
    }

    #[inline]
    pub fn prime() -> u128 {
        P
    }
}

impl From<Fp> for u128 {
    #[inline]
    fn from(x: Fp) -> u128 {
        if x.0 == P { 0 } else { x.0 }
    }
}

impl Rand for Fp {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Self::from_u128_discard_msb(rng.gen::<u128>())
    }

}

impl Randomize for Fp {
    #[inline]
    fn randomize<R: Rng>(&mut self, rng: &mut R) {
        *self = Self::rand(rng)
    }

}

impl Neg for Fp {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self {
        Fp(P - self.0)
    }
}

impl Add for Fp {
    type Output = Self;
    #[inline]
    fn add(self, other: Self) -> Self {
        Fp((self.0 + other.0).reduce_once_assert())
    }
}

impl AddAssign for Fp {
    #[inline]
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl Sub for Fp {
    type Output = Self;
    #[inline]
    fn sub(self, other: Self) -> Self {
        self + (-other)
    }
}

impl SubAssign for Fp {
    #[inline]
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other
    }
}

impl Mul for Fp {
    type Output = Self;
    #[inline]
    fn mul(self, other: Self) -> Self {
        let (sh, sl) = as_limbs(self.0);
        let (oh, ol) = as_limbs(other.0);

        // (64 bits * 63 bits) + (64 bits * 63 bits) = 128 bits
        let m: u128 = (sh as u128 * ol as u128) + (oh as u128 * sl as u128);
        let (mh, ml) = as_limbs(m);

        // (64 bits * 64 bits) + 128 bits = 129 bits
        let (rl, carry) = (sl as u128 * ol as u128).overflowing_add((ml as u128) << 64);

        // (63 bits * 63 bits) + 64 bits + 1 bit = 127 bits
        let rh: u128 = (sh as u128 * oh as u128) + (mh as u128) + (carry as u128);

        Fp((rh, rl).reduce_once().reduce_once_assert())
    }
}

impl MulAssign for Fp {
    #[inline]
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other
    }
}

impl PartialEq for Fp {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        u128::from(*self) == u128::from(*other)
    }
}

impl Eq for Fp {}

impl PartialOrd for Fp {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        u128::from(*self).partial_cmp(&u128::from(*other))
    }
}

impl Ord for Fp {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(&other).unwrap()
    }
}

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

    #[test]
    fn neg() {
        assert_eq!(-Fp(0), Fp(0));
        assert_eq!(-Fp(5), Fp(P - 5));
    }

    #[test]
    fn add() {
        assert_eq!(Fp(7) + Fp(5), Fp(12));
        assert_eq!(Fp(P - 2) + Fp(5), Fp(3));
        assert_eq!(
            Fp(75661398932549814984099328258351945610) + Fp(154440289138086217180118920884960981429),
            Fp(59960504610166800432530945427428821312)
        );
    }

    #[test]
    fn sub() {
        assert_eq!(Fp(7) - Fp(5), Fp(2));
        assert_eq!(Fp(4) - Fp(8), Fp(P - 4));
    }

    #[test]
    fn mul() {
        assert_eq!(Fp(4) * Fp(3), Fp(12));
        assert_eq!(Fp(P) * Fp(291298091), Fp(0));
        assert_eq!(
            Fp(14766549069271113692204649107775507741) * Fp(153613967287097206589234951623852979690),
            Fp(113548737858505840193892055835373785352)
        );
        // Two reductions are necessary for the following example.
        assert_eq!(
            Fp(75661398932549814984099328258351945610) * Fp(154440289138086217180118920884960981429),
            Fp(109146875586984049909139102289297416971)
        );
    }

    #[test]
    fn eq() {
        assert_eq!(Fp(0), Fp(P));
        assert!(Fp(17) != Fp(4));
        assert!(Fp(0) != Fp(4));
        assert!(Fp(P) != Fp(17));
    }

    #[test]
    fn ord() {
        assert!(Fp(0) < Fp(1));
        assert!(Fp(17) > Fp(0));
        assert!(Fp(P) < Fp(1));
        assert!(Fp(23) > Fp(P));
    }

    #[test]
    fn assign() {
        let mut a = Fp(17);

        a += Fp(3);
        assert_eq!(a, Fp(20));

        a -= Fp(5);
        assert_eq!(a, Fp(15));

        a *= Fp(2);
        assert_eq!(a, Fp(30));
    }
}
<|endoftext|>


<commit_before>use std::io::Read;
use std::net;
use std::str;
use std::string;

pub struct Listener{
    clientAddr: net::SocketAddr,
    reqType: String,
    reqFile: String,
    httpProto: String,
    userAgent: String,
    rawReq: String,
}

impl Listener {
    pub fn new (mut stream: net::TcpStream ){
        let mut tcpString: String = String::new();
        stream.read_to_string(&mut tcpString);

        println!("{}", tcpString);

    }

    fn listen (self) {

    }

    fn ParseRequestStr(self, req_str: &str) {
        //Populate the fields of the listener struct
        //http://www.trevisrothwell.com/2015/01/string-tokenization-in-rust/
        //Now StrExt doesn't exist. Part of std:str

        let mut term = req_str.ToString.Split(" ");

        loop { //Works only if path isn't missing
            match term.next().as_ref() {
                "GET" => {self.reqType = "GET"},
                path @ _ => {self.reqFile = path},
                "HTTP /1.1" => {self.httpProto = "HTTP /1.1"}
            }
        }
    }

}<commit_msg>Finally parsing string fack<commit_after>use std::io::Read;
use std::net;
use std::str;
use std::string;

pub struct Listener{
    clientAddr: net::SocketAddr,
    reqType: String,
    reqFile: String,
    httpProto: String,
    userAgent: String,
    rawReq: String,
}

impl Listener {
    pub fn new (mut stream: net::TcpStream ){
        let mut tcpString: String = String::new();
        stream.read_to_string(&mut tcpString);
        Listener::ParseRequestStr(tcpString.to_string());
        println!("{}", tcpString);

    }

    fn listen (self) {

    }

    pub fn ParseRequestStr(req_str: String) {
        //Populate the fields of the listener struct
        //http://www.trevisrothwell.com/2015/01/string-tokenization-in-rust/
        //Now StrExt doesn't exist. Part of std:str

        //let mut terms = req_str.to_string().split(" ");

        for term in req_str.split(" ") { //Works only if path isn't missing
            println!("{}",term);
           // match *term {
           //     String::from_str("GET") => {self.reqType = "GET".to_string()},
           //     path @ _ => {self.reqFile = path},
           //     String::from_str("HTTP /1.1") => {self.httpProto = "HTTP /1.1".to_string()}
           // }
        }
    }

}<|endoftext|>


<commit_before>use std::future::Future;
use std::io;
use std::net::ToSocketAddrs;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};

use futures::{ready, Sink, Stream, StreamExt};
use pin_project::{pin_project, project};
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;
use tokio_rustls::rustls::ClientConfig;
use tokio_rustls::webpki::DNSNameRef;
use tokio_rustls::{client::TlsStream, TlsConnector};
use tokio_util::codec::Decoder;

use crate::proto::{ImapCodec, ImapTransport, ResponseData};
use imap_proto::builders::command::Command;
use imap_proto::{Request, RequestId, State};

pub mod builder {
    pub use imap_proto::builders::command::{fetch, CommandBuilder, FetchCommand};
}

pub type TlsClient = Client<TlsStream<TcpStream>>;

pub struct Client<T> {
    transport: ImapTransport<T>,
    state: ClientState,
}

impl TlsClient {
    pub async fn connect(server: &str) -> io::Result<(ResponseData, Self)> {
        let addr = (server, 993).to_socket_addrs()?.next().ok_or_else(|| {
            io::Error::new(
                io::ErrorKind::Other,
                format!("no IP addresses found for {}", server),
            )
        })?;

        let mut tls_config = ClientConfig::new();
        tls_config
            .root_store
            .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
        let connector: TlsConnector = Arc::new(tls_config).into();

        let stream = TcpStream::connect(&addr).await?;
        let stream = connector
            .connect(DNSNameRef::try_from_ascii_str(server).unwrap(), stream)
            .await?;
        let mut transport = ImapCodec::default().framed(stream);

        let greeting = match transport.next().await {
            Some(greeting) => Ok(greeting),
            None => Err(io::Error::new(io::ErrorKind::Other, "no greeting found")),
        }?;
        let client = Client {
            transport,
            state: ClientState::new(),
        };

        greeting.map(|greeting| (greeting, client))
    }

    pub fn call<C: Into<Command>>(&mut self, cmd: C) -> ResponseStream<TlsStream<TcpStream>> {
        ResponseStream::new(self, cmd.into())
    }
}

#[pin_project]
pub struct ResponseStream<'a, T> {
    #[pin]
    client: &'a mut Client<T>,
    request_id: RequestId,
    cmd: Command,
    state: ResponseStreamState,
}

impl<'a, T> ResponseStream<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin,
{
    pub fn new(client: &mut Client<T>, cmd: Command) -> ResponseStream<'_, T> {
        let request_id = client.state.request_ids.next().unwrap(); // safe: never returns Err,
        ResponseStream {
            client,
            request_id,
            cmd,
            state: ResponseStreamState::Start,
        }
    }

    pub async fn try_collect(&mut self) -> Result<Vec<ResponseData>, io::Error> {
        let mut data = vec![];
        loop {
            match self.next().await {
                Some(Ok(rsp)) => {
                    data.push(rsp);
                }
                Some(Err(e)) => return Err(e),
                None => return Ok(data),
            }
        }
    }

    pub async fn try_for_each<F, Fut>(&mut self, mut f: F) -> Result<(), io::Error>
    where
        F: FnMut(ResponseData) -> Fut,
        Fut: Future<Output = Result<(), io::Error>>,
    {
        loop {
            match self.next().await {
                Some(Ok(rsp)) => f(rsp).await?,
                Some(Err(e)) => return Err(e),
                None => return Ok(()),
            }
        }
    }

    pub async fn try_fold<S, Fut, F>(&mut self, mut state: S, mut f: F) -> Result<S, io::Error>
    where
        F: FnMut(S, ResponseData) -> Fut,
        Fut: Future<Output = Result<S, io::Error>>,
    {
        loop {
            match self.next().await {
                Some(Ok(rsp)) => match f(state, rsp).await {
                    Ok(new) => {
                        state = new;
                    }
                    Err(e) => return Err(e),
                },
                Some(Err(e)) => return Err(e),
                None => return Ok(state),
            }
        }
    }
}

impl<'a, T> Stream for ResponseStream<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin,
{
    type Item = Result<ResponseData, io::Error>;

    #[project]
    fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        let mut me = self.project();
        loop {
            match me.state {
                ResponseStreamState::Start => {
                    ready!(Pin::new(&mut me.client.transport).poll_ready(cx))?;
                    let pinned = Pin::new(&mut me.client.transport);
                    pinned.start_send(&Request(me.request_id.as_bytes(), &me.cmd.args))?;
                    *me.state = ResponseStreamState::Sending;
                }
                ResponseStreamState::Sending => {
                    let pinned = Pin::new(&mut me.client.transport);
                    ready!(pinned.poll_flush(cx))?;
                    *me.state = ResponseStreamState::Receiving;
                }
                ResponseStreamState::Receiving => {
                    match ready!(Pin::new(&mut me.client.transport).poll_next(cx)) {
                        Some(Ok(rsp)) => {
                            match rsp.request_id() {
                                Some(req_id) if req_id == me.request_id => {}
                                Some(_) | None => return Poll::Ready(Some(Ok(rsp))),
                            }

                            if let Some(next_state) = me.cmd.next_state.as_ref() {
                                me.client.state.state = *next_state;
                            }
                            *me.state = ResponseStreamState::Done;
                            return Poll::Ready(Some(Ok(rsp)));
                        }
                        Some(Err(e)) => return Poll::Ready(Some(Err(e))),
                        None => {
                            return Poll::Ready(Some(Err(io::Error::new(
                                io::ErrorKind::Other,
                                "stream ended before command completion",
                            ))))
                        }
                    }
                }
                ResponseStreamState::Done => {
                    return Poll::Ready(None);
                }
            }
        }
    }
}

enum ResponseStreamState {
    Start,
    Sending,
    Receiving,
    Done,
}

pub struct ClientState {
    state: State,
    request_ids: IdGenerator,
}

impl ClientState {
    pub fn new() -> Self {
        Self {
            state: State::NotAuthenticated,
            request_ids: IdGenerator::new(),
        }
    }
}

impl Default for ClientState {
    fn default() -> Self {
        Self::new()
    }
}

pub struct IdGenerator {
    next: u64,
}

impl IdGenerator {
    pub fn new() -> Self {
        Self { next: 0 }
    }
}

impl Default for IdGenerator {
    fn default() -> Self {
        Self::new()
    }
}

impl Iterator for IdGenerator {
    type Item = RequestId;
    fn next(&mut self) -> Option<Self::Item> {
        self.next += 1;
        Some(RequestId(format!("A{:04}", self.next % 10_000)))
    }
}
<commit_msg>Eliminate unnecessary abstraction<commit_after>use std::future::Future;
use std::io;
use std::net::ToSocketAddrs;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};

use futures::{ready, Sink, Stream, StreamExt};
use pin_project::{pin_project, project};
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;
use tokio_rustls::rustls::ClientConfig;
use tokio_rustls::webpki::DNSNameRef;
use tokio_rustls::{client::TlsStream, TlsConnector};
use tokio_util::codec::Decoder;

use crate::proto::{ImapCodec, ImapTransport, ResponseData};
use imap_proto::builders::command::Command;
use imap_proto::{Request, RequestId, State};

pub mod builder {
    pub use imap_proto::builders::command::{fetch, CommandBuilder, FetchCommand};
}

pub type TlsClient = Client<TlsStream<TcpStream>>;

pub struct Client<T> {
    transport: ImapTransport<T>,
    state: State,
    request_ids: IdGenerator,
}

impl TlsClient {
    pub async fn connect(server: &str) -> io::Result<(ResponseData, Self)> {
        let addr = (server, 993).to_socket_addrs()?.next().ok_or_else(|| {
            io::Error::new(
                io::ErrorKind::Other,
                format!("no IP addresses found for {}", server),
            )
        })?;

        let mut tls_config = ClientConfig::new();
        tls_config
            .root_store
            .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
        let connector: TlsConnector = Arc::new(tls_config).into();

        let stream = TcpStream::connect(&addr).await?;
        let stream = connector
            .connect(DNSNameRef::try_from_ascii_str(server).unwrap(), stream)
            .await?;
        let mut transport = ImapCodec::default().framed(stream);

        let greeting = match transport.next().await {
            Some(greeting) => Ok(greeting),
            None => Err(io::Error::new(io::ErrorKind::Other, "no greeting found")),
        }?;
        let client = Client {
            transport,
            state: State::NotAuthenticated,
            request_ids: IdGenerator::new(),
        };

        greeting.map(|greeting| (greeting, client))
    }

    pub fn call<C: Into<Command>>(&mut self, cmd: C) -> ResponseStream<TlsStream<TcpStream>> {
        ResponseStream::new(self, cmd.into())
    }
}

#[pin_project]
pub struct ResponseStream<'a, T> {
    #[pin]
    client: &'a mut Client<T>,
    request_id: RequestId,
    cmd: Command,
    state: ResponseStreamState,
}

impl<'a, T> ResponseStream<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin,
{
    pub fn new(client: &mut Client<T>, cmd: Command) -> ResponseStream<'_, T> {
        let request_id = client.request_ids.next().unwrap(); // safe: never returns Err,
        ResponseStream {
            client,
            request_id,
            cmd,
            state: ResponseStreamState::Start,
        }
    }

    pub async fn try_collect(&mut self) -> Result<Vec<ResponseData>, io::Error> {
        let mut data = vec![];
        loop {
            match self.next().await {
                Some(Ok(rsp)) => {
                    data.push(rsp);
                }
                Some(Err(e)) => return Err(e),
                None => return Ok(data),
            }
        }
    }

    pub async fn try_for_each<F, Fut>(&mut self, mut f: F) -> Result<(), io::Error>
    where
        F: FnMut(ResponseData) -> Fut,
        Fut: Future<Output = Result<(), io::Error>>,
    {
        loop {
            match self.next().await {
                Some(Ok(rsp)) => f(rsp).await?,
                Some(Err(e)) => return Err(e),
                None => return Ok(()),
            }
        }
    }

    pub async fn try_fold<S, Fut, F>(&mut self, mut state: S, mut f: F) -> Result<S, io::Error>
    where
        F: FnMut(S, ResponseData) -> Fut,
        Fut: Future<Output = Result<S, io::Error>>,
    {
        loop {
            match self.next().await {
                Some(Ok(rsp)) => match f(state, rsp).await {
                    Ok(new) => {
                        state = new;
                    }
                    Err(e) => return Err(e),
                },
                Some(Err(e)) => return Err(e),
                None => return Ok(state),
            }
        }
    }
}

impl<'a, T> Stream for ResponseStream<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin,
{
    type Item = Result<ResponseData, io::Error>;

    #[project]
    fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        let mut me = self.project();
        loop {
            match me.state {
                ResponseStreamState::Start => {
                    ready!(Pin::new(&mut me.client.transport).poll_ready(cx))?;
                    let pinned = Pin::new(&mut me.client.transport);
                    pinned.start_send(&Request(me.request_id.as_bytes(), &me.cmd.args))?;
                    *me.state = ResponseStreamState::Sending;
                }
                ResponseStreamState::Sending => {
                    let pinned = Pin::new(&mut me.client.transport);
                    ready!(pinned.poll_flush(cx))?;
                    *me.state = ResponseStreamState::Receiving;
                }
                ResponseStreamState::Receiving => {
                    match ready!(Pin::new(&mut me.client.transport).poll_next(cx)) {
                        Some(Ok(rsp)) => {
                            match rsp.request_id() {
                                Some(req_id) if req_id == me.request_id => {}
                                Some(_) | None => return Poll::Ready(Some(Ok(rsp))),
                            }

                            if let Some(next_state) = me.cmd.next_state.as_ref() {
                                me.client.state = *next_state;
                            }
                            *me.state = ResponseStreamState::Done;
                            return Poll::Ready(Some(Ok(rsp)));
                        }
                        Some(Err(e)) => return Poll::Ready(Some(Err(e))),
                        None => {
                            return Poll::Ready(Some(Err(io::Error::new(
                                io::ErrorKind::Other,
                                "stream ended before command completion",
                            ))))
                        }
                    }
                }
                ResponseStreamState::Done => {
                    return Poll::Ready(None);
                }
            }
        }
    }
}

enum ResponseStreamState {
    Start,
    Sending,
    Receiving,
    Done,
}

pub struct IdGenerator {
    next: u64,
}

impl IdGenerator {
    pub fn new() -> Self {
        Self { next: 0 }
    }
}

impl Default for IdGenerator {
    fn default() -> Self {
        Self::new()
    }
}

impl Iterator for IdGenerator {
    type Item = RequestId;
    fn next(&mut self) -> Option<Self::Item> {
        self.next += 1;
        Some(RequestId(format!("A{:04}", self.next % 10_000)))
    }
}
<|endoftext|>