<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use libimagstore::storeid::StoreId;
use libimagstore::store::Entry;
use libimagstore::store::EntryHeader;
use libimagstore::store::Result as StoreResult;
use libimagerror::into::IntoError;

use error::LinkErrorKind as LEK;
use error::MapErrInto;
use result::Result;
use self::iter::LinkIter;
use self::iter::IntoValues;

use toml::Value;

pub type Link = StoreId;

pub trait InternalLinker {

    /// Get the internal links from the implementor object
    fn get_internal_links(&self) -> Result<LinkIter>;

    /// Set the internal links for the implementor object
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<LinkIter>;

    /// Add an internal link to the implementor object
    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()>;

    /// Remove an internal link from the implementor object
    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()>;

}

pub mod iter {
    use std::vec::IntoIter;
    use std::cmp::Ordering;
    use super::Link;

    use error::LinkErrorKind as LEK;
    use error::MapErrInto;
    use result::Result;

    use toml::Value;
    use itertools::Itertools;

    pub struct LinkIter(IntoIter<Link>);

    impl LinkIter {

        pub fn new(v: Vec<Link>) -> LinkIter {
            LinkIter(v.into_iter())
        }

    }

    impl Iterator for LinkIter {
        type Item = Link;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.next()
        }
    }

    pub trait IntoValues {
        fn into_values(self) -> IntoIter<Result<Value>>;
    }

    impl<I: Iterator<Item = Link>> IntoValues for I {
        fn into_values(self) -> IntoIter<Result<Value>> {
            self.map(|s| s.without_base().to_str().map_err_into(LEK::InternalConversionError))
                .unique_by(|entry| {
                    match entry {
                        &Ok(ref e) => Some(e.clone()),
                        &Err(_) => None,
                    }
                })
                .map(|elem| elem.map(Value::String))
                .sorted_by(|a, b| {
                    match (a, b) {
                        (&Ok(Value::String(ref a)), &Ok(Value::String(ref b))) => Ord::cmp(a, b),
                        (&Err(_), _) | (_, &Err(_)) => Ordering::Equal,
                        _ => unreachable!()
                    }
                })
                .into_iter()
        }
    }

}

impl InternalLinker for Entry {

    fn get_internal_links(&self) -> Result<LinkIter> {
        process_rw_result(self.get_header().read("imag.links"))
    }

    /// Set the links in a header and return the old links, if any.
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<LinkIter> {
        use internal::iter::IntoValues;

        let self_location = self.get_location().clone();
        let mut new_links = vec![];

        for link in links {
            if let Err(e) = add_foreign_link(link, self_location.clone()) {
                return Err(e);
            }
            let link = link.get_location().clone();
            new_links.push(link);
        }

        let new_links = try!(LinkIter::new(new_links)
                             .into_values()
                             .fold(Ok(vec![]), |acc, elem| {
                                acc.and_then(move |mut v| {
                                    elem.map_err_into(LEK::InternalConversionError)
                                        .map(|e| {
                                            v.push(e);
                                            v
                                        })
                                })
                            }));
        process_rw_result(self.get_header_mut().set("imag.links", Value::Array(new_links)))
    }

    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let new_link = link.get_location().clone();

        add_foreign_link(link, self.get_location().clone())
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|links| {
                        let links = links.chain(LinkIter::new(vec![new_link]));
                        rewrite_links(self.get_header_mut(), links)
                    })
            })
    }

    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let own_loc   = link.get_location().clone();
        let other_loc = link.get_location().clone();

        link.get_internal_links()
            .and_then(|links| {
                rewrite_links(self.get_header_mut(), links.filter(|l| *l != own_loc))
            })
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|links| {
                        rewrite_links(link.get_header_mut(), links.filter(|l| *l != other_loc))
                    })
            })
    }

}

fn rewrite_links<I: Iterator<Item = Link>>(header: &mut EntryHeader, links: I) -> Result<()> {
    let links = try!(links.into_values()
                     .fold(Ok(vec![]), |acc, elem| {
                        acc.and_then(move |mut v| {
                            elem.map_err_into(LEK::InternalConversionError)
                                .map(|e| {
                                    v.push(e);
                                    v
                                })
                        })
                     }));

    let process = header.set("imag.links", Value::Array(links));
    process_rw_result(process).map(|_| ())
}

/// When Linking A -> B, the specification wants us to link back B -> A.
/// This is a helper function which does this.
fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
    target.get_internal_links()
        .and_then(|links| {
            let links = try!(links
                             .chain(LinkIter::new(vec![from]))
                             .into_values()
                             .fold(Ok(vec![]), |acc, elem| {
                                acc.and_then(move |mut v| {
                                    elem.map_err_into(LEK::InternalConversionError)
                                        .map(|e| {
                                            v.push(e);
                                            v
                                        })
                                })
                             }));
            process_rw_result(target.get_header_mut().set("imag.links", Value::Array(links)))
                .map(|_| ())
        })
}

fn process_rw_result(links: StoreResult<Option<Value>>) -> Result<LinkIter> {
    use std::path::PathBuf;

    let links = match links {
        Err(e) => {
            debug!("RW action on store failed. Generating LinkError");
            return Err(LEK::EntryHeaderReadError.into_error_with_cause(Box::new(e)))
        },
        Ok(None) => {
            debug!("We got no value from the header!");
            return Ok(LinkIter::new(vec![]))
        },
        Ok(Some(Value::Array(l))) => l,
        Ok(Some(_)) => {
            debug!("We expected an Array for the links, but there was a non-Array!");
            return Err(LEK::ExistingLinkTypeWrong.into());
        }
    };

    if !links.iter().all(|l| is_match!(*l, Value::String(_))) {
        debug!("At least one of the Values which were expected in the Array of links is a non-String!");
        debug!("Generating LinkError");
        return Err(LEK::ExistingLinkTypeWrong.into());
    }

    let links : Vec<Link> = try!(links.into_iter()
        .map(|link| {
            match link {
                Value::String(s) => StoreId::new_baseless(PathBuf::from(s))
                    .map_err_into(LEK::StoreIdError),
                _ => unreachable!(),
            }
        })
        .collect());

    debug!("Ok, the RW action was successful, returning link vector now!");
    Ok(LinkIter::new(links))
}

#[cfg(test)]
mod test {
    use std::path::PathBuf;

    use libimagstore::store::Store;

    use super::InternalLinker;

    pub fn get_store() -> Store {
        Store::new(PathBuf::from("/"), None).unwrap()
    }

    #[test]
    fn test_new_entry_no_links() {
        let store = get_store();
        let entry = store.create(PathBuf::from("test_new_entry_no_links")).unwrap();
        let links = entry.get_internal_links();
        assert!(links.is_ok());
        let links = links.unwrap();
        assert_eq!(links.collect::<Vec<_>>().len(), 0);
    }

}

<commit_msg>Add test for linking+unlinking<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use libimagstore::storeid::StoreId;
use libimagstore::store::Entry;
use libimagstore::store::EntryHeader;
use libimagstore::store::Result as StoreResult;
use libimagerror::into::IntoError;

use error::LinkErrorKind as LEK;
use error::MapErrInto;
use result::Result;
use self::iter::LinkIter;
use self::iter::IntoValues;

use toml::Value;

pub type Link = StoreId;

pub trait InternalLinker {

    /// Get the internal links from the implementor object
    fn get_internal_links(&self) -> Result<LinkIter>;

    /// Set the internal links for the implementor object
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<LinkIter>;

    /// Add an internal link to the implementor object
    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()>;

    /// Remove an internal link from the implementor object
    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()>;

}

pub mod iter {
    use std::vec::IntoIter;
    use std::cmp::Ordering;
    use super::Link;

    use error::LinkErrorKind as LEK;
    use error::MapErrInto;
    use result::Result;

    use toml::Value;
    use itertools::Itertools;

    pub struct LinkIter(IntoIter<Link>);

    impl LinkIter {

        pub fn new(v: Vec<Link>) -> LinkIter {
            LinkIter(v.into_iter())
        }

    }

    impl Iterator for LinkIter {
        type Item = Link;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.next()
        }
    }

    pub trait IntoValues {
        fn into_values(self) -> IntoIter<Result<Value>>;
    }

    impl<I: Iterator<Item = Link>> IntoValues for I {
        fn into_values(self) -> IntoIter<Result<Value>> {
            self.map(|s| s.without_base().to_str().map_err_into(LEK::InternalConversionError))
                .unique_by(|entry| {
                    match entry {
                        &Ok(ref e) => Some(e.clone()),
                        &Err(_) => None,
                    }
                })
                .map(|elem| elem.map(Value::String))
                .sorted_by(|a, b| {
                    match (a, b) {
                        (&Ok(Value::String(ref a)), &Ok(Value::String(ref b))) => Ord::cmp(a, b),
                        (&Err(_), _) | (_, &Err(_)) => Ordering::Equal,
                        _ => unreachable!()
                    }
                })
                .into_iter()
        }
    }

}

impl InternalLinker for Entry {

    fn get_internal_links(&self) -> Result<LinkIter> {
        process_rw_result(self.get_header().read("imag.links"))
    }

    /// Set the links in a header and return the old links, if any.
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<LinkIter> {
        use internal::iter::IntoValues;

        let self_location = self.get_location().clone();
        let mut new_links = vec![];

        for link in links {
            if let Err(e) = add_foreign_link(link, self_location.clone()) {
                return Err(e);
            }
            let link = link.get_location().clone();
            new_links.push(link);
        }

        let new_links = try!(LinkIter::new(new_links)
                             .into_values()
                             .fold(Ok(vec![]), |acc, elem| {
                                acc.and_then(move |mut v| {
                                    elem.map_err_into(LEK::InternalConversionError)
                                        .map(|e| {
                                            v.push(e);
                                            v
                                        })
                                })
                            }));
        process_rw_result(self.get_header_mut().set("imag.links", Value::Array(new_links)))
    }

    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let new_link = link.get_location().clone();

        add_foreign_link(link, self.get_location().clone())
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|links| {
                        let links = links.chain(LinkIter::new(vec![new_link]));
                        rewrite_links(self.get_header_mut(), links)
                    })
            })
    }

    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let own_loc   = link.get_location().clone();
        let other_loc = link.get_location().clone();

        link.get_internal_links()
            .and_then(|links| {
                rewrite_links(self.get_header_mut(), links.filter(|l| *l != own_loc))
            })
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|links| {
                        rewrite_links(link.get_header_mut(), links.filter(|l| *l != other_loc))
                    })
            })
    }

}

fn rewrite_links<I: Iterator<Item = Link>>(header: &mut EntryHeader, links: I) -> Result<()> {
    let links = try!(links.into_values()
                     .fold(Ok(vec![]), |acc, elem| {
                        acc.and_then(move |mut v| {
                            elem.map_err_into(LEK::InternalConversionError)
                                .map(|e| {
                                    v.push(e);
                                    v
                                })
                        })
                     }));

    let process = header.set("imag.links", Value::Array(links));
    process_rw_result(process).map(|_| ())
}

/// When Linking A -> B, the specification wants us to link back B -> A.
/// This is a helper function which does this.
fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
    target.get_internal_links()
        .and_then(|links| {
            let links = try!(links
                             .chain(LinkIter::new(vec![from]))
                             .into_values()
                             .fold(Ok(vec![]), |acc, elem| {
                                acc.and_then(move |mut v| {
                                    elem.map_err_into(LEK::InternalConversionError)
                                        .map(|e| {
                                            v.push(e);
                                            v
                                        })
                                })
                             }));
            process_rw_result(target.get_header_mut().set("imag.links", Value::Array(links)))
                .map(|_| ())
        })
}

fn process_rw_result(links: StoreResult<Option<Value>>) -> Result<LinkIter> {
    use std::path::PathBuf;

    let links = match links {
        Err(e) => {
            debug!("RW action on store failed. Generating LinkError");
            return Err(LEK::EntryHeaderReadError.into_error_with_cause(Box::new(e)))
        },
        Ok(None) => {
            debug!("We got no value from the header!");
            return Ok(LinkIter::new(vec![]))
        },
        Ok(Some(Value::Array(l))) => l,
        Ok(Some(_)) => {
            debug!("We expected an Array for the links, but there was a non-Array!");
            return Err(LEK::ExistingLinkTypeWrong.into());
        }
    };

    if !links.iter().all(|l| is_match!(*l, Value::String(_))) {
        debug!("At least one of the Values which were expected in the Array of links is a non-String!");
        debug!("Generating LinkError");
        return Err(LEK::ExistingLinkTypeWrong.into());
    }

    let links : Vec<Link> = try!(links.into_iter()
        .map(|link| {
            match link {
                Value::String(s) => StoreId::new_baseless(PathBuf::from(s))
                    .map_err_into(LEK::StoreIdError),
                _ => unreachable!(),
            }
        })
        .collect());

    debug!("Ok, the RW action was successful, returning link vector now!");
    Ok(LinkIter::new(links))
}

#[cfg(test)]
mod test {
    use std::path::PathBuf;

    use libimagstore::store::Store;

    use super::InternalLinker;

    pub fn get_store() -> Store {
        Store::new(PathBuf::from("/"), None).unwrap()
    }

    #[test]
    fn test_new_entry_no_links() {
        let store = get_store();
        let entry = store.create(PathBuf::from("test_new_entry_no_links")).unwrap();
        let links = entry.get_internal_links();
        assert!(links.is_ok());
        let links = links.unwrap();
        assert_eq!(links.collect::<Vec<_>>().len(), 0);
    }

    #[test]
    fn test_link_two_entries() {
        let store = get_store();
        let mut e1 = store.create(PathBuf::from("test_link_two_entries1")).unwrap();
        assert!(e1.get_internal_links().is_ok());

        let mut e2 = store.create(PathBuf::from("test_link_two_entries2")).unwrap();
        assert!(e2.get_internal_links().is_ok());

        {
            assert!(e1.add_internal_link(&mut e2).is_ok());

            let e1_links = e1.get_internal_links().unwrap().collect::<Vec<_>>();
            let e2_links = e2.get_internal_links().unwrap().collect::<Vec<_>>();

            assert_eq!(e1_links.len(), 1);
            assert_eq!(e2_links.len(), 1);

            assert!(e1_links.first().map(|l| l.clone().with_base(store.path().clone()) == *e2.get_location()).unwrap_or(false));
            assert!(e2_links.first().map(|l| l.clone().with_base(store.path().clone()) == *e1.get_location()).unwrap_or(false));
        }

        {
            assert!(e1.remove_internal_link(&mut e2).is_ok());

            println!("{:?}", e2.to_str());
            let e2_links = e2.get_internal_links().unwrap().collect::<Vec<_>>();
            assert_eq!(e2_links.len(), 0, "Expected [], got: {:?}", e2_links);

            println!("{:?}", e1.to_str());
            let e1_links = e1.get_internal_links().unwrap().collect::<Vec<_>>();
            assert_eq!(e1_links.len(), 0, "Expected [], got: {:?}", e1_links);

        }
    }

}

<|endoftext|>


<commit_before>use result::Result;

pub type Link = String;

pub fn extract_links(buf: &str) -> Result<Vec<Link>> {
    unimplemented!()
}

<commit_msg>Implement link extractor<commit_after>use result::Result;

use hoedown::renderer::Render;
use hoedown::Buffer;
use hoedown::Markdown;

pub struct Link {
    pub title: String,
    pub link: String,
}

struct LinkExtractor {
    links: Vec<Link>,
}

impl LinkExtractor {

    pub fn new() -> LinkExtractor {
        LinkExtractor { links: vec![] }
    }

    pub fn links(self) -> Vec<Link> {
        self.links
    }

}

impl Render for LinkExtractor {

    fn link(&mut self,
            _: &mut Buffer,
            content: Option<&Buffer>,
            link: Option<&Buffer>,
            _: Option<&Buffer>)
        -> bool
    {
        let link  = link.and_then(|l| l.to_str().ok()).map(String::from);
        let content = content.and_then(|l| l.to_str().ok()).map(String::from);

        match (link, content) {
            (Some(link), Some(content)) => {
                self.links.push(Link { link: link, title: content });
                false
            },

            (_, _) => {
                false
            },
        }

    }

}

pub fn extract_links(buf: &str) -> Vec<Link> {
    let mut le = LinkExtractor::new();
    le.render(&Markdown::new(buf));
    le.links()
}

#[cfg(test)]
mod test {
    use super::{Link, extract_links};

    #[test]
    fn test_one_link() {
        let testtext = "Some [example text](http://example.com).";

        let exp = Link {
            title: String::from("example text"),
            link:  String::from("http://example.com"),
        };

        let mut links = extract_links(testtext);
        assert_eq!(1, links.len());
        assert_eq!(exp, links.pop().unwrap())
    }

}

<|endoftext|>


<commit_before>use system::SystemData;

pub struct Registers
{
    pub accumulator:u8,
    pub flags:u8,
    pub b_register:u8,
    pub c_register:u8,
    pub d_register:u8,
    pub e_register:u8,
    pub h_register:u8,
    pub l_register:u8,
    pub stack_pointer: u16,
    pub program_counter: u16,
}

// Returns clock cycles passed during opcode
pub fn parse_opcode(system_data: &mut SystemData, registers: &mut Registers) -> u8
{
    let mut cycles: u8 = 0;
    let opcode: u8 = system_data.mem_map[registers.program_counter as usize];
    println!("{:x}", opcode);

    //inc
    if (opcode & 0xC7) == 0x04
    {
        if (opcode & 0x38) == 0x38{
            registers.accumulator += 1;
            registers.program_counter += 1;
            cycles = 1;
        }
        else
        {
            println!("No Opcode Found");
        }
    }
    //16 bit ld group
    else if (opcode & 0xCF) == 0x01
    {
        cycles = 2;

        if (opcode & 0x30) == 0x30
        {
            registers.stack_pointer = system_data.mem_map[(registers.program_counter + 1) as usize] as u16 | (system_data.mem_map[(registers.program_counter + 2) as usize] as u16) << 8;
        }
        else if (opcode & 0x30) == 0x20
        {
            registers.h_register = system_data.mem_map[(registers.program_counter + 2) as usize];
            registers.l_register = system_data.mem_map[(registers.program_counter + 1) as usize];
        }
        else if (opcode & 0x30) == 0x10
        {
            registers.d_register = system_data.mem_map[(registers.program_counter + 2) as usize];
            registers.e_register = system_data.mem_map[(registers.program_counter + 1) as usize];
        }
        else if (opcode & 0x30) == 0x00
        {
            registers.b_register = system_data.mem_map[(registers.program_counter + 2) as usize];
            registers.c_register = system_data.mem_map[(registers.program_counter + 1) as usize];
        }
        else
        {
            cycles = 0;
            println!("No Opcode Found");
        }

        registers.program_counter += 3;
    }
    //xor
    else if (opcode & 0xF8) == 0xA8
    {
        if (opcode & 0x07) == 0x07
        {
            registers.accumulator = registers.accumulator ^ registers.accumulator;
            registers.program_counter += 1;
            cycles = 1;
            registers.flags = 0x00;
            if  registers.accumulator ==  0 {
                registers.flags = registers.flags | 0x80;
            }
        }
        else
        {
            println!("No Opcode Found");
        }
    }
    //LDD (HL), A - 32
    else if (opcode == 0x32)
    {
        let mut mem_loc: u16 = registers.l_register as u16 | (registers.h_register as u16) << 8;
        system_data.mem_map[mem_loc as usize] = registers.accumulator;
        mem_loc -= 1;
        registers.l_register = (mem_loc & 0x0F) as u8;
        registers.h_register = ((mem_loc & 0xF0) >> 8) as u8;
        cycles = 2;
        registers.program_counter += 1;
    }
    //cb codes
    else if (opcode == 0xCB){
        let opcode_next :u8 = system_data.mem_map[(registers.program_counter + 1) as usize];
        //bit b, r
        if (opcode_next & 0xC0) == 0x40
        {
            cycles = 2;
            let test_bit: u8 = (opcode_next & 0x38) >> 3;
            if (opcode_next & 0x07) == 0x04
            {
                registers.flags = registers.flags & 0x10;

                if ((registers.h_register >> test_bit) & 0x01) == 0x00
                {
                    registers.flags = registers.flags | 0xA0;
                }
                else
                {
                    registers.flags = registers.flags | 0x20;
                }
            }
            else
            {
                cycles = 0;
                println!("No Opcode Found");
            }
            registers.program_counter += 2;
        }
        else
        {
            println!("No Opcode Found");
        }
    }
    else
    {
        println!("No Opcode Found");
    }

    return cycles;
}

pub fn init_registers() -> Registers
{
    return Registers
    {
        accumulator: 0,
        flags: 0,
        b_register:0,
        c_register:0,
        d_register:0,
        e_register:0,
        h_register:0,
        l_register:0,
        stack_pointer: 0,
        program_counter: 0,
    };
}<commit_msg>Added a jnz opcode<commit_after>use system::SystemData;

pub struct Registers
{
    pub accumulator:u8,
    pub flags:u8,
    pub b_register:u8,
    pub c_register:u8,
    pub d_register:u8,
    pub e_register:u8,
    pub h_register:u8,
    pub l_register:u8,
    pub stack_pointer: u16,
    pub program_counter: u16,
}

// Returns clock cycles passed during opcode
pub fn parse_opcode(system_data: &mut SystemData, registers: &mut Registers) -> u8
{
    let mut cycles: u8 = 0;
    let opcode: u8 = system_data.mem_map[registers.program_counter as usize];
    println!("{:x}", opcode);

    //inc
    if (opcode & 0xC7) == 0x04
    {
        if (opcode & 0x38) == 0x38{
            registers.accumulator += 1;
            registers.program_counter += 1;
            cycles = 1;
        }
        else
        {
            println!("No Opcode Found");
        }
    }
    //16 bit ld group
    else if (opcode & 0xCF) == 0x01
    {
        cycles = 2;

        if (opcode & 0x30) == 0x30
        {
            registers.stack_pointer = system_data.mem_map[(registers.program_counter + 1) as usize] as u16 | (system_data.mem_map[(registers.program_counter + 2) as usize] as u16) << 8;
        }
        else if (opcode & 0x30) == 0x20
        {
            registers.h_register = system_data.mem_map[(registers.program_counter + 2) as usize];
            registers.l_register = system_data.mem_map[(registers.program_counter + 1) as usize];
        }
        else if (opcode & 0x30) == 0x10
        {
            registers.d_register = system_data.mem_map[(registers.program_counter + 2) as usize];
            registers.e_register = system_data.mem_map[(registers.program_counter + 1) as usize];
        }
        else if (opcode & 0x30) == 0x00
        {
            registers.b_register = system_data.mem_map[(registers.program_counter + 2) as usize];
            registers.c_register = system_data.mem_map[(registers.program_counter + 1) as usize];
        }
        else
        {
            cycles = 0;
            println!("No Opcode Found");
        }

        registers.program_counter += 3;
    }
    //xor
    else if (opcode & 0xF8) == 0xA8
    {
        if (opcode & 0x07) == 0x07
        {
            registers.accumulator = registers.accumulator ^ registers.accumulator;
            registers.program_counter += 1;
            cycles = 1;
            registers.flags = 0x00;
            if  registers.accumulator ==  0 {
                registers.flags = registers.flags | 0x80;
            }
        }
        else
        {
            println!("No Opcode Found");
        }
    }
    else if (opcode == 0x20)
    {
        if (registers.flags & 0x80) != 0x80 {
            cycles = 3;
            let pc_dest: i8 = (system_data.mem_map[(registers.program_counter + 1) as usize] + 2) as i8;
            registers.program_counter = (registers.program_counter as i32 + pc_dest as i32) as u16;
        }
        else {
            cycles = 2;
            registers.program_counter += 2;
        }
    }

    //LDD (HL), A - 32
    else if (opcode == 0x32)
    {
        let mut mem_loc: u16 = registers.l_register as u16 | (registers.h_register as u16) << 8;
        system_data.mem_map[mem_loc as usize] = registers.accumulator;
        mem_loc -= 1;
        registers.l_register = (mem_loc & 0x0F) as u8;
        registers.h_register = ((mem_loc & 0xF0) >> 8) as u8;
        cycles = 2;
        registers.program_counter += 1;
    }
    //cb codes
    else if (opcode == 0xCB){
        let opcode_next :u8 = system_data.mem_map[(registers.program_counter + 1) as usize];
        //bit b, r
        if (opcode_next & 0xC0) == 0x40
        {
            cycles = 2;
            let test_bit: u8 = (opcode_next & 0x38) >> 3;
            if (opcode_next & 0x07) == 0x04
            {
                registers.flags = registers.flags & 0x10;

                if ((registers.h_register >> test_bit) & 0x01) == 0x00
                {
                    registers.flags = registers.flags | 0xA0;
                }
                else
                {
                    registers.flags = registers.flags | 0x20;
                }
            }
            else
            {
                cycles = 0;
                println!("No Opcode Found");
            }
            registers.program_counter += 2;
        }
        else
        {
            println!("No Opcode Found");
        }
    }
    else
    {
        println!("No Opcode Found");
    }

    return cycles;
}

pub fn init_registers() -> Registers
{
    return Registers
    {
        accumulator: 0,
        flags: 0,
        b_register:0,
        c_register:0,
        d_register:0,
        e_register:0,
        h_register:0,
        l_register:0,
        stack_pointer: 0,
        program_counter: 0,
    };
}<|endoftext|>


<commit_before>use clock::Clock;

//
// Clock Creation
//

#[test]
fn test_on_the_hour() {
    assert_eq!(Clock::new(8, 0).to_string(), "08:00");
}

#[test]
fn test_past_the_hour() {
    assert_eq!(Clock::new(11, 9).to_string(), "11:09");
}

#[test]
fn test_midnight_is_zero_hours() {
    assert_eq!(Clock::new(24, 0).to_string(), "00:00");
}

#[test]
fn test_hour_rolls_over() {
    assert_eq!(Clock::new(25, 0).to_string(), "01:00");
}

#[test]
fn test_hour_rolls_over_continuously() {
    assert_eq!(Clock::new(100, 0).to_string(), "04:00");
}

#[test]
fn test_sixty_minutes_is_next_hour() {
    assert_eq!(Clock::new(1, 60).to_string(), "02:00");
}

#[test]
fn test_minutes_roll_over() {
    assert_eq!(Clock::new(0, 160).to_string(), "02:40");
}

#[test]
fn test_minutes_roll_over_continuously() {
    assert_eq!(Clock::new(0, 1723).to_string(), "04:43");
}

#[test]
fn test_hours_and_minutes_roll_over() {
    assert_eq!(Clock::new(25, 160).to_string(), "03:40");
}

#[test]
fn test_hours_and_minutes_roll_over_continuously() {
    assert_eq!(Clock::new(201, 3001).to_string(), "11:01");
}

#[test]
fn test_hours_and_minutes_roll_over_to_exactly_midnight() {
    assert_eq!(Clock::new(72, 8640).to_string(), "00:00");
}

#[test]
fn test_negative_hour() {
    assert_eq!(Clock::new(-1, 15).to_string(), "23:15");
}

#[test]
fn test_negative_hour_roll_over() {
    assert_eq!(Clock::new(-25, 00).to_string(), "23:00");
}

#[test]
fn test_negative_hour_roll_over_continuously() {
    assert_eq!(Clock::new(-91, 00).to_string(), "05:00");
}

#[test]
fn test_negative_minutes() {
    assert_eq!(Clock::new(1, -40).to_string(), "00:20");
}

#[test]
fn test_negative_minutes_roll_over() {
    assert_eq!(Clock::new(1, -160).to_string(), "22:20");
}

#[test]
fn test_negative_minutes_roll_over_continuously() {
    assert_eq!(Clock::new(1, -4820).to_string(), "16:40");
}

#[test]
fn test_negative_sixty_minutes_is_prev_hour() {
    assert_eq!(Clock::new(2, -60).to_string(), "01:00");
}

#[test]
fn test_negative_one_twenty_minutes_is_two_prev_hours() {
    assert_eq!(Clock::new(1, -120).to_string(), "23:00");
}

#[test]
fn test_negative_hour_and_minutes_both_roll_over() {
    assert_eq!(Clock::new(-25, -160).to_string(), "20:20");
}

#[test]
fn test_negative_hour_and_minutes_both_roll_over_continuously() {
    assert_eq!(Clock::new(-121, -5810).to_string(), "22:10");
}

#[test]
fn test_zero_hour_and_negative_minutes() {
    assert_eq!(Clock::new(0, -22).to_string(), "23:38");
}

//
// Clock Math
//

#[test]
fn test_add_minutes() {
    let clock = Clock::new(10, 0).add_minutes(3);
    assert_eq!(clock.to_string(), "10:03");
}

#[test]
fn test_add_no_minutes() {
    let clock = Clock::new(6, 41).add_minutes(0);
    assert_eq!(clock.to_string(), "06:41");
}

#[test]
fn test_add_to_next_hour() {
    let clock = Clock::new(0, 45).add_minutes(40);
    assert_eq!(clock.to_string(), "01:25");
}

#[test]
fn test_add_more_than_one_hour() {
    let clock = Clock::new(10, 0).add_minutes(61);
    assert_eq!(clock.to_string(), "11:01");
}

#[test]
fn test_add_more_than_two_hours_with_carry() {
    let clock = Clock::new(0, 45).add_minutes(160);
    assert_eq!(clock.to_string(), "03:25");
}

#[test]
fn test_add_across_midnight() {
    let clock = Clock::new(23, 59).add_minutes(2);
    assert_eq!(clock.to_string(), "00:01");
}

#[test]
fn test_add_more_than_one_day() {
    let clock = Clock::new(5, 32).add_minutes(1500);
    assert_eq!(clock.to_string(), "06:32");
}

#[test]
fn test_add_more_than_two_days() {
    let clock = Clock::new(1, 1).add_minutes(3500);
    assert_eq!(clock.to_string(), "11:21");
}

#[test]
fn test_subtract_minutes() {
    let clock = Clock::new(10, 3).add_minutes(-3);
    assert_eq!(clock.to_string(), "10:00");
}

#[test]
fn test_subtract_to_previous_hour() {
    let clock = Clock::new(10, 3).add_minutes(-30);
    assert_eq!(clock.to_string(), "09:33");
}

#[test]
fn test_subtract_more_than_an_hour() {
    let clock = Clock::new(10, 3).add_minutes(-70);
    assert_eq!(clock.to_string(), "08:53");
}

#[test]
fn test_subtract_across_midnight() {
    let clock = Clock::new(0, 3).add_minutes(-4);
    assert_eq!(clock.to_string(), "23:59");
}

#[test]
fn test_subtract_more_than_two_hours() {
    let clock = Clock::new(0, 0).add_minutes(-160);
    assert_eq!(clock.to_string(), "21:20");
}

#[test]
fn test_subtract_more_than_two_hours_with_borrow() {
    let clock = Clock::new(6, 15).add_minutes(-160);
    assert_eq!(clock.to_string(), "03:35");
}

#[test]
fn test_subtract_more_than_one_day() {
    let clock = Clock::new(5, 32).add_minutes(-1500);
    assert_eq!(clock.to_string(), "04:32");
}

#[test]
fn test_subtract_more_than_two_days() {
    let clock = Clock::new(2, 20).add_minutes(-3000);
    assert_eq!(clock.to_string(), "00:20");
}

//
// Test Equality
//

#[test]
fn test_compare_clocks_for_equality() {
    assert_eq!(Clock::new(15, 37), Clock::new(15, 37));
}

#[test]
fn test_compare_clocks_a_minute_apart() {
    assert_ne!(Clock::new(15, 36), Clock::new(15, 37));
}

#[test]
fn test_compare_clocks_an_hour_apart() {
    assert_ne!(Clock::new(14, 37), Clock::new(15, 37));
}

#[test]
fn test_compare_clocks_with_hour_overflow() {
    assert_eq!(Clock::new(10, 37), Clock::new(34, 37));
}

#[test]
#[ignore]
fn test_compare_clocks_with_hour_overflow_by_several_days() {
    assert_eq!(Clock::new(99, 11), Clock::new(3, 11));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_hour() {
    assert_eq!(Clock::new(-2, 40), Clock::new(22, 40));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_hour_that_wraps() {
    assert_eq!(Clock::new(-31, 3), Clock::new(17, 3));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_hour_that_wraps_multiple_times() {
    assert_eq!(Clock::new(-83, 49), Clock::new(13, 49));
}

#[test]
#[ignore]
fn test_compare_clocks_with_minutes_overflow() {
    assert_eq!(Clock::new(0, 1441), Clock::new(0, 1));
}

#[test]
#[ignore]
fn test_compare_clocks_with_minutes_overflow_by_several_days() {
    assert_eq!(Clock::new(2, 4322), Clock::new(2, 2));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_minute() {
    assert_eq!(Clock::new(3, -20), Clock::new(2, 40));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_minute_that_wraps() {
    assert_eq!(Clock::new(5, -1490), Clock::new(4, 10));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_minute_that_wraps_multiple() {
    assert_eq!(Clock::new(6, -4305), Clock::new(6, 15));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_hours_and_minutes() {
    assert_eq!(Clock::new(-12, -268), Clock::new(7, 32));
}

#[test]
#[ignore]
fn test_compare_clocks_with_negative_hours_and_minutes_that_wrap() {
    assert_eq!(Clock::new(-54, -11_513), Clock::new(18, 7));
}

#[test]
#[ignore]
fn test_compare_full_clock_and_zeroed_clock() {
    assert_eq!(Clock::new(24, 0), Clock::new(0, 0));
}
<commit_msg>Solve clock<commit_after>use clock::Clock;

//
// Clock Creation
//

#[test]
fn test_on_the_hour() {
    assert_eq!(Clock::new(8, 0).to_string(), "08:00");
}

#[test]
fn test_past_the_hour() {
    assert_eq!(Clock::new(11, 9).to_string(), "11:09");
}

#[test]
fn test_midnight_is_zero_hours() {
    assert_eq!(Clock::new(24, 0).to_string(), "00:00");
}

#[test]
fn test_hour_rolls_over() {
    assert_eq!(Clock::new(25, 0).to_string(), "01:00");
}

#[test]
fn test_hour_rolls_over_continuously() {
    assert_eq!(Clock::new(100, 0).to_string(), "04:00");
}

#[test]
fn test_sixty_minutes_is_next_hour() {
    assert_eq!(Clock::new(1, 60).to_string(), "02:00");
}

#[test]
fn test_minutes_roll_over() {
    assert_eq!(Clock::new(0, 160).to_string(), "02:40");
}

#[test]
fn test_minutes_roll_over_continuously() {
    assert_eq!(Clock::new(0, 1723).to_string(), "04:43");
}

#[test]
fn test_hours_and_minutes_roll_over() {
    assert_eq!(Clock::new(25, 160).to_string(), "03:40");
}

#[test]
fn test_hours_and_minutes_roll_over_continuously() {
    assert_eq!(Clock::new(201, 3001).to_string(), "11:01");
}

#[test]
fn test_hours_and_minutes_roll_over_to_exactly_midnight() {
    assert_eq!(Clock::new(72, 8640).to_string(), "00:00");
}

#[test]
fn test_negative_hour() {
    assert_eq!(Clock::new(-1, 15).to_string(), "23:15");
}

#[test]
fn test_negative_hour_roll_over() {
    assert_eq!(Clock::new(-25, 00).to_string(), "23:00");
}

#[test]
fn test_negative_hour_roll_over_continuously() {
    assert_eq!(Clock::new(-91, 00).to_string(), "05:00");
}

#[test]
fn test_negative_minutes() {
    assert_eq!(Clock::new(1, -40).to_string(), "00:20");
}

#[test]
fn test_negative_minutes_roll_over() {
    assert_eq!(Clock::new(1, -160).to_string(), "22:20");
}

#[test]
fn test_negative_minutes_roll_over_continuously() {
    assert_eq!(Clock::new(1, -4820).to_string(), "16:40");
}

#[test]
fn test_negative_sixty_minutes_is_prev_hour() {
    assert_eq!(Clock::new(2, -60).to_string(), "01:00");
}

#[test]
fn test_negative_one_twenty_minutes_is_two_prev_hours() {
    assert_eq!(Clock::new(1, -120).to_string(), "23:00");
}

#[test]
fn test_negative_hour_and_minutes_both_roll_over() {
    assert_eq!(Clock::new(-25, -160).to_string(), "20:20");
}

#[test]
fn test_negative_hour_and_minutes_both_roll_over_continuously() {
    assert_eq!(Clock::new(-121, -5810).to_string(), "22:10");
}

#[test]
fn test_zero_hour_and_negative_minutes() {
    assert_eq!(Clock::new(0, -22).to_string(), "23:38");
}

//
// Clock Math
//

#[test]
fn test_add_minutes() {
    let clock = Clock::new(10, 0).add_minutes(3);
    assert_eq!(clock.to_string(), "10:03");
}

#[test]
fn test_add_no_minutes() {
    let clock = Clock::new(6, 41).add_minutes(0);
    assert_eq!(clock.to_string(), "06:41");
}

#[test]
fn test_add_to_next_hour() {
    let clock = Clock::new(0, 45).add_minutes(40);
    assert_eq!(clock.to_string(), "01:25");
}

#[test]
fn test_add_more_than_one_hour() {
    let clock = Clock::new(10, 0).add_minutes(61);
    assert_eq!(clock.to_string(), "11:01");
}

#[test]
fn test_add_more_than_two_hours_with_carry() {
    let clock = Clock::new(0, 45).add_minutes(160);
    assert_eq!(clock.to_string(), "03:25");
}

#[test]
fn test_add_across_midnight() {
    let clock = Clock::new(23, 59).add_minutes(2);
    assert_eq!(clock.to_string(), "00:01");
}

#[test]
fn test_add_more_than_one_day() {
    let clock = Clock::new(5, 32).add_minutes(1500);
    assert_eq!(clock.to_string(), "06:32");
}

#[test]
fn test_add_more_than_two_days() {
    let clock = Clock::new(1, 1).add_minutes(3500);
    assert_eq!(clock.to_string(), "11:21");
}

#[test]
fn test_subtract_minutes() {
    let clock = Clock::new(10, 3).add_minutes(-3);
    assert_eq!(clock.to_string(), "10:00");
}

#[test]
fn test_subtract_to_previous_hour() {
    let clock = Clock::new(10, 3).add_minutes(-30);
    assert_eq!(clock.to_string(), "09:33");
}

#[test]
fn test_subtract_more_than_an_hour() {
    let clock = Clock::new(10, 3).add_minutes(-70);
    assert_eq!(clock.to_string(), "08:53");
}

#[test]
fn test_subtract_across_midnight() {
    let clock = Clock::new(0, 3).add_minutes(-4);
    assert_eq!(clock.to_string(), "23:59");
}

#[test]
fn test_subtract_more_than_two_hours() {
    let clock = Clock::new(0, 0).add_minutes(-160);
    assert_eq!(clock.to_string(), "21:20");
}

#[test]
fn test_subtract_more_than_two_hours_with_borrow() {
    let clock = Clock::new(6, 15).add_minutes(-160);
    assert_eq!(clock.to_string(), "03:35");
}

#[test]
fn test_subtract_more_than_one_day() {
    let clock = Clock::new(5, 32).add_minutes(-1500);
    assert_eq!(clock.to_string(), "04:32");
}

#[test]
fn test_subtract_more_than_two_days() {
    let clock = Clock::new(2, 20).add_minutes(-3000);
    assert_eq!(clock.to_string(), "00:20");
}

//
// Test Equality
//

#[test]
fn test_compare_clocks_for_equality() {
    assert_eq!(Clock::new(15, 37), Clock::new(15, 37));
}

#[test]
fn test_compare_clocks_a_minute_apart() {
    assert_ne!(Clock::new(15, 36), Clock::new(15, 37));
}

#[test]
fn test_compare_clocks_an_hour_apart() {
    assert_ne!(Clock::new(14, 37), Clock::new(15, 37));
}

#[test]
fn test_compare_clocks_with_hour_overflow() {
    assert_eq!(Clock::new(10, 37), Clock::new(34, 37));
}

#[test]
fn test_compare_clocks_with_hour_overflow_by_several_days() {
    assert_eq!(Clock::new(99, 11), Clock::new(3, 11));
}

#[test]
fn test_compare_clocks_with_negative_hour() {
    assert_eq!(Clock::new(-2, 40), Clock::new(22, 40));
}

#[test]
fn test_compare_clocks_with_negative_hour_that_wraps() {
    assert_eq!(Clock::new(-31, 3), Clock::new(17, 3));
}

#[test]
fn test_compare_clocks_with_negative_hour_that_wraps_multiple_times() {
    assert_eq!(Clock::new(-83, 49), Clock::new(13, 49));
}

#[test]
fn test_compare_clocks_with_minutes_overflow() {
    assert_eq!(Clock::new(0, 1441), Clock::new(0, 1));
}

#[test]
fn test_compare_clocks_with_minutes_overflow_by_several_days() {
    assert_eq!(Clock::new(2, 4322), Clock::new(2, 2));
}

#[test]
fn test_compare_clocks_with_negative_minute() {
    assert_eq!(Clock::new(3, -20), Clock::new(2, 40));
}

#[test]
fn test_compare_clocks_with_negative_minute_that_wraps() {
    assert_eq!(Clock::new(5, -1490), Clock::new(4, 10));
}

#[test]
fn test_compare_clocks_with_negative_minute_that_wraps_multiple() {
    assert_eq!(Clock::new(6, -4305), Clock::new(6, 15));
}

#[test]
fn test_compare_clocks_with_negative_hours_and_minutes() {
    assert_eq!(Clock::new(-12, -268), Clock::new(7, 32));
}

#[test]
fn test_compare_clocks_with_negative_hours_and_minutes_that_wrap() {
    assert_eq!(Clock::new(-54, -11_513), Clock::new(18, 7));
}

#[test]
fn test_compare_full_clock_and_zeroed_clock() {
    assert_eq!(Clock::new(24, 0), Clock::new(0, 0));
}
<|endoftext|>


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

use std::env;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;

extern crate csv_checker;

fn report_errors_for_file(file: File) -> i32 {
    let mut exit = 0;

    let mut reader = BufReader::new(file);

    let report = csv_checker::csv_report(&mut reader);

    for error in report {
        exit = 1;
        println!(
            "error at line {}, col {}: {}",
            error.line, error.col, error.text
        );
    }

    exit
}

fn errors_for_args() -> i32 {
    let mut exit_code: i32 = 0;

    // Skip the first arg since it's the program itself
    let paths = env::args().skip(1);

    if paths.len() == 0 {
        panic!("Provide some paths!");
    }

    for arg in paths {
        println!("= {} =", arg);

        let path = Path::new(&arg);

        exit_code += match File::open(&path) {
            Err(_) => {
                println!("!!! Not found");
                1
            }
            Ok(file) => report_errors_for_file(file),
        };
    }

    exit_code
}

fn main() {
    let exit_code = errors_for_args();
    std::process::exit(exit_code);
}
<commit_msg>Set file exit code once<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::env;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;

extern crate csv_checker;

fn report_errors_for_file(file: File) -> i32 {
    let mut reader = BufReader::new(file);

    let mut report = csv_checker::csv_report(&mut reader).peekable();

    let exit = match report.peek() {
        None => 0,
        _ => 1,
    };

    for error in report {
        println!(
            "error at line {}, col {}: {}",
            error.line, error.col, error.text
        );
    }

    exit
}

fn errors_for_args() -> i32 {
    let mut exit_code: i32 = 0;

    // Skip the first arg since it's the program itself
    let paths = env::args().skip(1);

    if paths.len() == 0 {
        panic!("Provide some paths!");
    }

    for arg in paths {
        println!("= {} =", arg);

        let path = Path::new(&arg);

        exit_code += match File::open(&path) {
            Err(_) => {
                println!("!!! Not found");
                1
            }
            Ok(file) => report_errors_for_file(file),
        };
    }

    exit_code
}

fn main() {
    let exit_code = errors_for_args();
    std::process::exit(exit_code);
}
<|endoftext|>


<commit_before>extern crate csv;
use std::io::{self, Write};
use std::f32;
mod common;

fn ask_mileage() -> u32 {

    print!("Enter the mileage you want to estimate: ");
    io::stdout().flush().unwrap();

    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).ok().expect("Failed to read stdin");
    buffer = buffer.split_whitespace().nth(0).expect("Failed to get first word").to_string();
    buffer.parse().ok().expect("Wanted a positive number")
}

pub fn retrieve_thetas(file: &str) -> Option<(f32, f32)> {

    if let Ok(mut rdr) = csv::Reader::from_file(file) {

        if let Ok(ret) = rdr.decode().nth(0).unwrap() {
            return Some(ret);
        }
    }
    None
}

pub fn retrieve_min_max(file: &str) -> Option<(f32, f32)> {

    if let Ok(mut rdr) = csv::Reader::from_file(file) {

        if let Ok(ret) = rdr.decode().nth(0).unwrap() {
            return Some(ret);
        }
    }
    None
}

fn main() {

    let mut thetas_file = common::TMP_FILE_THETAS.to_string();
    if let Some(arg1) = std::env::args().nth(1) {
        thetas_file = arg1;
    }

    // retrieving data
    let (theta0, theta1) = retrieve_thetas(thetas_file.as_ref()).unwrap_or((0_f32, 0_f32));
    let (min, max) = retrieve_min_max(common::TMP_FILE_MIN_MAX).unwrap_or((0_f32, f32::INFINITY));
    let normed_mileage = common::normalize(ask_mileage() as f32, min, max);

    let estimated = common::estimate_price(normed_mileage, theta0, theta1);
    println!("Estimated price is `{}`", estimated);
}
<commit_msg>estimator working with options<commit_after>extern crate csv;
extern crate getopts;

use getopts::Options;
use std::io::{self, Write};
use std::f32;

mod common;

fn ask_mileage() -> u32 {

    print!("Enter the mileage you want to estimate: ");
    io::stdout().flush().unwrap();

    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).ok().expect("Failed to read stdin");
    buffer = buffer.split_whitespace().nth(0).expect("Failed to get first word").to_string();
    buffer.parse().ok().expect("Wanted a positive number")
}

pub fn retrieve_thetas(file: &str) -> Option<(f32, f32)> {

    if let Ok(mut rdr) = csv::Reader::from_file(file) {

        if let Ok(ret) = rdr.decode().nth(0).unwrap() {
            return Some(ret);
        }
    }
    None
}

pub fn retrieve_min_max(file: &str) -> Option<(f32, f32)> {

    if let Ok(mut rdr) = csv::Reader::from_file(file) {

        if let Ok(ret) = rdr.decode().nth(0).unwrap() {
            return Some(ret);
        }
    }
    None
}

fn print_usage(program: &str, opts: Options) {

    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {

    let args: Vec<String> = std::env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optopt("m", "mileage", "set directly the mileage you want to estimate, default `stdin`", "VALUE");
    opts.optopt("", "tmp-file-thetas", format!("set the file where you want to read thetas values, default {}", common::TMP_FILE_THETAS).as_ref(), "FILE");
    opts.optopt("", "tmp-file-min-max", format!("set the file where you want to read min-max values, default {}", common::TMP_FILE_MIN_MAX).as_ref(), "FILE");
    opts.optflag("g", "graph", "display a graph representing the data and the curve found");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let thetas_file = matches.opt_str("tmp-file-thetas").unwrap_or(common::TMP_FILE_THETAS.to_string());
    let min_max_file = matches.opt_str("tmp-file-min-max").unwrap_or(common::TMP_FILE_MIN_MAX.to_string());

    // retrieving data
    let (theta0, theta1) = retrieve_thetas(thetas_file.as_ref()).unwrap_or((0_f32, 0_f32));
    let (min, max) = retrieve_min_max(min_max_file.as_ref()).unwrap_or((0_f32, f32::INFINITY));

    let mileage: f32 = match matches.opt_str("m") {
        Some(value) => value.parse().ok().expect("Option `-m` need a number..."),
        None => ask_mileage() as f32
    };

    let normed_mileage = common::normalize(mileage, min, max);

    let estimated = common::estimate_price(normed_mileage, theta0, theta1);
    println!("Estimated price is `{}`", estimated);
}
<|endoftext|>


<commit_before>use scroll_derive::{Pread, Pwrite, SizeWith, IOread, IOwrite};
use scroll::{Pread, Pwrite, Cread, Cwrite, LE};

use scroll::ctx::SizeWith;

#[derive(Debug, PartialEq, Pread, Pwrite)]
struct Data {
  id: u32,
  timestamp: f64,
}

#[test]
fn test_data (){
    let bytes = [0xefu8, 0xbe, 0xad, 0xde, 0, 0, 0, 0, 0, 0, 224, 63];
    let data: Data = bytes.pread_with(0, LE).unwrap();
    println!("data: {:?}", &data);
    assert_eq!(data.id, 0xdeadbeefu32);
    assert_eq!(data.timestamp, 0.5f64);
    let mut bytes2 = vec![0; ::std::mem::size_of::<Data>()];
    bytes2.pwrite_with(data, 0, LE).unwrap();
    let data: Data = bytes.pread_with(0, LE).unwrap();
    let data2: Data = bytes2.pread_with(0, LE).unwrap();
    assert_eq!(data, data2);
}

#[derive(Debug, PartialEq, Pread, Pwrite)]
struct Data2 {
  name: [u8; 32],
}

#[test]
fn test_array (){
    let bytes = [0u8; 64];
    let data: Data2 = bytes.pread_with(0, LE).unwrap();
    println!("data: {:?}", &data);
}

#[derive(Debug, PartialEq, Pread, Pwrite, SizeWith)]
struct Data3 {
  name: u32,
}

#[test]
fn test_sizewith (){
    let bytes = [0u8; 64];
    let data: Data3 = bytes.gread_with(&mut 0, LE).unwrap();
    println!("data: {:?}", &data);
}

#[derive(Debug, PartialEq, IOread, IOwrite, SizeWith)]
struct Data4 {
    name: u32,
    j: u16,
    arr: [u8; 2]
}

#[test]
fn test_ioread (){
    let bytes = [0, 1, 2, 3, 0xde, 0xed, 0xbe, 0xaf];
    let data: Data4 = bytes.cread_with(0, LE);
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.j, 0xedde);
    assert_eq!(data.arr, [0xbe, 0xaf]);
}

#[test]
fn test_iowrite (){
    let bytes = [0, 1, 2, 3, 0xde, 0xed, 0xbe, 0xaf];
    let data: Data4 = bytes.cread_with(0, LE);
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.j, 0xedde);
    assert_eq!(data.arr, [0xbe, 0xaf]);

    let mut bytes_null = [0u8; 8];
    bytes_null.cwrite_with(&data, 0, LE);
    println!("bytes_null: {:?}", &bytes_null);
    println!("bytes     : {:?}", &bytes);
    assert_eq!(bytes_null, bytes);

    let mut bytes_null = [0u8; 8];
    bytes_null.cwrite_with(data, 0, LE);
    println!("bytes_null: {:?}", &bytes_null);
    println!("bytes     : {:?}", &bytes);
    assert_eq!(bytes_null, bytes);
}

#[derive(Debug, PartialEq, Pread, SizeWith)]
#[repr(C)]
struct Data5 {
    name: u32,
    j: u16,
    arr1: [u8; 2],
    arr2: [u16; 2]
}

#[test]
fn test_pread_arrays (){
    let bytes = [0, 1, 2, 3, 0, 0, 0xde, 0xed, 0xad, 0xde, 0xef, 0xbe];
    let data: Data5 = bytes.pread_with(0, LE).unwrap();
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.arr1, [0xde, 0xed]);
    assert_eq!(data.arr2, [0xdead, 0xbeef]);
    let offset = &mut 0;
    let data: Data5 = bytes.gread_with(offset, LE).unwrap();
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.arr1, [0xde, 0xed]);
    assert_eq!(data.arr2, [0xdead, 0xbeef]);
    assert_eq!(*offset, ::std::mem::size_of::<Data5>());
}

#[derive(Debug, PartialEq, Pread, SizeWith)]
#[repr(C)]
struct Data6 {
    id: u32,
    name: [u8; 5],
}

#[test]
fn test_array_copy (){
    let bytes = [0xde, 0xed, 0xef, 0xbe, 0x68, 0x65, 0x6c, 0x6c, 0x0];
    let data: Data6 = bytes.pread_with(0, LE).unwrap();
    let name: &str = data.name.pread(0).unwrap();
    println!("data: {:?}", &data);
    println!("data.name: {:?}", name);
    assert_eq!(data.id, 0xbeefedde);
    assert_eq!(name, "hell");
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, SizeWith)]
struct Data7A {
    pub y: u64,
    pub x: u32,
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, SizeWith)]
struct Data7B {
    pub a: Data7A,
}

#[test]
fn test_nested_struct() {
    let b = Data7B { a: Data7A { y: 1, x: 2 } };
    let size = Data7B::size_with(&LE);
    assert_eq!(size, 12);
    let mut bytes = vec![0; size];
    let written = bytes.pwrite_with(&b, 0, LE).unwrap();
    assert_eq!(written, size);
    let mut read = 0;
    let b2: Data7B = bytes.gread_with(&mut read, LE).unwrap();
    assert_eq!(read, size);
    assert_eq!(b, b2);
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, IOread, IOwrite, SizeWith)]
#[repr(C)]
struct Data8<T, Y> {
    ids: [T; 3],
    xyz: Y
}

#[test]
fn test_generics() {
    let mut bytes = [0xde, 0xed, 0xef, 0x10, 0x10];
    let data: Data8<u8, u16> = bytes.pread_with(0, LE).unwrap();
    assert_eq!(data.ids, [0xde, 0xed, 0xef]);
    assert_eq!(data.xyz, 0x1010);
    let data: Data8<u8, u16> = bytes.cread_with(0, LE);
    assert_eq!(data.ids, [0xde, 0xed, 0xef]);
    assert_eq!(data.xyz, 0x1010);
    let size = Data8::<u8, u16>::size_with(&LE);
    let written = bytes.pwrite_with(&data, 0, LE).unwrap();
    assert_eq!(written, size);
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, IOread, IOwrite, SizeWith)]
struct Data9(u8, u16);

#[test]
fn test_newtype() {
    let mut bytes = [0xde, 0x10, 0x10];
    let data: Data9 = bytes.pread_with(0, LE).unwrap();
    assert_eq!(data.0, 0xde);
    assert_eq!(data.1, 0x1010);
    let data: Data9 = bytes.cread_with(0, LE);
    assert_eq!(data.0, 0xde);
    assert_eq!(data.1, 0x1010);
    let size = Data9::size_with(&LE);
    let written = bytes.pwrite_with(&data, 0, LE).unwrap();
    assert_eq!(written, size);
}
<commit_msg>scroll_derive: add macro_rules test for 1.47 rustc breakage<commit_after>use scroll::{Cread, Cwrite, Pread, Pwrite, LE};
use scroll_derive::{IOread, IOwrite, Pread, Pwrite, SizeWith};

use scroll::ctx::SizeWith;

macro_rules! test {
    ( struct $name:ident { $( $field:ident: $t:ty, )* } ) => {
        #[derive(Pread)]
        pub struct $name {
            $( pub $field: $t, )*
        }
    };
}

test! {
    struct Test {
        field: [u16; 40],
    }
}

#[derive(Debug, PartialEq, Pread, Pwrite)]
struct Data {
    id: u32,
    timestamp: f64,
}

#[test]
fn test_data() {
    let bytes = [0xefu8, 0xbe, 0xad, 0xde, 0, 0, 0, 0, 0, 0, 224, 63];
    let data: Data = bytes.pread_with(0, LE).unwrap();
    println!("data: {:?}", &data);
    assert_eq!(data.id, 0xdeadbeefu32);
    assert_eq!(data.timestamp, 0.5f64);
    let mut bytes2 = vec![0; ::std::mem::size_of::<Data>()];
    bytes2.pwrite_with(data, 0, LE).unwrap();
    let data: Data = bytes.pread_with(0, LE).unwrap();
    let data2: Data = bytes2.pread_with(0, LE).unwrap();
    assert_eq!(data, data2);
}

#[derive(Debug, PartialEq, Pread, Pwrite)]
struct Data2 {
    name: [u8; 32],
}

#[test]
fn test_array() {
    let bytes = [0u8; 64];
    let data: Data2 = bytes.pread_with(0, LE).unwrap();
    println!("data: {:?}", &data);
}

#[derive(Debug, PartialEq, Pread, Pwrite, SizeWith)]
struct Data3 {
    name: u32,
}

#[test]
fn test_sizewith() {
    let bytes = [0u8; 64];
    let data: Data3 = bytes.gread_with(&mut 0, LE).unwrap();
    println!("data: {:?}", &data);
}

#[derive(Debug, PartialEq, IOread, IOwrite, SizeWith)]
struct Data4 {
    name: u32,
    j: u16,
    arr: [u8; 2],
}

#[test]
fn test_ioread() {
    let bytes = [0, 1, 2, 3, 0xde, 0xed, 0xbe, 0xaf];
    let data: Data4 = bytes.cread_with(0, LE);
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.j, 0xedde);
    assert_eq!(data.arr, [0xbe, 0xaf]);
}

#[test]
fn test_iowrite() {
    let bytes = [0, 1, 2, 3, 0xde, 0xed, 0xbe, 0xaf];
    let data: Data4 = bytes.cread_with(0, LE);
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.j, 0xedde);
    assert_eq!(data.arr, [0xbe, 0xaf]);

    let mut bytes_null = [0u8; 8];
    bytes_null.cwrite_with(&data, 0, LE);
    println!("bytes_null: {:?}", &bytes_null);
    println!("bytes     : {:?}", &bytes);
    assert_eq!(bytes_null, bytes);

    let mut bytes_null = [0u8; 8];
    bytes_null.cwrite_with(data, 0, LE);
    println!("bytes_null: {:?}", &bytes_null);
    println!("bytes     : {:?}", &bytes);
    assert_eq!(bytes_null, bytes);
}

#[derive(Debug, PartialEq, Pread, SizeWith)]
#[repr(C)]
struct Data5 {
    name: u32,
    j: u16,
    arr1: [u8; 2],
    arr2: [u16; 2],
}

#[test]
fn test_pread_arrays() {
    let bytes = [0, 1, 2, 3, 0, 0, 0xde, 0xed, 0xad, 0xde, 0xef, 0xbe];
    let data: Data5 = bytes.pread_with(0, LE).unwrap();
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.arr1, [0xde, 0xed]);
    assert_eq!(data.arr2, [0xdead, 0xbeef]);
    let offset = &mut 0;
    let data: Data5 = bytes.gread_with(offset, LE).unwrap();
    println!("data: {:?}", &data);
    assert_eq!(data.name, 50462976);
    assert_eq!(data.arr1, [0xde, 0xed]);
    assert_eq!(data.arr2, [0xdead, 0xbeef]);
    assert_eq!(*offset, ::std::mem::size_of::<Data5>());
}

#[derive(Debug, PartialEq, Pread, SizeWith)]
#[repr(C)]
struct Data6 {
    id: u32,
    name: [u8; 5],
}

#[test]
fn test_array_copy() {
    let bytes = [0xde, 0xed, 0xef, 0xbe, 0x68, 0x65, 0x6c, 0x6c, 0x0];
    let data: Data6 = bytes.pread_with(0, LE).unwrap();
    let name: &str = data.name.pread(0).unwrap();
    println!("data: {:?}", &data);
    println!("data.name: {:?}", name);
    assert_eq!(data.id, 0xbeefedde);
    assert_eq!(name, "hell");
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, SizeWith)]
struct Data7A {
    pub y: u64,
    pub x: u32,
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, SizeWith)]
struct Data7B {
    pub a: Data7A,
}

#[test]
fn test_nested_struct() {
    let b = Data7B {
        a: Data7A { y: 1, x: 2 },
    };
    let size = Data7B::size_with(&LE);
    assert_eq!(size, 12);
    let mut bytes = vec![0; size];
    let written = bytes.pwrite_with(&b, 0, LE).unwrap();
    assert_eq!(written, size);
    let mut read = 0;
    let b2: Data7B = bytes.gread_with(&mut read, LE).unwrap();
    assert_eq!(read, size);
    assert_eq!(b, b2);
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, IOread, IOwrite, SizeWith)]
#[repr(C)]
struct Data8<T, Y> {
    ids: [T; 3],
    xyz: Y,
}

#[test]
fn test_generics() {
    let mut bytes = [0xde, 0xed, 0xef, 0x10, 0x10];
    let data: Data8<u8, u16> = bytes.pread_with(0, LE).unwrap();
    assert_eq!(data.ids, [0xde, 0xed, 0xef]);
    assert_eq!(data.xyz, 0x1010);
    let data: Data8<u8, u16> = bytes.cread_with(0, LE);
    assert_eq!(data.ids, [0xde, 0xed, 0xef]);
    assert_eq!(data.xyz, 0x1010);
    let size = Data8::<u8, u16>::size_with(&LE);
    let written = bytes.pwrite_with(&data, 0, LE).unwrap();
    assert_eq!(written, size);
}

#[derive(Debug, PartialEq, Eq, Pread, Pwrite, IOread, IOwrite, SizeWith)]
struct Data9(u8, u16);

#[test]
fn test_newtype() {
    let mut bytes = [0xde, 0x10, 0x10];
    let data: Data9 = bytes.pread_with(0, LE).unwrap();
    assert_eq!(data.0, 0xde);
    assert_eq!(data.1, 0x1010);
    let data: Data9 = bytes.cread_with(0, LE);
    assert_eq!(data.0, 0xde);
    assert_eq!(data.1, 0x1010);
    let size = Data9::size_with(&LE);
    let written = bytes.pwrite_with(&data, 0, LE).unwrap();
    assert_eq!(written, size);
}
<|endoftext|>


<commit_before>use super::*;
use Allocator;

use core::ptr;

extern "C" {
    /// We need this to allocate aligned memory for our heap.
    fn memalign(alignment: usize, size: usize) -> *mut u8;

    // Release our memory.
    fn free(ptr: *mut u8);
}

const HEAP_ALIGN: usize = 4096;
const HEAP_SIZE: usize = 256;

#[test]
fn test_allocation_size_and_order() {
    unsafe {
        let mem = memalign(HEAP_ALIGN, HEAP_SIZE);
        let mut free_lists: [FreeList; 5]
            = [ FreeList::new(), FreeList::new()
              , FreeList::new(), FreeList::new()
              , FreeList::new()
              ];
        let heap = BuddyHeapAllocator::new( mem
                                          , &mut free_lists
                                          , HEAP_SIZE );

        // TEST NEEDED: Can't align beyond MIN_HEAP_ALIGN.

        // Can't align beyond heap_size.
        assert_eq!(None, heap.alloc_size(256, 256*2));

        // Simple allocations just round up to next block size.
        assert_eq!(Some(16), heap.alloc_size(0, 1));
        assert_eq!(Some(16), heap.alloc_size(1, 1));
        assert_eq!(Some(16), heap.alloc_size(16, 1));
        assert_eq!(Some(32), heap.alloc_size(17, 1));
        assert_eq!(Some(32), heap.alloc_size(32, 32));
        assert_eq!(Some(256), heap.alloc_size(256, 256));

        // Aligned allocations use alignment as block size.
        assert_eq!(Some(64), heap.alloc_size(16, 64));

        // Block orders.
        assert_eq!(Some(0), heap.alloc_order(0, 1));
        assert_eq!(Some(0), heap.alloc_order(1, 1));
        assert_eq!(Some(0), heap.alloc_order(16, 16));
        assert_eq!(Some(1), heap.alloc_order(32, 32));
        assert_eq!(Some(2), heap.alloc_order(64, 64));
        assert_eq!(Some(3), heap.alloc_order(128, 128));
        assert_eq!(Some(4), heap.alloc_order(256, 256));
        assert_eq!(None, heap.alloc_order(512, 512));

        free(mem);
    }
}

#[test]
fn test_get_buddy() {
    unsafe {
        let mem = memalign(HEAP_ALIGN, HEAP_SIZE);
        let mut free_lists: [FreeList; 5]
            = [ FreeList::new(), FreeList::new()
              , FreeList::new(), FreeList::new()
              , FreeList::new()
              ];
        let heap = BuddyHeapAllocator::new( mem
                                          , &mut free_lists
                                          , HEAP_SIZE );
        let block_16_0 = mem;
        let block_16_1 = mem.offset(16);
        assert_eq!(Some(block_16_1), heap.get_buddy(0, block_16_0));
        assert_eq!(Some(block_16_0), heap.get_buddy(0, block_16_1));

        let block_32_0 = mem;
        let block_32_1 = mem.offset(32);
        assert_eq!(Some(block_32_1), heap.get_buddy(1, block_32_0));
        assert_eq!(Some(block_32_0), heap.get_buddy(1, block_32_1));

        let block_32_2 = mem.offset(64);
        let block_32_3 = mem.offset(96);
        assert_eq!(Some(block_32_3), heap.get_buddy(1, block_32_2));
        assert_eq!(Some(block_32_2), heap.get_buddy(1, block_32_3));

        let block_256_0 = mem;
        assert_eq!(None, heap.get_buddy(4, block_256_0));

        free(mem);
    }
}

#[test]
fn test_alloc_and_dealloc() {
    unsafe {
        let mem = memalign(HEAP_ALIGN, HEAP_SIZE);
        let mut free_lists: [FreeList; 5]
            = [ FreeList::new(), FreeList::new()
              , FreeList::new(), FreeList::new()
              , FreeList::new()
              ];
        let mut heap = BuddyHeapAllocator::new( mem
                                              , &mut free_lists
                                              , HEAP_SIZE );

        let block_128_0 = heap.allocate(128, 128);
        assert_eq!(Some(mem.offset(0)), block_128_0);

        heap.deallocate(block_128_0.unwrap(), 128,128);

        let block_16_0 = heap.allocate(8, 8);
        assert_eq!(Some(mem), block_16_0);

        let bigger_than_heap = heap.allocate(4096, HEAP_SIZE);
        assert_eq!(None, bigger_than_heap);

        let bigger_than_free = heap.allocate(HEAP_SIZE, HEAP_SIZE);
        assert_eq!(None, bigger_than_free);

        let block_16_1 = heap.allocate(8, 8);
        assert_eq!(Some(mem.offset(16)), block_16_1);

        let block_16_2 = heap.allocate(8, 8);
        assert_eq!(Some(mem.offset(32)), block_16_2);

        let block_32_2 = heap.allocate(32, 32);
        assert_eq!(Some(mem.offset(64)), block_32_2);

        let block_16_3 = heap.allocate(8, 8);
        assert_eq!(Some(mem.offset(48)), block_16_3);

        // let too_fragmented = heap.allocate(64, 64);
        // assert_eq!(None, too_fragmented);
        heap.deallocate(block_16_0.unwrap(), 8, 8);
        heap.deallocate(block_16_3.unwrap(), 8, 8);
        heap.deallocate(block_16_1.unwrap(), 8, 8);
        heap.deallocate(block_16_2.unwrap(), 8, 8);

        heap.deallocate(block_32_2.unwrap(), 32, 32);

        let block_128_0 = heap.allocate(128, 128);
        assert_eq!(Some(mem.offset(0)), block_128_0);

        let block_128_1 = heap.allocate(128, 128);
        assert_eq!(Some(mem.offset(128)), block_128_1);

        heap.deallocate(block_128_1.unwrap(), 128, 128);
        heap.deallocate(block_128_0.unwrap(), 128, 128);

        // And allocate the whole heap, just to make sure everything
        // got cleaned up correctly.
        let block_256_0 = heap.allocate(256, 256).unwrap();
        assert_eq!(mem.offset(0), block_256_0);

        free(mem);
    }
}
<commit_msg>[alloc] fix issue with tests that crashed on CI<commit_after>use super::*;
use memory::alloc::Allocator;

use core::ptr;

extern "C" {
    /// We need this to allocate aligned memory for our heap.
    fn memalign(alignment: usize, size: usize) -> *mut u8;

    // Release our memory.
    fn free(ptr: *mut u8);
}

const HEAP_ALIGN: usize = 4096;
const HEAP_SIZE: usize = 256;

#[test]
fn test_allocation_size_and_order() {
    unsafe {
        let mem = memalign(HEAP_ALIGN, HEAP_SIZE);
        let mut free_lists: [FreeList; 5]
            = [ FreeList::new(), FreeList::new()
              , FreeList::new(), FreeList::new()
              , FreeList::new()
              ];
        let heap = BuddyHeapAllocator::new( mem
                                          , &mut free_lists
                                          , HEAP_SIZE );

        // TEST NEEDED: Can't align beyond MIN_HEAP_ALIGN.

        // Can't align beyond heap_size.
        assert_eq!(None, heap.alloc_size(256, 256*2));

        // Simple allocations just round up to next block size.
        assert_eq!(Some(16), heap.alloc_size(0, 1));
        assert_eq!(Some(16), heap.alloc_size(1, 1));
        assert_eq!(Some(16), heap.alloc_size(16, 1));
        assert_eq!(Some(32), heap.alloc_size(17, 1));
        assert_eq!(Some(32), heap.alloc_size(32, 32));
        assert_eq!(Some(256), heap.alloc_size(256, 256));

        // Aligned allocations use alignment as block size.
        assert_eq!(Some(64), heap.alloc_size(16, 64));

        // Block orders.
        assert_eq!(Some(0), heap.alloc_order(0, 1));
        assert_eq!(Some(0), heap.alloc_order(1, 1));
        assert_eq!(Some(0), heap.alloc_order(16, 16));
        assert_eq!(Some(1), heap.alloc_order(32, 32));
        assert_eq!(Some(2), heap.alloc_order(64, 64));
        assert_eq!(Some(3), heap.alloc_order(128, 128));
        assert_eq!(Some(4), heap.alloc_order(256, 256));
        assert_eq!(None, heap.alloc_order(512, 512));

        free(mem);
    }
}

#[test]
fn test_get_buddy() {
    unsafe {
        let mem = memalign(HEAP_ALIGN, HEAP_SIZE);
        let mut free_lists: [FreeList; 5]
            = [ FreeList::new(), FreeList::new()
              , FreeList::new(), FreeList::new()
              , FreeList::new()
              ];
        let heap = BuddyHeapAllocator::new( mem
                                          , &mut free_lists
                                          , HEAP_SIZE );
        let block_16_0 = mem;
        let block_16_1 = mem.offset(16);
        assert_eq!(Some(block_16_1), heap.get_buddy(0, block_16_0));
        assert_eq!(Some(block_16_0), heap.get_buddy(0, block_16_1));

        let block_32_0 = mem;
        let block_32_1 = mem.offset(32);
        assert_eq!(Some(block_32_1), heap.get_buddy(1, block_32_0));
        assert_eq!(Some(block_32_0), heap.get_buddy(1, block_32_1));

        let block_32_2 = mem.offset(64);
        let block_32_3 = mem.offset(96);
        assert_eq!(Some(block_32_3), heap.get_buddy(1, block_32_2));
        assert_eq!(Some(block_32_2), heap.get_buddy(1, block_32_3));

        let block_256_0 = mem;
        assert_eq!(None, heap.get_buddy(4, block_256_0));

        free(mem);
    }
}

#[test]
fn test_alloc_and_dealloc() {
    unsafe {
        let mem = memalign(HEAP_ALIGN, HEAP_SIZE);
        let mut free_lists: [FreeList; 5]
            = [ FreeList::new(), FreeList::new()
              , FreeList::new(), FreeList::new()
              , FreeList::new()
              ];
        let mut heap = BuddyHeapAllocator::new( mem
                                              , &mut free_lists
                                              , HEAP_SIZE );

        let block_128_0 = heap.allocate(128, 128);
        assert_eq!(Some(mem.offset(0)), block_128_0);

        heap.deallocate(block_128_0.unwrap(), 128,128);

        let block_16_0 = heap.allocate(8, 8);
        assert_eq!(Some(mem), block_16_0);

        let bigger_than_heap = heap.allocate(4096, HEAP_SIZE);
        assert_eq!(None, bigger_than_heap);

        let bigger_than_free = heap.allocate(HEAP_SIZE, HEAP_SIZE);
        assert_eq!(None, bigger_than_free);

        let block_16_1 = heap.allocate(8, 8);
        assert_eq!(Some(mem.offset(16)), block_16_1);

        let block_16_2 = heap.allocate(8, 8);
        assert_eq!(Some(mem.offset(32)), block_16_2);

        let block_32_2 = heap.allocate(32, 32);
        assert_eq!(Some(mem.offset(64)), block_32_2);

        let block_16_3 = heap.allocate(8, 8);
        assert_eq!(Some(mem.offset(48)), block_16_3);

        // let too_fragmented = heap.allocate(64, 64);
        // assert_eq!(None, too_fragmented);
        heap.deallocate(block_16_0.unwrap(), 8, 8);
        heap.deallocate(block_16_3.unwrap(), 8, 8);
        heap.deallocate(block_16_1.unwrap(), 8, 8);
        heap.deallocate(block_16_2.unwrap(), 8, 8);

        heap.deallocate(block_32_2.unwrap(), 32, 32);

        let block_128_0 = heap.allocate(128, 128);
        assert_eq!(Some(mem.offset(0)), block_128_0);

        let block_128_1 = heap.allocate(128, 128);
        assert_eq!(Some(mem.offset(128)), block_128_1);

        heap.deallocate(block_128_1.unwrap(), 128, 128);
        heap.deallocate(block_128_0.unwrap(), 128, 128);

        // And allocate the whole heap, just to make sure everything
        // got cleaned up correctly.
        let block_256_0 = heap.allocate(256, 256).unwrap();
        assert_eq!(mem.offset(0), block_256_0);

        free(mem);
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate syntect;
use test::Bencher;

use syntect::parsing::SyntaxSet;
use syntect::highlighting::ThemeSet;
use syntect::easy::HighlightLines;
use std::fs::File;
use std::io::Read;

fn highlight_file(b: &mut Bencher, path_s: &str) {
    // don't load from dump so we don't count lazy regex compilation time
    let ps = SyntaxSet::load_defaults_nonewlines();
    let ts = ThemeSet::load_defaults();

    let syntax = ps.find_syntax_for_file(path_s).unwrap().unwrap();
    let mut f = File::open(path_s).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s).unwrap();

    let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]);
    b.iter(|| {
        for line in s.lines() {
            let regions = h.highlight(line);
            test::black_box(&regions);
        }
    });
}

#[bench]
fn bench_highlighting_nesting(b: &mut Bencher) {
    highlight_file(b, "testdata/highlight_test.erb");
}

#[bench]
fn bench_highlighting_xml(b: &mut Bencher) {
    highlight_file(b, "testdata/InspiredGitHub.tmtheme/InspiredGitHub.tmTheme");
}

#[bench]
fn bench_highlighting_jquery(b: &mut Bencher) {
    highlight_file(b, "testdata/jquery.js");
}

#[bench]
fn bench_highlighting_rustc(b: &mut Bencher) {
    highlight_file(b, "testdata/parser.rs");
}
<commit_msg>Add benchmark for highlighting YAML.<commit_after>#![feature(test)]

extern crate test;
extern crate syntect;
use test::Bencher;

use syntect::parsing::SyntaxSet;
use syntect::highlighting::ThemeSet;
use syntect::easy::HighlightLines;
use std::fs::File;
use std::io::Read;

fn highlight_file(b: &mut Bencher, path_s: &str) {
    // don't load from dump so we don't count lazy regex compilation time
    let ps = SyntaxSet::load_defaults_nonewlines();
    let ts = ThemeSet::load_defaults();

    let syntax = ps.find_syntax_for_file(path_s).unwrap().unwrap();
    let mut f = File::open(path_s).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s).unwrap();

    let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]);
    b.iter(|| {
        for line in s.lines() {
            let regions = h.highlight(line);
            test::black_box(&regions);
        }
    });
}

#[bench]
fn bench_highlighting_nesting(b: &mut Bencher) {
    highlight_file(b, "testdata/highlight_test.erb");
}

#[bench]
fn bench_highlighting_xml(b: &mut Bencher) {
    highlight_file(b, "testdata/InspiredGitHub.tmtheme/InspiredGitHub.tmTheme");
}

#[bench]
fn bench_highlighting_yaml(b: &mut Bencher) {
    highlight_file(b, "testdata/Packages/Ruby/Ruby.sublime-syntax");
}

#[bench]
fn bench_highlighting_jquery(b: &mut Bencher) {
    highlight_file(b, "testdata/jquery.js");
}

#[bench]
fn bench_highlighting_rustc(b: &mut Bencher) {
    highlight_file(b, "testdata/parser.rs");
}
<|endoftext|>


<commit_before>extern mod std;

#[path="./common/mod.rs"]
mod common;

#[path="./prob0001_0050/mod.rs"]
mod prob0001_0050;
#[path="./prob0051_0100/mod.rs"]
mod prob0051_0100;

priv use common::problem::{ Problem };

priv static problem_sets: &'static [&'static [&'static Problem<'static>]] = &[
    prob0001_0050::problems,
    prob0051_0100::problems
];

priv fn each_problems(f: &fn(&Problem) -> bool) {
    for problem_sets.each_val |ps| {
        for ps.each_val |p| {
            if !f(p) { return; }
        }
    }
}

priv fn solve(p: &Problem) {
    io::println(fmt!("Problem #%u: %s", p.id, p.answer));
    assert_eq!((p.solver)(), p.answer.to_str());
}

fn main() {
    let nums = os::args().filter_mapped(|&s| uint::from_str(s));
    if nums.is_empty() {
        for each_problems |p| { solve(p); }
    } else {
        for nums.each_val |n| {
            for each_problems |p| {
                if p.id == n { solve(p); }
            }
        }
    }
}
<commit_msg>Show computation time<commit_after>extern mod std;

#[path="./common/mod.rs"]
mod common;

#[path="./prob0001_0050/mod.rs"]
mod prob0001_0050;
#[path="./prob0051_0100/mod.rs"]
mod prob0051_0100;

priv use std::time::{ precise_time_ns };

priv use common::problem::{ Problem };

priv static problem_sets: &'static [&'static [&'static Problem<'static>]] = &[
    prob0001_0050::problems,
    prob0051_0100::problems
];

priv fn each_problems(f: &fn(&Problem) -> bool) {
    for problem_sets.each_val |ps| {
        for ps.each_val |p| {
            if !f(p) { return; }
        }
    }
}

priv static NSEC_PER_SEC: u64 = 1000000000;
priv fn nanosec_to_str(nsec: u64) -> ~str {
    return fmt!("%3u.%09u",
         (nsec / NSEC_PER_SEC) as uint,
         (nsec % NSEC_PER_SEC) as uint);
}

priv fn solve(p: &Problem) -> u64 {
    let start_time = precise_time_ns();
    let comp_answer = (p.solver)();
    let calc_time   = precise_time_ns() - start_time;

    assert_eq!(comp_answer, p.answer.to_str());

    io::println(fmt!("%-5u %-12s %s",
                     p.id, p.answer, nanosec_to_str(calc_time)));

    return calc_time;
}

fn main() {
    let nums = os::args().filter_mapped(|&s| uint::from_str(s));

    let mut total_time = 0;
    let mut solve_cnt = 0;
    if nums.is_empty() {
        for each_problems |p| {
            total_time += solve(p);
            solve_cnt += 1;
        }
    } else {
        for nums.each_val |n| {
            for each_problems |p| {
                if p.id == n {
                    total_time += solve(p);
                    solve_cnt += 1;
                }
            }
        }
    }

    if solve_cnt > 1 {
        io::println(fmt!("TOTAL %-12s %s", "", nanosec_to_str(total_time)));
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;

use smithay::{
    reexports::wayland_server::protocol::wl_surface,
    utils::Rectangle,
    wayland::{
        compositor::{roles::Role, CompositorToken, SubsurfaceRole, SurfaceAttributes, TraversalAction},
        shell::{
            legacy::{ShellSurface, ShellSurfaceRole},
            xdg::{ToplevelSurface, XdgSurfaceRole},
        },
    },
};

pub enum Kind<R> {
    Xdg(ToplevelSurface<R>),
    Wl(ShellSurface<R>),
}

impl<R> Kind<R>
where
    R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
    pub fn alive(&self) -> bool {
        match *self {
            Kind::Xdg(ref t) => t.alive(),
            Kind::Wl(ref t) => t.alive(),
        }
    }
    pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> {
        match *self {
            Kind::Xdg(ref t) => t.get_surface(),
            Kind::Wl(ref t) => t.get_surface(),
        }
    }

    /// Do this handle and the other one actually refer to the same toplevel surface?
    pub fn equals(&self, other: &Self) -> bool {
        match (self, other) {
            (Kind::Xdg(a), Kind::Xdg(b)) => a.equals(b),
            (Kind::Wl(a), Kind::Wl(b)) => a.equals(b),
            _ => false,
        }
    }
}

struct Window<R> {
    location: (i32, i32),
    /// A bounding box over the input areas of this window and its children.
    ///
    /// Used for the fast path of the check in `matching`.
    input_bbox: Rectangle,
    toplevel: Kind<R>,
}

impl<R> Window<R>
where
    R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
    /// Finds the topmost surface under this point if any and returns it together with the location of this
    /// surface.
    ///
    /// You need to provide a `contains_point` function which checks if the point (in surface-local
    /// coordinates) is within the input region of the given `SurfaceAttributes`.
    fn matching<F>(
        &self,
        point: (f64, f64),
        ctoken: CompositorToken<R>,
        contains_point: F,
    ) -> Option<(wl_surface::WlSurface, (f64, f64))>
    where
        F: Fn(&SurfaceAttributes, (f64, f64)) -> bool,
    {
        if !self.input_bbox.contains((point.0 as i32, point.1 as i32)) {
            return None;
        }
        // need to check more carefully
        let found = RefCell::new(None);
        if let Some(wl_surface) = self.toplevel.get_surface() {
            ctoken.with_surface_tree_downward(
                wl_surface,
                self.location,
                |wl_surface, attributes, role, &(mut x, mut y)| {
                    if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
                        x += subdata.location.0;
                        y += subdata.location.1;
                    }

                    let surface_local_point = (point.0 - x as f64, point.1 - y as f64);
                    if contains_point(attributes, surface_local_point) {
                        *found.borrow_mut() = Some((wl_surface.clone(), (x as f64, y as f64)));
                    }

                    TraversalAction::DoChildren((x, y))
                },
                |_, _, _, _| {},
                |_, _, _, _| {
                    // only continue if the point is not found
                    found.borrow().is_none()
                },
            );
        }
        found.into_inner()
    }

    fn self_update<F>(&mut self, ctoken: CompositorToken<R>, get_size: F)
    where
        F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
    {
        let (base_x, base_y) = self.location;
        let (mut min_x, mut min_y, mut max_x, mut max_y) = (base_x, base_y, base_x, base_y);
        if let Some(wl_surface) = self.toplevel.get_surface() {
            ctoken.with_surface_tree_downward(
                wl_surface,
                (base_x, base_y),
                |_, attributes, role, &(mut x, mut y)| {
                    // The input region is intersected with the surface size, so the surface size
                    // can serve as an approximation for the input bounding box.
                    if let Some((w, h)) = get_size(attributes) {
                        if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
                            x += subdata.location.0;
                            y += subdata.location.1;
                        }
                        // update the bounding box
                        if x < min_x {
                            min_x = x;
                        }
                        if y < min_y {
                            min_y = y;
                        }
                        if x + w > max_x {
                            max_x = x + w;
                        }
                        if y + h > max_y {
                            max_y = y + w;
                        }
                        TraversalAction::DoChildren((x, y))
                    } else {
                        TraversalAction::SkipChildren
                    }
                },
                |_, _, _, _| {},
                |_, _, _, _| true,
            );
        }
        self.input_bbox = Rectangle {
            x: min_x,
            y: min_y,
            width: max_x - min_x,
            height: max_y - min_y,
        };
    }
}

pub struct WindowMap<R, F, G> {
    ctoken: CompositorToken<R>,
    windows: Vec<Window<R>>,
    /// A function returning the surface size.
    get_size: F,
    /// A function that checks if the point is in the surface's input region.
    contains_point: G,
}

impl<R, F, G> WindowMap<R, F, G>
where
    F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
    G: Fn(&SurfaceAttributes, (f64, f64)) -> bool,
    R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
    pub fn new(ctoken: CompositorToken<R>, get_size: F, contains_point: G) -> Self {
        WindowMap {
            ctoken,
            windows: Vec::new(),
            get_size,
            contains_point,
        }
    }

    pub fn insert(&mut self, toplevel: Kind<R>, location: (i32, i32)) {
        let mut window = Window {
            location,
            input_bbox: Rectangle::default(),
            toplevel,
        };
        window.self_update(self.ctoken, &self.get_size);
        self.windows.insert(0, window);
    }

    pub fn get_surface_under(&self, point: (f64, f64)) -> Option<(wl_surface::WlSurface, (f64, f64))> {
        for w in &self.windows {
            if let Some(surface) = w.matching(point, self.ctoken, &self.contains_point) {
                return Some(surface);
            }
        }
        None
    }

    pub fn get_surface_and_bring_to_top(
        &mut self,
        point: (f64, f64),
    ) -> Option<(wl_surface::WlSurface, (f64, f64))> {
        let mut found = None;
        for (i, w) in self.windows.iter().enumerate() {
            if let Some(surface) = w.matching(point, self.ctoken, &self.contains_point) {
                found = Some((i, surface));
                break;
            }
        }
        if let Some((i, surface)) = found {
            let winner = self.windows.remove(i);
            self.windows.insert(0, winner);
            Some(surface)
        } else {
            None
        }
    }

    pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
    where
        Func: FnMut(&Kind<R>, (i32, i32)),
    {
        for w in self.windows.iter().rev() {
            f(&w.toplevel, w.location)
        }
    }

    pub fn refresh(&mut self) {
        self.windows.retain(|w| w.toplevel.alive());
        for w in &mut self.windows {
            w.self_update(self.ctoken, &self.get_size);
        }
    }

    pub fn clear(&mut self) {
        self.windows.clear();
    }

    /// Returns the location of the toplevel, if it exists.
    pub fn location(&self, toplevel: &Kind<R>) -> Option<(i32, i32)> {
        self.windows
            .iter()
            .find(|w| w.toplevel.equals(toplevel))
            .map(|w| w.location)
    }
}
<commit_msg>anvil.window_map: add WindowMap::set_location<commit_after>use std::cell::RefCell;

use smithay::{
    reexports::wayland_server::protocol::wl_surface,
    utils::Rectangle,
    wayland::{
        compositor::{roles::Role, CompositorToken, SubsurfaceRole, SurfaceAttributes, TraversalAction},
        shell::{
            legacy::{ShellSurface, ShellSurfaceRole},
            xdg::{ToplevelSurface, XdgSurfaceRole},
        },
    },
};

pub enum Kind<R> {
    Xdg(ToplevelSurface<R>),
    Wl(ShellSurface<R>),
}

impl<R> Kind<R>
where
    R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
    pub fn alive(&self) -> bool {
        match *self {
            Kind::Xdg(ref t) => t.alive(),
            Kind::Wl(ref t) => t.alive(),
        }
    }
    pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> {
        match *self {
            Kind::Xdg(ref t) => t.get_surface(),
            Kind::Wl(ref t) => t.get_surface(),
        }
    }

    /// Do this handle and the other one actually refer to the same toplevel surface?
    pub fn equals(&self, other: &Self) -> bool {
        match (self, other) {
            (Kind::Xdg(a), Kind::Xdg(b)) => a.equals(b),
            (Kind::Wl(a), Kind::Wl(b)) => a.equals(b),
            _ => false,
        }
    }
}

struct Window<R> {
    location: (i32, i32),
    /// A bounding box over the input areas of this window and its children.
    ///
    /// Used for the fast path of the check in `matching`.
    input_bbox: Rectangle,
    toplevel: Kind<R>,
}

impl<R> Window<R>
where
    R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
    /// Finds the topmost surface under this point if any and returns it together with the location of this
    /// surface.
    ///
    /// You need to provide a `contains_point` function which checks if the point (in surface-local
    /// coordinates) is within the input region of the given `SurfaceAttributes`.
    fn matching<F>(
        &self,
        point: (f64, f64),
        ctoken: CompositorToken<R>,
        contains_point: F,
    ) -> Option<(wl_surface::WlSurface, (f64, f64))>
    where
        F: Fn(&SurfaceAttributes, (f64, f64)) -> bool,
    {
        if !self.input_bbox.contains((point.0 as i32, point.1 as i32)) {
            return None;
        }
        // need to check more carefully
        let found = RefCell::new(None);
        if let Some(wl_surface) = self.toplevel.get_surface() {
            ctoken.with_surface_tree_downward(
                wl_surface,
                self.location,
                |wl_surface, attributes, role, &(mut x, mut y)| {
                    if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
                        x += subdata.location.0;
                        y += subdata.location.1;
                    }

                    let surface_local_point = (point.0 - x as f64, point.1 - y as f64);
                    if contains_point(attributes, surface_local_point) {
                        *found.borrow_mut() = Some((wl_surface.clone(), (x as f64, y as f64)));
                    }

                    TraversalAction::DoChildren((x, y))
                },
                |_, _, _, _| {},
                |_, _, _, _| {
                    // only continue if the point is not found
                    found.borrow().is_none()
                },
            );
        }
        found.into_inner()
    }

    fn self_update<F>(&mut self, ctoken: CompositorToken<R>, get_size: F)
    where
        F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
    {
        let (base_x, base_y) = self.location;
        let (mut min_x, mut min_y, mut max_x, mut max_y) = (base_x, base_y, base_x, base_y);
        if let Some(wl_surface) = self.toplevel.get_surface() {
            ctoken.with_surface_tree_downward(
                wl_surface,
                (base_x, base_y),
                |_, attributes, role, &(mut x, mut y)| {
                    // The input region is intersected with the surface size, so the surface size
                    // can serve as an approximation for the input bounding box.
                    if let Some((w, h)) = get_size(attributes) {
                        if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
                            x += subdata.location.0;
                            y += subdata.location.1;
                        }
                        // update the bounding box
                        if x < min_x {
                            min_x = x;
                        }
                        if y < min_y {
                            min_y = y;
                        }
                        if x + w > max_x {
                            max_x = x + w;
                        }
                        if y + h > max_y {
                            max_y = y + w;
                        }
                        TraversalAction::DoChildren((x, y))
                    } else {
                        TraversalAction::SkipChildren
                    }
                },
                |_, _, _, _| {},
                |_, _, _, _| true,
            );
        }
        self.input_bbox = Rectangle {
            x: min_x,
            y: min_y,
            width: max_x - min_x,
            height: max_y - min_y,
        };
    }
}

pub struct WindowMap<R, F, G> {
    ctoken: CompositorToken<R>,
    windows: Vec<Window<R>>,
    /// A function returning the surface size.
    get_size: F,
    /// A function that checks if the point is in the surface's input region.
    contains_point: G,
}

impl<R, F, G> WindowMap<R, F, G>
where
    F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
    G: Fn(&SurfaceAttributes, (f64, f64)) -> bool,
    R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole> + 'static,
{
    pub fn new(ctoken: CompositorToken<R>, get_size: F, contains_point: G) -> Self {
        WindowMap {
            ctoken,
            windows: Vec::new(),
            get_size,
            contains_point,
        }
    }

    pub fn insert(&mut self, toplevel: Kind<R>, location: (i32, i32)) {
        let mut window = Window {
            location,
            input_bbox: Rectangle::default(),
            toplevel,
        };
        window.self_update(self.ctoken, &self.get_size);
        self.windows.insert(0, window);
    }

    pub fn get_surface_under(&self, point: (f64, f64)) -> Option<(wl_surface::WlSurface, (f64, f64))> {
        for w in &self.windows {
            if let Some(surface) = w.matching(point, self.ctoken, &self.contains_point) {
                return Some(surface);
            }
        }
        None
    }

    pub fn get_surface_and_bring_to_top(
        &mut self,
        point: (f64, f64),
    ) -> Option<(wl_surface::WlSurface, (f64, f64))> {
        let mut found = None;
        for (i, w) in self.windows.iter().enumerate() {
            if let Some(surface) = w.matching(point, self.ctoken, &self.contains_point) {
                found = Some((i, surface));
                break;
            }
        }
        if let Some((i, surface)) = found {
            let winner = self.windows.remove(i);
            self.windows.insert(0, winner);
            Some(surface)
        } else {
            None
        }
    }

    pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
    where
        Func: FnMut(&Kind<R>, (i32, i32)),
    {
        for w in self.windows.iter().rev() {
            f(&w.toplevel, w.location)
        }
    }

    pub fn refresh(&mut self) {
        self.windows.retain(|w| w.toplevel.alive());
        for w in &mut self.windows {
            w.self_update(self.ctoken, &self.get_size);
        }
    }

    pub fn clear(&mut self) {
        self.windows.clear();
    }

    /// Returns the location of the toplevel, if it exists.
    pub fn location(&self, toplevel: &Kind<R>) -> Option<(i32, i32)> {
        self.windows
            .iter()
            .find(|w| w.toplevel.equals(toplevel))
            .map(|w| w.location)
    }

    /// Sets the location of the toplevel, if it exists.
    pub fn set_location(&mut self, toplevel: &Kind<R>, location: (i32, i32)) {
        if let Some(w) = self.windows.iter_mut().find(|w| w.toplevel.equals(toplevel)) {
            w.location = location;
            w.self_update(self.ctoken, &self.get_size);
        }
    }
}
<|endoftext|>