<commit_before>use futures::future;
use futures::Future;
use hyper::Uri;
use hyper::client::{Client, Request};
use hyper::Method::Post;
use mktemp::Temp;
use slog;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
use tokio_core::reactor::{Handle, Remote};
use tokio_process::CommandExt;
use tera::Tera;

use http_client;
use papers::DocumentSpec;
use error::{Error, ErrorKind};

pub struct Workspace {
    dir: Temp,
    document_spec: DocumentSpec,
    handle: Handle,
    template_path: ::std::path::PathBuf,
    logger: slog::Logger,
}

/// We ignore file names that end with a slash for now, and always determine the file name from the Uri
/// TODO: investigate Content-Disposition: attachment
fn extract_file_name_from_uri(uri: &Uri) -> Option<String> {
    match uri.path().split('/').last() {
        Some(name) => {
            if !name.is_empty() {
                Some(name.to_string())
            } else {
                None
            }
        },
        None => None,
    }
}

/// Since `mktemp::Temp` implements Drop by deleting the directory, we don't need to worry about
/// leaving files or directories behind. On the flipside, we must ensure it is not dropped before
/// the last returned future that needs the directory finishes.
impl Workspace {

    pub fn new(remote: Remote, document_spec: DocumentSpec, logger: slog::Logger) -> Result<Workspace, Error> {
        let dir = Temp::new_dir()?;
        let mut template_path = dir.to_path_buf();
        template_path.push(Path::new("out.tex"));
        Ok(Workspace {
            document_spec: document_spec,
            handle: remote.handle().unwrap(),
            template_path: template_path,
            dir: dir,
            logger: logger,
        })
    }

    pub fn preview(self) -> Box<Future<Item=String, Error=Error>> {
        let Workspace {
            handle,
            document_spec,
            ..
        } = self;

        let DocumentSpec {
            template_url,
            variables,
            ..
        } = document_spec;

        // Download the template and populate it
        let work = http_client::download_file(&handle.clone(), template_url.0)
            .and_then(|bytes| {
                future::result(::std::string::String::from_utf8(bytes))
                    .map_err(Error::from)
            }).and_then(move |template_string| {
                Tera::one_off(&template_string, &variables, false)
                    .map_err(Error::from)
            });

        Box::new(work)
    }

    pub fn execute(self) -> Box<Future<Item=(), Error=Error>> {
        // debug!("Starting Workspace worker");

        let Workspace {
            handle,
            document_spec,
            template_path,
            dir,
            logger,
        } = self;

        let DocumentSpec {
            assets_urls,
            callback_url,
            template_url,
            variables,
        } = document_spec;

        let out_tex_path = dir.to_path_buf();
        let out_pdf_path = dir.to_path_buf();

        // First download the template and populate it
        let work = http_client::download_file(&handle.clone(), template_url.0)
                .and_then(|bytes| {
                    // debug!("Successfully downloaded template");
                    future::result(::std::string::String::from_utf8(bytes))
                        .map_err(Error::from)
                        .map(|template_string| (handle, template_string))
                }).and_then(move |(handle, template_string)| {
                    Tera::one_off(&template_string, &variables, false)
                        .map_err(Error::from)
                        .map(|latex_string| (handle, latex_string))
                }).and_then(|(handle, latex_string)| {
                    // debug!("Writing template to {:?}", template_path.clone());
                    let mut file = ::std::fs::File::create(template_path.clone()).unwrap();
                    file.write_all(latex_string.as_bytes()).unwrap();
                    // debug!("Template successfully written to {:?}", template_path.clone());
                    future::ok((handle, template_path))
                })

        // Then download the assets and save them in the temporary directory
                .and_then(move |(handle, template_path)| {
                    let named = assets_urls.into_iter().filter_map(|url| {
                        let inner = url.0;
                        extract_file_name_from_uri(&inner).map(|file_name| (file_name, inner))
                    });

                    let inner_handle = handle.clone();

                    let download_named = move |(name, url)| {
                        let mut path = out_tex_path.clone();
                        path.push(name);

                        http_client::download_file(&inner_handle, url)
                            .map(move |bytes| ::std::fs::File::create(&path).unwrap().write_all(&bytes))
                            .map_err(Error::from)
                    };
                    // debug!("Downloading assets {:?}", named);
                    future::join_all(named.map(download_named))
                        .map(|result| (handle, template_path, result))
                })

        // Then run latex
                .and_then(move |(handle, template_path, _)| {
                    let inner_handle = handle.clone();
                    let temp_dir_path = template_path.parent().unwrap().to_str().unwrap();
                    Command::new("xelatex")
                        .arg(&format!("-output-directory={}", temp_dir_path))
                        .arg(template_path.clone())
                        .status_async(&inner_handle)
                        .map(|exit_status| (exit_status, handle))
                        .map_err(Error::from)
                }).and_then(|(exit_status, handle)| {
                    if exit_status.success() {
                        future::ok(handle)
                    } else {
                        future::err(ErrorKind::LatexFailed.into())
                    }
                })

        // Then construct the path to the generated PDF
                .and_then(move |handle| {
                    let mut path = out_pdf_path;
                    path.push(Path::new("out.pdf"));
                    future::ok((handle, path))
                })

        // Then get the bytes from the generated PDF path
                .and_then(|(handle, pdf_path)| {
                    // debug!("Reading the pdf from {:?}", pdf_path);
                    let pdf_file = ::std::fs::File::open(pdf_path).unwrap();
                    let pdf_bytes: Vec<u8> = pdf_file.bytes().collect::<Result<Vec<u8>, _>>().unwrap();
                    future::ok((handle, pdf_bytes))
                })

        // Finally, post the PDF to the callback URL
                .and_then(move |(handle, pdf_bytes)| {
                    let mut request = Request::new(Post, callback_url.0);
                    request.set_body(pdf_bytes);

                    // Avoid dir being dropped early
                    let _dir = dir;

                    Client::new(&handle).request(request)
                        .map(|_| ())
                        .map_err(Error::from)
                });

        Box::new(work)
    }
}

#[cfg(test)]
mod tests {
    use hyper::Uri;
    use super::extract_file_name_from_uri;

    #[test]
    fn test_extract_file_name_from_uri_works() {
        let assert_extracted = |input: &'static str, expected_output: Option<&'static str>| {
            let uri = input.parse::<Uri>().unwrap();
            assert_eq!(extract_file_name_from_uri(&uri), expected_output.map(|o| o.to_string()));
        };

        assert_extracted("/logo.png", Some("logo.png"));
        assert_extracted("/assets/", None);
        assert_extracted("/assets/icon", Some("icon"));
        assert_extracted("/", None);
        assert_extracted("http://www.store2be.com", None);
    }
}
<commit_msg>:sparkles: Log debug messages from execute<commit_after>use futures::future;
use futures::Future;
use hyper::Uri;
use hyper::client::{Client, Request};
use hyper::Method::Post;
use mktemp::Temp;
use slog;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
use tokio_core::reactor::{Handle, Remote};
use tokio_process::CommandExt;
use tera::Tera;

use http_client;
use papers::DocumentSpec;
use error::{Error, ErrorKind};

pub struct Workspace {
    dir: Temp,
    document_spec: DocumentSpec,
    handle: Handle,
    template_path: ::std::path::PathBuf,
    logger: slog::Logger,
}

struct WorkspaceContext {
    handle: Handle,
    logger: slog::Logger,
}

/// We ignore file names that end with a slash for now, and always determine the file name from the Uri
/// TODO: investigate Content-Disposition: attachment
fn extract_file_name_from_uri(uri: &Uri) -> Option<String> {
    match uri.path().split('/').last() {
        Some(name) => {
            if !name.is_empty() {
                Some(name.to_string())
            } else {
                None
            }
        },
        None => None,
    }
}

/// Since `mktemp::Temp` implements Drop by deleting the directory, we don't need to worry about
/// leaving files or directories behind. On the flipside, we must ensure it is not dropped before
/// the last returned future that needs the directory finishes.
impl Workspace {

    pub fn new(remote: Remote, document_spec: DocumentSpec, logger: slog::Logger) -> Result<Workspace, Error> {
        let dir = Temp::new_dir()?;
        let mut template_path = dir.to_path_buf();
        template_path.push(Path::new("out.tex"));
        Ok(Workspace {
            document_spec: document_spec,
            handle: remote.handle().unwrap(),
            template_path: template_path,
            dir: dir,
            logger: logger,
        })
    }

    pub fn preview(self) -> Box<Future<Item=String, Error=Error>> {
        let Workspace {
            handle,
            document_spec,
            ..
        } = self;

        let DocumentSpec {
            template_url,
            variables,
            ..
        } = document_spec;

        // Download the template and populate it
        let work = http_client::download_file(&handle.clone(), template_url.0)
            .and_then(|bytes| {
                future::result(::std::string::String::from_utf8(bytes))
                    .map_err(Error::from)
            }).and_then(move |template_string| {
                Tera::one_off(&template_string, &variables, false)
                    .map_err(Error::from)
            });

        Box::new(work)
    }

    pub fn execute(self) -> Box<Future<Item=(), Error=Error>> {
        let Workspace {
            handle,
            document_spec,
            template_path,
            dir,
            logger,
        } = self;

        let DocumentSpec {
            assets_urls,
            callback_url,
            template_url,
            variables,
        } = document_spec;

        debug!(logger, "Starting Workspace worker");

        let out_tex_path = dir.to_path_buf();
        let out_pdf_path = dir.to_path_buf();

        let context = WorkspaceContext {
            handle: handle,
            logger: logger,
        };

        // First download the template and populate it
        let work = http_client::download_file(&context.handle.clone(), template_url.0)
                .and_then(move |bytes| {
                    debug!(context.logger, "Successfully downloaded template");
                    future::result(::std::string::String::from_utf8(bytes))
                        .map_err(Error::from)
                        .map(|template_string| (context, template_string))
                }).and_then(move |(context, template_string)| {
                    Tera::one_off(&template_string, &variables, false)
                        .map_err(Error::from)
                        .map(|latex_string| (context, latex_string))
                }).and_then(|(context, latex_string)| {
                    debug!(context.logger, "Writing template to {:?}", template_path.clone());
                    let mut file = ::std::fs::File::create(template_path.clone()).unwrap();
                    file.write_all(latex_string.as_bytes()).unwrap();
                    debug!(context.logger, "Template successfully written to {:?}", template_path.clone());
                    future::ok((context, template_path))
                })

        // Then download the assets and save them in the temporary directory
                .and_then(move |(context, template_path)| {
                    let named = assets_urls.into_iter().filter_map(|url| {
                        let inner = url.0;
                        extract_file_name_from_uri(&inner).map(|file_name| (file_name, inner))
                    });

                    let inner_handle = context.handle.clone();

                    let download_named = move |(name, url)| {
                        let mut path = out_tex_path.clone();
                        path.push(name);

                        http_client::download_file(&inner_handle, url)
                            .map(move |bytes| ::std::fs::File::create(&path).unwrap().write_all(&bytes))
                            .map_err(Error::from)
                    };
                    debug!(context.logger, "Downloading assets {:?}", named);
                    future::join_all(named.map(download_named))
                        .map(|result| (context, template_path, result))
                })

        // Then run latex
                .and_then(move |(context, template_path, _)| {
                    let inner_handle = context.handle.clone();
                    let temp_dir_path = template_path.parent().unwrap().to_str().unwrap();
                    Command::new("xelatex")
                        .arg(&format!("-output-directory={}", temp_dir_path))
                        .arg(template_path.clone())
                        .status_async(&inner_handle)
                        .map(|exit_status| (context, exit_status))
                        .map_err(Error::from)
                }).and_then(|(context, exit_status)| {
                    if exit_status.success() {
                        future::ok(context)
                    } else {
                        future::err(ErrorKind::LatexFailed.into())
                    }
                })

        // Then construct the path to the generated PDF
                .and_then(move |context| {
                    let mut path = out_pdf_path;
                    path.push(Path::new("out.pdf"));
                    future::ok((context, path))
                })

        // Then get the bytes from the generated PDF path
                .and_then(|(context, pdf_path)| {
                    debug!(context.logger, "Reading the pdf from {:?}", pdf_path);
                    let pdf_file = ::std::fs::File::open(pdf_path).unwrap();
                    let pdf_bytes: Vec<u8> = pdf_file.bytes().collect::<Result<Vec<u8>, _>>().unwrap();
                    future::ok((context, pdf_bytes))
                })

        // Finally, post the PDF to the callback URL
                .and_then(move |(context, pdf_bytes)| {
                    let mut request = Request::new(Post, callback_url.0);
                    request.set_body(pdf_bytes);

                    // Avoid dir being dropped early
                    let _dir = dir;

                    Client::new(&context.handle).request(request)
                        .map(|_| ())
                        .map_err(Error::from)
                });

        Box::new(work)
    }
}

#[cfg(test)]
mod tests {
    use hyper::Uri;
    use super::extract_file_name_from_uri;

    #[test]
    fn test_extract_file_name_from_uri_works() {
        let assert_extracted = |input: &'static str, expected_output: Option<&'static str>| {
            let uri = input.parse::<Uri>().unwrap();
            assert_eq!(extract_file_name_from_uri(&uri), expected_output.map(|o| o.to_string()));
        };

        assert_extracted("/logo.png", Some("logo.png"));
        assert_extracted("/assets/", None);
        assert_extracted("/assets/icon", Some("icon"));
        assert_extracted("/", None);
        assert_extracted("http://www.store2be.com", None);
    }
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
const END_TAG_LEN: u32 = 8;

use core::mem::transmute;

#[macro_use]
macro_rules! ptr {
    ($it:expr) => { &$it as *const _ }
}

pub mod elf;
pub mod elf64;

#[repr(C)]
pub struct Info { pub length: u32
                , _pad: u32
                , tag_start: Tag
                }

impl Info {

    pub unsafe fn from(addr: usize) -> &'static Self {
        let info = &*(addr as *const Info);
        assert!(info.has_end());
        info
    }

    /// Finds the tag with the given tag type.
    ///
    /// This is actually safe since the tag types are constrained by The
    /// `TagType` enum
    pub fn get_tag(&self, tag_type: TagType) -> Option<&'static Tag> {
        self.tags()
            .find(|t| t.ty == tag_type)
    }

    #[inline]
    pub fn mem_map(&self) -> Option<&'static MemMapTag> {
        self.get_tag(TagType::MemoryMap)
            .map(|tag| unsafe { &*(ptr!(tag) as *const MemMapTag) })
    }

    #[inline]
    pub fn elf64_sections(&self) -> Option<&'static elf64::SectionsTag> {
        self.get_tag(TagType::ELFSections)
            .map(|tag| unsafe { &*(ptr!(tag) as *const elf64::SectionsTag) })
    }

    #[inline]
    fn tags(&self) -> Tags { Tags(ptr!(self.tag_start)) }

    fn has_end(&self) -> bool {
        let end_tag_addr
            = (self as *const _) as usize +
              (self.length - END_TAG_LEN) as usize;
        let end_tag = unsafe {&*(end_tag_addr as *const Tag)};
        end_tag.ty == TagType::End && end_tag.length == 8
    }
}

/// A Multiboot tag.
///
/// From the specification:
///
/// Boot information consists of a fixed part and a series of tags.
/// Its start is 8-bytes aligned. Fixed part is as following:
///
///<rawtext>
///
///             +-------------------+
///     u32     | total_size        |
///     u32     | reserved          |
///             +-------------------+
///</rawtext>
///
/// `total_size` contains the total size of boot information including this
/// field and terminating tag in bytes.
/// `reserved` is always set to zero and must be ignored by OS image.
///
///  Every tag begins with following fields:
///<rawtext>
///
///             +-------------------+
///     u32     | type              |
///     u32     | size              |
///             +-------------------+
///</rawtext>
/// `type` contains an identifier of contents of the rest of the tag. `size`
/// contains the size of tag including header fields but not including padding.
/// Tags follow one another padded when necessary in order for each tag to
/// start at 8-bytes aligned address. Tags are terminated by a tag of type `0`
/// and size `8`.
#[repr(C)]
#[derive(Debug)]
pub struct Tag { ty: TagType
               , length: u32
               }

/// Types of Multiboot tags
///
/// Refer to Chapter 3 of the Multiboot 2 spec
#[repr(u32)]
#[derive(Debug, Eq, PartialEq)]
pub enum TagType { /// Tag that indicates the end of multiboot tags
                   End              = 0
                 , /// Command line passed to the bootloader
                   CommandLine      = 1
                 , BootloaderName   = 2
                 , Modules          = 3
                 , BasicMemInfo     = 4
                 , BIOSBootDev      = 5
                 , MemoryMap        = 6
                 , VBEInfo          = 7
                 , FramebufferInfo  = 8
                 , ELFSections      = 9
                 , APMTable         = 10
                 }

struct Tags(*const Tag);

impl Tags {
    #[inline] fn advance(&mut self, size: u32) {
        let next_addr = self.0 as usize + size as usize;
        self.0 = (((next_addr-1) & !0x7) + 0x8) as *const _;
    }
}

impl Iterator for Tags {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<Self::Item> {
        match unsafe { &*self.0 } {
            &Tag{ ty: TagType::End, length: END_TAG_LEN } => None
          , tag => { self.advance(tag.length); Some(tag) }
        }
    }
}

#[repr(C)]
pub struct MemMapTag { tag: Tag
                     , entry_size: u32
                     , entry_version: u32
                     , first_entry: MemArea
                     }
impl MemMapTag {
    pub fn entries(&self) -> Entries {
        Entries { curr: (&self.first_entry) as *const MemArea
                , last: ((self as *const MemMapTag as u32) +
                        (self.tag.length - self.entry_size))
                        as *const MemArea
                , size: self.entry_size
                }
    }
}

#[repr(u32)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum MemAreaType { Available = 1
                     , ACPI      = 3
                     , Preserve  = 4
                     }

#[repr(C)]
pub struct MemArea { pub base: u64
                   , pub length: u64
                   , ty: MemAreaType
                   , _pad: u32
                   }

pub struct Entries { curr: *const MemArea
                   , last: *const MemArea
                   , size: u32
                   }

impl Iterator for Entries {
    type Item = &'static MemArea;
    fn next(&mut self) -> Option<&'static MemArea> {
        if self.curr > self.last {
            None
        } else {
            let current = unsafe { &*self.curr };
            self.curr = (self.curr as u32 + self.size) as *const MemArea;
            if current.ty == MemAreaType::Available {
                Some(current)
            } else {
                self.next()
            }
        }
    }
}
<commit_msg>Attempt to fix KP by flattening MemMapTag structure Fine, I WON'T be clever...<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
const END_TAG_LEN: u32 = 8;

#[macro_use]
macro_rules! ptr {
    ($it:expr) => { &$it as *const _ }
}

pub mod elf;
pub mod elf64;

#[repr(C)]
pub struct Info { pub length: u32
                , _pad: u32
                , tag_start: Tag
                }

impl Info {

    pub unsafe fn from(addr: usize) -> &'static Self {
        let info = &*(addr as *const Info);
        assert!(info.has_end());
        info
    }

    /// Finds the tag with the given tag type.
    ///
    /// This is actually safe since the tag types are constrained by The
    /// `TagType` enum
    pub fn get_tag(&self, tag_type: TagType) -> Option<&'static Tag> {
        self.tags()
            .find(|t| t.ty == tag_type)
    }

    #[inline]
    pub fn mem_map(&self) -> Option<&'static MemMapTag> {
        self.get_tag(TagType::MemoryMap)
            .map(|tag| unsafe { &*(ptr!(tag) as *const MemMapTag) })
    }

    #[inline]
    pub fn elf64_sections(&self) -> Option<&'static elf64::SectionsTag> {
        self.get_tag(TagType::ELFSections)
            .map(|tag| unsafe { &*(ptr!(tag) as *const elf64::SectionsTag) })
    }

    #[inline]
    fn tags(&self) -> Tags { Tags(ptr!(self.tag_start)) }

    fn has_end(&self) -> bool {
        let end_tag_addr
            = (self as *const _) as usize +
              (self.length - END_TAG_LEN) as usize;
        let end_tag = unsafe {&*(end_tag_addr as *const Tag)};
        end_tag.ty == TagType::End && end_tag.length == 8
    }
}

/// A Multiboot tag.
///
/// From the specification:
///
/// Boot information consists of a fixed part and a series of tags.
/// Its start is 8-bytes aligned. Fixed part is as following:
///
///<rawtext>
///
///             +-------------------+
///     u32     | total_size        |
///     u32     | reserved          |
///             +-------------------+
///</rawtext>
///
/// `total_size` contains the total size of boot information including this
/// field and terminating tag in bytes.
/// `reserved` is always set to zero and must be ignored by OS image.
///
///  Every tag begins with following fields:
///<rawtext>
///
///             +-------------------+
///     u32     | type              |
///     u32     | size              |
///             +-------------------+
///</rawtext>
/// `type` contains an identifier of contents of the rest of the tag. `size`
/// contains the size of tag including header fields but not including padding.
/// Tags follow one another padded when necessary in order for each tag to
/// start at 8-bytes aligned address. Tags are terminated by a tag of type `0`
/// and size `8`.
#[repr(C)]
#[derive(Debug)]
pub struct Tag { ty: TagType
               , length: u32
               }

/// Types of Multiboot tags
///
/// Refer to Chapter 3 of the Multiboot 2 spec
#[repr(u32)]
#[derive(Debug, Eq, PartialEq)]
pub enum TagType { /// Tag that indicates the end of multiboot tags
                   End              = 0
                 , /// Command line passed to the bootloader
                   CommandLine      = 1
                 , BootloaderName   = 2
                 , Modules          = 3
                 , BasicMemInfo     = 4
                 , BIOSBootDev      = 5
                 , MemoryMap        = 6
                 , VBEInfo          = 7
                 , FramebufferInfo  = 8
                 , ELFSections      = 9
                 , APMTable         = 10
                 }

struct Tags(*const Tag);

impl Tags {
    #[inline] fn advance(&mut self, size: u32) {
        let next_addr = self.0 as usize + size as usize;
        self.0 = (((next_addr-1) & !0x7) + 0x8) as *const _;
    }
}

impl Iterator for Tags {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<Self::Item> {
        match unsafe { &*self.0 } {
            &Tag{ ty: TagType::End, length: END_TAG_LEN } => None
          , tag => { self.advance(tag.length); Some(tag) }
        }
    }
}

#[repr(C)]
pub struct MemMapTag { ty: TagType
                     , length: u32
                     , entry_size: u32
                     , entry_version: u32
                     , first_entry: MemArea
                     }
impl MemMapTag {
    pub fn entries(&self) -> Entries {
        Entries { curr: (&self.first_entry) as *const MemArea
                , last: ((self as *const MemMapTag as u32) +
                        (self.length - self.entry_size))
                        as *const MemArea
                , size: self.entry_size
                }
    }
}

#[repr(u32)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum MemAreaType { Available = 1
                     , ACPI      = 3
                     , Preserve  = 4
                     }

#[repr(C)]
pub struct MemArea { pub base: u64
                   , pub length: u64
                   , ty: MemAreaType
                   , _pad: u32
                   }

pub struct Entries { curr: *const MemArea
                   , last: *const MemArea
                   , size: u32
                   }

impl Iterator for Entries {
    type Item = &'static MemArea;
    fn next(&mut self) -> Option<&'static MemArea> {
        if self.curr > self.last {
            None
        } else {
            let current = unsafe { &*self.curr };
            self.curr = (self.curr as u32 + self.size) as *const MemArea;
            if current.ty == MemAreaType::Available {
                Some(current)
            } else {
                self.next()
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::DerefMut;

use toml::Value;

use std::collections::BTreeMap;

use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;
use result::Result;
use error::CounterError as CE;
use error::CounterErrorKind as CEK;

pub type CounterName = String;
pub type CounterUnit = String;

pub struct Counter<'a> {
    fle: FileLockEntry<'a>,
}

impl<'a> Counter<'a> {

    pub fn new(store: &Store, name: CounterName, init: i64, unit: CounterUnit) -> Result<Counter> {
        use std::ops::DerefMut;

        debug!("Creating new counter: '{}' with value: {}", name, init);
        let fle = {
            let lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
            if lockentry.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(lockentry.err().unwrap()))));
            }
            let mut lockentry = lockentry.unwrap();

            {
                let mut entry  = lockentry.deref_mut();
                let mut header = entry.get_header_mut();
                let setres = header.set("counter", Value::Table(BTreeMap::new()));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.name", Value::String(name));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.value", Value::Integer(init));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.unit", Value::String(unit));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }
            }

            lockentry
        };

        Ok(Counter { fle: fle })
    }

    pub fn inc(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i + 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn dec(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i - 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn reset(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(0))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn set(&mut self, v: i64) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(v))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn name(&self) -> Result<CounterName> {
        self.fle.get_header().read("counter.name")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn value(&self) -> Result<i64> {
        self.fle.get_header().read("counter.value")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::Integer(i)) => Ok(i),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn unit(&self) -> Result<CounterUnit> {
        self.fle.get_header().read("counter.unit")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|u| {
                match u {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn load(name: CounterName, store: &Store) -> Result<Counter> {
        debug!("Loading counter: '{}'", name);
        match store.retrieve(ModuleEntryPath::new(name).into_storeid()) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

    pub fn delete(name: CounterName, store: &Store) -> Result<()> {
        debug!("Deleting counter: '{}'", name);
        store.delete(ModuleEntryPath::new(name).into_storeid())
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
    }

    pub fn all_counters(store: &Store) -> Result<CounterIterator> {
        store.retrieve_for_module("counter")
            .map(|iter| CounterIterator::new(store, iter))
            .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e))))
    }

}

trait FromStoreId {
    fn from_storeid(&Store, StoreId) -> Result<Counter>;
}

impl<'a> FromStoreId for Counter<'a> {

    fn from_storeid(store: &Store, id: StoreId) -> Result<Counter> {
        debug!("Loading counter from storeid: '{:?}'", id);
        match store.retrieve(id) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

}

pub struct CounterIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> CounterIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> {
        CounterIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for CounterIterator<'a> {
    type Item = Result<Counter<'a>>;

    fn next(&mut self) -> Option<Result<Counter<'a>>> {
        self.iditer
            .next()
            .map(|id| Counter::from_storeid(self.store, id))
    }

}

<commit_msg>replaced typedef with newtype<commit_after>use std::ops::DerefMut;

use toml::Value;

use std::collections::BTreeMap;
use std::fmt;
use std::fmt::Display;

use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagerror::into::IntoError;

use module_path::ModuleEntryPath;
use result::Result;
use error::CounterError as CE;
use error::CounterErrorKind as CEK;

pub type CounterName = String;

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct CounterUnit(pub String);

impl Display for CounterUnit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({})", self.0)
    }
}

pub struct Counter<'a> {
    fle: FileLockEntry<'a>,
}

impl<'a> Counter<'a> {

    pub fn new(store: &Store, name: CounterName, init: i64, unit: CounterUnit) -> Result<Counter> {
        use std::ops::DerefMut;

        debug!("Creating new counter: '{}' with value: {}", name, init);
        let fle = {
            let lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
            if lockentry.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(lockentry.err().unwrap()))));
            }
            let mut lockentry = lockentry.unwrap();

            {
                let mut entry  = lockentry.deref_mut();
                let mut header = entry.get_header_mut();
                let setres = header.set("counter", Value::Table(BTreeMap::new()));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.name", Value::String(name));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.value", Value::Integer(init))
                    .and_then(|_| header.set("counter.unit", Value::String(unit.clone().0)));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }
            }

            lockentry
        };

        Ok(Counter { fle: fle })
    }

    pub fn inc(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i + 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn dec(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i - 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn reset(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(0))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn set(&mut self, v: i64) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(v))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn name(&self) -> Result<CounterName> {
        self.fle.get_header().read("counter.name")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn value(&self) -> Result<i64> {
        self.fle.get_header().read("counter.value")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::Integer(i)) => Ok(i),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn unit(&self) -> Result<CounterUnit> {
        self.fle.get_header().read("counter.unit")
            .map_err(|e| CEK::StoreWriteError.into_error_with_cause(Box::new(e)))
            .and_then(|u|
                match u {
                    Some(Value::String(s)) => Ok(CounterUnit(s)),
                    _ => Err(CEK::HeaderTypeError.into_error())
                }
            )
    }

    pub fn load(name: CounterName, store: &Store) -> Result<Counter> {
        debug!("Loading counter: '{}'", name);
        match store.retrieve(ModuleEntryPath::new(name).into_storeid()) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

    pub fn delete(name: CounterName, store: &Store) -> Result<()> {
        debug!("Deleting counter: '{}'", name);
        store.delete(ModuleEntryPath::new(name).into_storeid())
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
    }

    pub fn all_counters(store: &Store) -> Result<CounterIterator> {
        store.retrieve_for_module("counter")
            .map(|iter| CounterIterator::new(store, iter))
            .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e))))
    }

}

trait FromStoreId {
    fn from_storeid(&Store, StoreId) -> Result<Counter>;
}

impl<'a> FromStoreId for Counter<'a> {

    fn from_storeid(store: &Store, id: StoreId) -> Result<Counter> {
        debug!("Loading counter from storeid: '{:?}'", id);
        match store.retrieve(id) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

}

pub struct CounterIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> CounterIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> {
        CounterIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for CounterIterator<'a> {
    type Item = Result<Counter<'a>>;

    fn next(&mut self) -> Option<Result<Counter<'a>>> {
        self.iditer
            .next()
            .map(|id| Counter::from_storeid(self.store, id))
    }

}

<|endoftext|>


<commit_before>use postings::DocSet;
use postings::SkipResult;
use DocId;

/// Creates a `DocSet` that iterator through the intersection of two `DocSet`s.
pub struct IntersectionDocSet<TDocSet: DocSet> {
    docsets: Vec<TDocSet>,
    finished: bool,
    doc: DocId,
}

impl<TDocSet: DocSet> From<Vec<TDocSet>> for IntersectionDocSet<TDocSet> {
    fn from(mut docsets: Vec<TDocSet>) -> IntersectionDocSet<TDocSet> {
        assert!(docsets.len() >= 2);
        docsets.sort_by_key(|docset| docset.size_hint());
        IntersectionDocSet {
            docsets: docsets,
            finished: false,
            doc: 0u32,
        }
    }
}

impl<TDocSet: DocSet> IntersectionDocSet<TDocSet> {
    /// Returns an array to the underlying `DocSet`s of the intersection.
    /// These `DocSet` are in the same position as the `IntersectionDocSet`,
    /// so that user can access their `docfreq` and `positions`.
    pub fn docsets(&self) -> &[TDocSet] {
        &self.docsets[..]
    }
}

impl<TDocSet: DocSet> DocSet for IntersectionDocSet<TDocSet> {
    fn size_hint(&self) -> usize {
        self.docsets
            .iter()
            .map(|docset| docset.size_hint())
            .min()
            .unwrap() // safe as docsets cannot be empty.
    }

    #[allow(never_loop)]
    fn advance(&mut self) -> bool {
        if self.finished {
            return false;
        }

        let mut candidate_doc = self.doc;
        let mut candidate_ord = self.docsets.len();

        'outer: loop {

            for (ord, docset) in self.docsets.iter_mut().enumerate() {
                if ord != candidate_ord {
                    // Candidate_ord is already at the
                    // right position.
                    //
                    // Calling `skip_next` would advance this docset
                    // and miss it.
                    match docset.skip_next(candidate_doc) {
                        SkipResult::Reached => {}
                        SkipResult::OverStep => {
                            // this is not in the intersection,
                            // let's update our candidate.
                            candidate_doc = docset.doc();
                            candidate_ord = ord;
                            continue 'outer;
                        }
                        SkipResult::End => {
                            self.finished = true;
                            return false;
                        }
                    }
                }
            }

            self.doc = candidate_doc;
            return true;
        }
    }

    fn doc(&self) -> DocId {
        self.doc
    }
}

#[cfg(test)]
mod tests {

    use postings::{DocSet, VecPostings, IntersectionDocSet};

    #[test]
    fn test_intersection() {
        {
            let left = VecPostings::from(vec![1, 3, 9]);
            let right = VecPostings::from(vec![3, 4, 9, 18]);
            let mut intersection = IntersectionDocSet::from(vec![left, right]);
            assert!(intersection.advance());
            assert_eq!(intersection.doc(), 3);
            assert!(intersection.advance());
            assert_eq!(intersection.doc(), 9);
            assert!(!intersection.advance());
        }
        {
            let a = VecPostings::from(vec![1, 3, 9]);
            let b = VecPostings::from(vec![3, 4, 9, 18]);
            let c = VecPostings::from(vec![1, 5, 9, 111]);
            let mut intersection = IntersectionDocSet::from(vec![a, b, c]);
            assert!(intersection.advance());
            assert_eq!(intersection.doc(), 9);
            assert!(!intersection.advance());
        }
    }

    #[test]
    fn test_intersection_zero() {
        let left = VecPostings::from(vec![0]);
        let right = VecPostings::from(vec![0]);
        let mut intersection = IntersectionDocSet::from(vec![left, right]);
        assert!(intersection.advance());
        assert_eq!(intersection.doc(), 0);
    }

    #[test]
    fn test_intersection_empty() {
        let a = VecPostings::from(vec![1, 3]);
        let b = VecPostings::from(vec![1, 4]);
        let c = VecPostings::from(vec![3, 9]);
        let mut intersection = IntersectionDocSet::from(vec![a, b, c]);
        assert!(!intersection.advance());
    }
}
<commit_msg>Comment nit<commit_after>use postings::DocSet;
use postings::SkipResult;
use DocId;

/// Creates a `DocSet` that iterator through the intersection of two `DocSet`s.
pub struct IntersectionDocSet<TDocSet: DocSet> {
    docsets: Vec<TDocSet>,
    finished: bool,
    doc: DocId,
}

impl<TDocSet: DocSet> From<Vec<TDocSet>> for IntersectionDocSet<TDocSet> {
    fn from(mut docsets: Vec<TDocSet>) -> IntersectionDocSet<TDocSet> {
        assert!(docsets.len() >= 2);
        docsets.sort_by_key(|docset| docset.size_hint());
        IntersectionDocSet {
            docsets: docsets,
            finished: false,
            doc: 0u32,
        }
    }
}

impl<TDocSet: DocSet> IntersectionDocSet<TDocSet> {
    /// Returns an array to the underlying `DocSet`s of the intersection.
    /// These `DocSet` are in the same position as the `IntersectionDocSet`,
    /// so that user can access their `docfreq` and `positions`.
    pub fn docsets(&self) -> &[TDocSet] {
        &self.docsets[..]
    }
}

impl<TDocSet: DocSet> DocSet for IntersectionDocSet<TDocSet> {
    fn size_hint(&self) -> usize {
        self.docsets
            .iter()
            .map(|docset| docset.size_hint())
            .min()
            .unwrap() // safe as docsets cannot be empty.
    }

    #[allow(never_loop)]
    fn advance(&mut self) -> bool {
        if self.finished {
            return false;
        }

        let mut candidate_doc = self.doc;
        let mut candidate_ord = self.docsets.len();

        'outer: loop {

            for (ord, docset) in self.docsets.iter_mut().enumerate() {
                if ord != candidate_ord {
                    // `candidate_ord` is already at the
                    // right position.
                    //
                    // Calling `skip_next` would advance this docset
                    // and miss it.
                    match docset.skip_next(candidate_doc) {
                        SkipResult::Reached => {}
                        SkipResult::OverStep => {
                            // this is not in the intersection,
                            // let's update our candidate.
                            candidate_doc = docset.doc();
                            candidate_ord = ord;
                            continue 'outer;
                        }
                        SkipResult::End => {
                            self.finished = true;
                            return false;
                        }
                    }
                }
            }

            self.doc = candidate_doc;
            return true;
        }
    }

    fn doc(&self) -> DocId {
        self.doc
    }
}

#[cfg(test)]
mod tests {

    use postings::{DocSet, VecPostings, IntersectionDocSet};

    #[test]
    fn test_intersection() {
        {
            let left = VecPostings::from(vec![1, 3, 9]);
            let right = VecPostings::from(vec![3, 4, 9, 18]);
            let mut intersection = IntersectionDocSet::from(vec![left, right]);
            assert!(intersection.advance());
            assert_eq!(intersection.doc(), 3);
            assert!(intersection.advance());
            assert_eq!(intersection.doc(), 9);
            assert!(!intersection.advance());
        }
        {
            let a = VecPostings::from(vec![1, 3, 9]);
            let b = VecPostings::from(vec![3, 4, 9, 18]);
            let c = VecPostings::from(vec![1, 5, 9, 111]);
            let mut intersection = IntersectionDocSet::from(vec![a, b, c]);
            assert!(intersection.advance());
            assert_eq!(intersection.doc(), 9);
            assert!(!intersection.advance());
        }
    }

    #[test]
    fn test_intersection_zero() {
        let left = VecPostings::from(vec![0]);
        let right = VecPostings::from(vec![0]);
        let mut intersection = IntersectionDocSet::from(vec![left, right]);
        assert!(intersection.advance());
        assert_eq!(intersection.doc(), 0);
    }

    #[test]
    fn test_intersection_empty() {
        let a = VecPostings::from(vec![1, 3]);
        let b = VecPostings::from(vec![1, 4]);
        let c = VecPostings::from(vec![3, 9]);
        let mut intersection = IntersectionDocSet::from(vec![a, b, c]);
        assert!(!intersection.advance());
    }
}
<|endoftext|>


<commit_before>#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}

impl From<Bar> for Foo {
    fn from(child: Bar) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Bar {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Bar, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) };
        if is_kind_of {
            Ok(Bar(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Bar")
        }
    }
}
impl IBar for Bar {}
impl From<Baz> for Bar {
    fn from(child: Baz) -> Bar {
        Bar(child.0)
    }
}
impl std::convert::TryFrom<Bar> for Baz {
    type Error = &'static str;
    fn try_from(parent: Bar) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Bar cannot be downcasted to Baz")
        }
    }
}
impl IFoo for Baz {}
impl From<Baz> for Foo {
    fn from(child: Baz) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Baz {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Baz")
        }
    }
}
pub trait IBar: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Baz(pub id);
impl std::ops::Deref for Baz {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Baz {}
impl Baz {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
    }
}
impl IBaz for Baz {}
pub trait IBaz: Sized + std::ops::Deref {}
<commit_msg>Update to fix CI<commit_after>#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}
impl From<Bar> for Foo {
    fn from(child: Bar) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Bar {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Bar, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) };
        if is_kind_of {
            Ok(Bar(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Bar")
        }
    }
}
impl IBar for Bar {}
pub trait IBar: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Baz(pub id);
impl std::ops::Deref for Baz {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Baz {}
impl Baz {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
    }
}
impl From<Baz> for Bar {
    fn from(child: Baz) -> Bar {
        Bar(child.0)
    }
}
impl std::convert::TryFrom<Bar> for Baz {
    type Error = &'static str;
    fn try_from(parent: Bar) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Bar cannot be downcasted to Baz")
        }
    }
}
impl IFoo for Baz {}
impl From<Baz> for Foo {
    fn from(child: Baz) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Baz {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Baz")
        }
    }
}
impl IBaz for Baz {}
pub trait IBaz: Sized + std::ops::Deref {}
<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)]

extern crate proc_macro;

#[cfg(test)]
#[macro_use]
extern crate serde_derive;

use proc_macro::TokenStream;
use quote::quote;
use syn::{Lit, Meta, MetaNameValue};

#[proc_macro_derive(Partial, attributes(location))]
pub fn derive_partial(tokens: TokenStream) -> TokenStream {
    let ast: syn::DeriveInput = syn::parse(tokens).unwrap();
    let mut location: Option<String> = None;
    let name = &ast.ident;

    // Iterate over the struct's #[...] attributes
    for option in ast.attrs.into_iter() {
        let option = option.parse_meta().unwrap();
        match option {
            // Match '#[ident = lit]' attributes. Match guard makes it '#[prefix = lit]'
            Meta::NameValue(MetaNameValue {
                ref path, ref lit, ..
            }) if path.is_ident("location") => {
                if let Lit::Str(lit) = lit {
                    location = Some(lit.value());
                }
            }
            _ => {} // ...
        }
    }

    let location = location.unwrap();

    let gen = quote! {
        impl<'a> ::toml_query::read::Partial<'a> for #name {
            const LOCATION : &'static str = #location;
            type  Output                  = Self;
        }
    };

    gen.into()
}
<commit_msg>Remove unused crate<commit_after>#![warn(rust_2018_idioms)]

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::{Lit, Meta, MetaNameValue};

#[proc_macro_derive(Partial, attributes(location))]
pub fn derive_partial(tokens: TokenStream) -> TokenStream {
    let ast: syn::DeriveInput = syn::parse(tokens).unwrap();
    let mut location: Option<String> = None;
    let name = &ast.ident;

    // Iterate over the struct's #[...] attributes
    for option in ast.attrs.into_iter() {
        let option = option.parse_meta().unwrap();
        match option {
            // Match '#[ident = lit]' attributes. Match guard makes it '#[prefix = lit]'
            Meta::NameValue(MetaNameValue {
                ref path, ref lit, ..
            }) if path.is_ident("location") => {
                if let Lit::Str(lit) = lit {
                    location = Some(lit.value());
                }
            }
            _ => {} // ...
        }
    }

    let location = location.unwrap();

    let gen = quote! {
        impl<'a> ::toml_query::read::Partial<'a> for #name {
            const LOCATION : &'static str = #location;
            type  Output                  = Self;
        }
    };

    gen.into()
}
<|endoftext|>


<commit_before>extern crate lopdf;

use lopdf::{Document, Object, StringFormat};
use std::io::Result;

fn modify_text() -> Result<Document> {
	let mut doc = Document::load("assets/example.pdf")?;
	doc.version = "1.4".to_string();
	if let Some(content_stream) = doc.objects.get_mut(&(4, 0)) {
		match *content_stream {
			Object::Stream(ref mut stream) => {
				let mut content = stream.decode_content().unwrap();
				content.operations[3].operands[0] = Object::String(
					b"Modified text!".to_vec(),
					StringFormat::Literal);
				stream.set_content(content.encode().unwrap());
			},
			_ => ()
		}
	}

	doc.save("test_3_modify.pdf")?;
	Ok(doc)
}

#[test]
fn test_modify() {
	assert_eq!(modify_text().is_ok(), true);
}

#[test]
fn test_get_object() {
	let mut doc = Document::new();
	let id = doc.add_object(Object::String("test".as_bytes().to_vec(), StringFormat::Literal));
	println!("{:?}", id);
	assert!(doc.get_object(id).is_some());
}<commit_msg>Fixed unit tests<commit_after>extern crate lopdf;

use lopdf::{Document, Object, StringFormat};
use std::io::Result;

fn modify_text() -> Result<Document> {
	let mut doc = Document::load("assets/example.pdf")?;
	doc.version = "1.4".to_string();
	if let Some(content_stream) = doc.objects.get_mut(&(4, 0)) {
		match *content_stream {
			Object::Stream(ref mut stream) => {
				let mut content = stream.decode_content().unwrap();
				content.operations[3].operands[0] = Object::String(
					b"Modified text!".to_vec(),
					StringFormat::Literal);
				stream.set_content(content.encode().unwrap());
			},
			_ => ()
		}
	}

	doc.save("test_3_modify.pdf")?;
	Ok(doc)
}

#[test]
fn test_modify() {
	assert_eq!(modify_text().is_ok(), true);
}

#[test]
fn test_get_object() {
	use lopdf::Dictionary as LoDictionary;
	use lopdf::Stream as LoStream;
	use self::Object;

	let mut doc = Document::new();
	let id = doc.add_object(Object::String("test".as_bytes().to_vec(), StringFormat::Literal));
	let id2 = doc.add_object(Object::Stream(LoStream::new(LoDictionary::new(), "stream".as_bytes().to_vec())));

	println!("{:?}", id);
	println!("{:?}", id2);
	assert!(doc.get_object(id).is_some());
	assert!(doc.get_object(id2).is_some());
}<|endoftext|>


<commit_before>#[test]
fn dogfood() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    let output = std::process::Command::new(clippy_cmd)
        .current_dir(root_dir)
        .env("CLIPPY_DOGFOOD", "1")
        .arg("clippy-preview")
        .arg("--all-targets")
        .arg("--all-features")
        .arg("--")
        .args(&["-D", "clippy::all"])
        .args(&["-D", "clippy::internal"])
        .args(&["-D", "clippy::pedantic"])
        .output()
        .unwrap();
    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    assert!(output.status.success());
}

#[test]
fn dogfood_tests() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    for d in &[
        "clippy_workspace_tests",
        "clippy_workspace_tests/src",
        "clippy_workspace_tests/subcrate",
        "clippy_workspace_tests/subcrate/src",
        "clippy_dev",
        "rustc_tools_util",
    ] {
        let output = std::process::Command::new(&clippy_cmd)
            .current_dir(root_dir.join(d))
            .env("CLIPPY_DOGFOOD", "1")
            .arg("clippy")
            .arg("--")
            .args(&["-D", "clippy::all"])
            .args(&["-D", "clippy::pedantic"])
            .output()
            .unwrap();
        println!("status: {}", output.status);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

        assert!(output.status.success());
    }
}
<commit_msg>tests: execute dogfood tests with incremental compilation disabled<commit_after>#[test]
fn dogfood() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    let output = std::process::Command::new(clippy_cmd)
        .current_dir(root_dir)
        .env("CLIPPY_DOGFOOD", "1")
        .env("CARGO_INCREMENTAL", "0")
        .arg("clippy-preview")
        .arg("--all-targets")
        .arg("--all-features")
        .arg("--")
        .args(&["-D", "clippy::all"])
        .args(&["-D", "clippy::internal"])
        .args(&["-D", "clippy::pedantic"])
        .output()
        .unwrap();
    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    assert!(output.status.success());
}

#[test]
fn dogfood_tests() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    for d in &[
        "clippy_workspace_tests",
        "clippy_workspace_tests/src",
        "clippy_workspace_tests/subcrate",
        "clippy_workspace_tests/subcrate/src",
        "clippy_dev",
        "rustc_tools_util",
    ] {
        let output = std::process::Command::new(&clippy_cmd)
            .current_dir(root_dir.join(d))
            .env("CLIPPY_DOGFOOD", "1")
            .env("CARGO_INCREMENTAL", "0")
            .arg("clippy")
            .arg("--")
            .args(&["-D", "clippy::all"])
            .args(&["-D", "clippy::pedantic"])
            .output()
            .unwrap();
        println!("status: {}", output.status);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

        assert!(output.status.success());
    }
}
<|endoftext|>


<commit_before>extern crate scroll;
extern crate goblin;
use goblin::archive::*;
use goblin::elf;
use scroll::Pread;
use std::path::Path;
use std::fs::File;

#[test]
fn parse_file_header() {
    let file_header: [u8; SIZEOF_HEADER] = [0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x30, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                            0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x20,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38,
                                            0x32, 0x34, 0x34, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x60, 0x0a];
    let buffer = &file_header[..];
    match buffer.pread::<MemberHeader>(0) {
        Err(_) => assert!(false),
        Ok(file_header2) => {
            let file_header = MemberHeader {
                identifier: [0x2f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,],
                timestamp: [48, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
                owner_id: [48, 32, 32, 32, 32, 32],
                group_id: [48, 32, 32, 32, 32, 32],
                mode: [48, 32, 32, 32, 32, 32, 32, 32],
                file_size: [56, 50, 52, 52, 32, 32, 32, 32, 32, 32],
                terminator: [96, 10] };
            assert_eq!(file_header, file_header2)
        }
    }
}

#[test]
fn parse_archive() {
    let crt1a: Vec<u8> = include!("../etc/crt1a.rs");
    const START: &'static str = "_start";
    match Archive::parse(&crt1a) {
        Ok(archive) => {
            assert_eq!(archive.member_of_symbol(START), Some("crt1.o"));
            if let Some(member) = archive.get("crt1.o") {
                assert_eq!(member.offset, 194);
                assert_eq!(member.size(), 1928)
            } else {
                println!("could not get crt1.o");
                assert!(false)
            }
        },
        Err(err) => {println!("could not parse archive: {:?}", err); assert!(false)}
    };
}

#[test]
fn parse_self_wow_so_meta_doge() {
    use std::io::Read;
    let path = Path::new("target").join("debug").join("libgoblin.rlib");
    match File::open(path) {
        Ok(mut fd) => {
            let buffer = { let mut v = Vec::new(); fd.read_to_end(&mut v).unwrap(); v};
            match Archive::parse(&buffer) {
                Ok(archive) => {
                    let mut found = false;
                    for member in archive.members() {
                        if member.starts_with("goblin") && member.ends_with("0.o") {
                            assert_eq!(archive.member_of_symbol("wow_so_meta_doge_symbol"), Some(member.as_str()));
                            match archive.extract(member.as_str(), &buffer) {
                                Ok(bytes) => {
                                    match elf::Elf::parse(&bytes) {
                                        Ok(elf) => {
                                            assert!(elf.entry == 0);
                                            assert!(elf.bias == 0);
                                            found = true;
                                            break;
                                        },
                                        Err(err) => {
                                            println!("{:?}", err);
                                            #[cfg(target_os="linux")]
                                            assert!(false)
                                        }
                                    }
                                },
                                Err(_) => assert!(false)
                            }
                        }
                    }
                    if !found {
                        println!("goblin-<hash>.0.o not found");
                        assert!(false)
                    }
                },
                Err(err) => {println!("{:?}", err); assert!(false)}
            }
        },
        Err(err) => {println!("{:?}", err); assert!(false)}
    }
}
<commit_msg>archive: add 1.18 fix for separate object file compilation in self rlib<commit_after>extern crate scroll;
extern crate goblin;
use goblin::archive::*;
use goblin::elf;
use scroll::Pread;
use std::path::Path;
use std::fs::File;

#[test]
fn parse_file_header() {
    let file_header: [u8; SIZEOF_HEADER] = [0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x30, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                            0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x20,
                                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38,
                                            0x32, 0x34, 0x34, 0x20, 0x20, 0x20, 0x20,
                                            0x20, 0x20, 0x60, 0x0a];
    let buffer = &file_header[..];
    match buffer.pread::<MemberHeader>(0) {
        Err(_) => assert!(false),
        Ok(file_header2) => {
            let file_header = MemberHeader {
                identifier: [0x2f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,],
                timestamp: [48, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
                owner_id: [48, 32, 32, 32, 32, 32],
                group_id: [48, 32, 32, 32, 32, 32],
                mode: [48, 32, 32, 32, 32, 32, 32, 32],
                file_size: [56, 50, 52, 52, 32, 32, 32, 32, 32, 32],
                terminator: [96, 10] };
            assert_eq!(file_header, file_header2)
        }
    }
}

#[test]
fn parse_archive() {
    let crt1a: Vec<u8> = include!("../etc/crt1a.rs");
    const START: &'static str = "_start";
    match Archive::parse(&crt1a) {
        Ok(archive) => {
            assert_eq!(archive.member_of_symbol(START), Some("crt1.o"));
            if let Some(member) = archive.get("crt1.o") {
                assert_eq!(member.offset, 194);
                assert_eq!(member.size(), 1928)
            } else {
                println!("could not get crt1.o");
                assert!(false)
            }
        },
        Err(err) => {println!("could not parse archive: {:?}", err); assert!(false)}
    };
}

#[test]
fn parse_self_wow_so_meta_doge() {
    use std::io::Read;
    let path = Path::new("target").join("debug").join("libgoblin.rlib");
    match File::open(path) {
        Ok(mut fd) => {
            let buffer = { let mut v = Vec::new(); fd.read_to_end(&mut v).unwrap(); v};
            match Archive::parse(&buffer) {
                Ok(archive) => {
                    let mut found = false;
                    for member in archive.members() {
                        println!("member: {:?}", member);
                        if member.starts_with("goblin") &&
                            // pre 1.18
                            (member.ends_with("0.o") ||
                             // >= 1.18
                             member.ends_with("goblin-archive.o")) {
                            assert_eq!(archive.member_of_symbol("wow_so_meta_doge_symbol"), Some(member.as_str()));
                            match archive.extract(member.as_str(), &buffer) {
                                Ok(bytes) => {
                                    match elf::Elf::parse(&bytes) {
                                        Ok(elf) => {
                                            assert!(elf.entry == 0);
                                            assert!(elf.bias == 0);
                                            found = true;
                                            break;
                                        },
                                        Err(err) => {
                                            println!("{:?}", err);
                                            #[cfg(target_os="linux")]
                                            assert!(false)
                                        }
                                    }
                                },
                                Err(_) => assert!(false)
                            }
                        }
                    }
                    if !found {
                        println!("goblin-<hash>.0.o not found");
                        assert!(false)
                    }
                },
                Err(err) => {println!("{:?}", err); assert!(false)}
            }
        },
        Err(err) => {println!("{:?}", err); assert!(false)}
    }
}
<|endoftext|>


<commit_before>use protobuf::hex::decode_hex;

use protobuf::*;

use test::*;

use super::test_basic_pb::*;

#[test]
fn test1() {
    let mut test1 = Test1::new();
    test1.set_a(150);
    test_serialize_deserialize("08 96 01", &test1);
}

#[test]
fn test2() {
    let mut test2 = Test2::new();
    test2.set_b("testing".to_string());
    test_serialize_deserialize("12 07 74 65 73 74 69 6e 67", &test2);
}

#[test]
fn test3() {
    let mut test1 = Test1::new();
    test1.set_a(150);
    let mut test3 = Test3::new();
    test3.set_c(test1);
    test_serialize_deserialize("1a 03 08 96 01", &test3);
}

#[test]
fn test4() {
    let mut test4 = Test4::new();
    test4.set_d([3i32, 270, 86942].to_vec());
    test_serialize_deserialize("22 06 03 8E 02 9E A7 05", &test4);
}

#[test]
fn test_recursion_limit() {
    let mut test = TestRecursion::new();
    for _ in 0..10 {
        let mut t = TestRecursion::new();
        t.mut_children().push(test);
        test = t;
    }

    let bytes = test.write_to_bytes().unwrap();
    let cases = vec![
        (None, false),
        (Some(9), true),
        (Some(10), false),
    ];

    for (limit, has_err) in cases {
        let mut is = CodedInputStream::from_bytes(&bytes);
        if let Some(limit) = limit {
            is.set_recursion_limit(limit);
        }
        let mut t = TestRecursion::new();
        let res = t.merge_from(&mut is);
        assert_eq!(res.is_err(), has_err, "limit: {:?}", limit);
        if !has_err {
            assert_eq!(t, test, "limit: {:?}", limit);
        }
    }
}

#[test]
fn test_read_unpacked_expect_packed() {
    let mut test_packed_unpacked = TestPackedUnpacked::new();
    test_packed_unpacked.set_packed(Vec::new());
    test_packed_unpacked.set_unpacked([17i32, 1000].to_vec());
    test_deserialize("20 11 20 e8 07", &test_packed_unpacked);
}

#[test]
fn test_read_packed_expect_unpacked() {
    let mut test_packed_unpacked = TestPackedUnpacked::new();
    test_packed_unpacked.set_packed([17i32, 1000].to_vec());
    test_packed_unpacked.set_unpacked(Vec::new());
    test_deserialize("2a 03 11 e8 07", &test_packed_unpacked);
}

#[test]
fn test_end_by_negative_int() {
    // added following https://github.com/stepancheg/rust-protobuf/pull/209
    let mut test = Test1::new();
    test.set_a(-1);
    test_serialize_deserialize("08 ff ff ff ff ff ff ff ff ff 01", &test);
}

#[test]
fn test_empty() {
    test_serialize_deserialize("", &TestEmpty::new());
}

#[test]
fn test_read_junk() {
    assert!(parse_from_bytes::<Test1>(&decode_hex("00")).is_err());
}

#[test]
fn test_unknown_fields_length_delimited() {
    let mut message = TestUnknownFields::new();
    message.set_a(150);
    message
        .mut_unknown_fields()
        .add_length_delimited(4, [0x10u8, 0x20, 0x30].to_vec());
    test_serialize_deserialize("08 96 01 22 03 10 20 30", &message);
}

#[test]
fn test_unknown_fields_fixed32() {
    let mut message = TestUnknownFields::new();
    message.set_a(150);
    message.mut_unknown_fields().add_fixed32(4, 0x01020304);
    message.mut_unknown_fields().add_fixed32(4, 0xA1A2A3A4);
    test_serialize_deserialize("08 96 01 25 04 03 02 01 25 A4 A3 A2 A1", &message);
}

#[test]
fn test_types_singular() {
    let mut message = TestTypesSingular::new();
    message.set_double_field(19f64);
    message.set_float_field(20f32);
    message.set_int32_field(21);
    message.set_int64_field(-22);
    message.set_uint32_field(23);
    message.set_uint64_field(24);
    message.set_sint32_field(-25);
    message.set_sint64_field(26);
    message.set_fixed32_field(27);
    message.set_fixed64_field(28);
    message.set_sfixed32_field(-29);
    message.set_sfixed64_field(30);
    message.set_bool_field(true);
    message.set_string_field("thirty two".to_string());
    message.set_bytes_field([33u8, 34].to_vec());
    message.set_enum_field(TestEnumDescriptor::BLUE);
    test_serialize_deserialize_no_hex(&message);
}

#[test]
fn test_types_repeated() {
    let mut message = TestTypesRepeated::new();
    message.set_double_field([19f64, 20f64].to_vec());
    message.set_float_field([20f32].to_vec());
    message.set_int32_field([21i32, -22, 23].to_vec());
    message.set_int64_field([22i64].to_vec());
    message.set_uint32_field([23u32, 24].to_vec());
    message.set_uint64_field([24u64].to_vec());
    message.set_sint32_field([25i32].to_vec());
    message.set_sint64_field([26i64, -27].to_vec());
    message.set_fixed32_field([27u32].to_vec());
    message.set_fixed64_field([28u64].to_vec());
    message.set_sfixed32_field([29i32, -30].to_vec());
    message.set_sfixed64_field([30i64].to_vec());
    message.set_bool_field([true, true].to_vec());
    message.set_string_field(RepeatedField::from_slice(
        &["thirty two".to_string(), "thirty three".to_string()],
    ));
    message.set_bytes_field(RepeatedField::from_slice(
        &[[33u8, 34].to_vec(), [35u8].to_vec()],
    ));
    message.set_enum_field(
        [TestEnumDescriptor::BLUE, TestEnumDescriptor::GREEN].to_vec(),
    );
    test_serialize_deserialize_no_hex(&message);
}

#[test]
fn test_types_repeated_packed() {
    let mut message = TestTypesRepeatedPacked::new();
    message.set_double_field([19f64, 20f64].to_vec());
    message.set_float_field([20f32].to_vec());
    message.set_int32_field([21i32, -22, 23].to_vec());
    message.set_int64_field([22i64].to_vec());
    message.set_uint32_field([23u32, 24].to_vec());
    message.set_uint64_field([24u64].to_vec());
    message.set_sint32_field([-25i32, 26].to_vec());
    message.set_sint64_field([26i64, -27, 28].to_vec());
    message.set_fixed32_field([27u32].to_vec());
    message.set_fixed64_field([28u64].to_vec());
    message.set_sfixed32_field([29i32, -30].to_vec());
    message.set_sfixed64_field([30i64].to_vec());
    message.set_bool_field([true, true].to_vec());
    message.set_string_field(RepeatedField::from_slice(
        &["thirty two".to_string(), "thirty three".to_string()],
    ));
    message.set_bytes_field(RepeatedField::from_slice(
        &[[33u8, 34].to_vec(), [35u8].to_vec()],
    ));
    message.set_enum_field(
        [TestEnumDescriptor::BLUE, TestEnumDescriptor::GREEN].to_vec(),
    );
    test_serialize_deserialize_no_hex(&message);
}

#[test]
fn test_file_descriptor_proto() {
    let p: &'static descriptor::FileDescriptorProto = file_descriptor_proto();
    assert!(p.has_name());
    assert_eq!("test_basic_pb.proto", p.get_name());
}

#[test]
fn test_default_instance() {
    let d = TestDefaultInstance::new();
    assert_eq!("", d.get_field().get_s());
}

#[test]
fn test_message_descriptor() {
    assert_eq!("TestDescriptor", TestDescriptor::new().descriptor().name());

    let d = reflect::MessageDescriptor::for_type::<TestDescriptor>();
    assert_eq!("TestDescriptor", d.name());
    assert_eq!("basic.TestDescriptor", d.full_name());

    let mut t = TestDescriptor::new();
    t.set_stuff(55);

    let field = d.field_by_name("stuff");
    assert_eq!(55, field.get_i32(&t));
}

#[test]
fn test_enum_descriptor() {
    let d = TestEnumDescriptor::RED.enum_descriptor();
    assert_eq!("TestEnumDescriptor", d.name());
    assert_eq!(
        "TestEnumDescriptor",
        reflect::EnumDescriptor::for_type::<TestEnumDescriptor>().name()
    );
    assert_eq!("GREEN", d.value_by_name("GREEN").name());
}

#[test]
fn test_invalid_tag() {
    // 01 is invalid tag, because field number for that tag would be 0
    let bytes = decode_hex("01 02 03");
    let r = parse_from_bytes::<TestInvalidTag>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_no_varint() {
    // 08 is valid tag that should be followed by varint
    let bytes = decode_hex("08");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_middle_of_varint() {
    // 08 is field 1, wire type varint
    // 96 is non-final byte of varint
    let bytes = decode_hex("08 96");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_middle_of_length_delimited() {
    // 0a is field 1, wire type length delimited
    // 03 is length 3
    let bytes = decode_hex("0a 03 10");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_repeated_packed() {
    // 12 is field 2, wire type length delimited
    // 04 is length 4
    let bytes = decode_hex("12 04 10 20");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_bug_sint() {
    {
        let mut x = TestBugSint::new();
        x.set_s32(-1);
        test_serialize_deserialize("08 01", &x);
    }
    {
        let mut x = TestBugSint::new();
        x.set_s64(-2);
        test_serialize_deserialize("10 03", &x);
    }
}
<commit_msg>Smoke test for #264<commit_after>use protobuf::hex::decode_hex;

use protobuf::*;

use test::*;

use super::test_basic_pb::*;

#[test]
fn test1() {
    let mut test1 = Test1::new();
    test1.set_a(150);
    test_serialize_deserialize("08 96 01", &test1);
}

#[test]
fn test2() {
    let mut test2 = Test2::new();
    test2.set_b("testing".to_string());
    test_serialize_deserialize("12 07 74 65 73 74 69 6e 67", &test2);
}

#[test]
fn test3() {
    let mut test1 = Test1::new();
    test1.set_a(150);
    let mut test3 = Test3::new();
    test3.set_c(test1);
    test_serialize_deserialize("1a 03 08 96 01", &test3);
}

#[test]
fn test4() {
    let mut test4 = Test4::new();
    test4.set_d([3i32, 270, 86942].to_vec());
    test_serialize_deserialize("22 06 03 8E 02 9E A7 05", &test4);
}

#[test]
fn test_recursion_limit() {
    let mut test = TestRecursion::new();
    for _ in 0..10 {
        let mut t = TestRecursion::new();
        t.mut_children().push(test);
        test = t;
    }

    let bytes = test.write_to_bytes().unwrap();
    let cases = vec![
        (None, false),
        (Some(9), true),
        (Some(10), false),
    ];

    for (limit, has_err) in cases {
        let mut is = CodedInputStream::from_bytes(&bytes);
        if let Some(limit) = limit {
            is.set_recursion_limit(limit);
        }
        let mut t = TestRecursion::new();
        let res = t.merge_from(&mut is);
        assert_eq!(res.is_err(), has_err, "limit: {:?}", limit);
        if !has_err {
            assert_eq!(t, test, "limit: {:?}", limit);
        }
    }
}

#[test]
fn test_read_unpacked_expect_packed() {
    let mut test_packed_unpacked = TestPackedUnpacked::new();
    test_packed_unpacked.set_packed(Vec::new());
    test_packed_unpacked.set_unpacked([17i32, 1000].to_vec());
    test_deserialize("20 11 20 e8 07", &test_packed_unpacked);
}

#[test]
fn test_read_packed_expect_unpacked() {
    let mut test_packed_unpacked = TestPackedUnpacked::new();
    test_packed_unpacked.set_packed([17i32, 1000].to_vec());
    test_packed_unpacked.set_unpacked(Vec::new());
    test_deserialize("2a 03 11 e8 07", &test_packed_unpacked);
}

#[test]
fn test_end_by_negative_int() {
    // added following https://github.com/stepancheg/rust-protobuf/pull/209
    let mut test = Test1::new();
    test.set_a(-1);
    test_serialize_deserialize("08 ff ff ff ff ff ff ff ff ff 01", &test);
}

#[test]
fn test_empty() {
    test_serialize_deserialize("", &TestEmpty::new());
}

#[test]
fn test_read_junk() {
    assert!(parse_from_bytes::<Test1>(&decode_hex("00")).is_err());
}

#[test]
fn test_unknown_fields_length_delimited() {
    let mut message = TestUnknownFields::new();
    message.set_a(150);
    message
        .mut_unknown_fields()
        .add_length_delimited(4, [0x10u8, 0x20, 0x30].to_vec());
    test_serialize_deserialize("08 96 01 22 03 10 20 30", &message);
}

#[test]
fn test_unknown_fields_fixed32() {
    let mut message = TestUnknownFields::new();
    message.set_a(150);
    message.mut_unknown_fields().add_fixed32(4, 0x01020304);
    message.mut_unknown_fields().add_fixed32(4, 0xA1A2A3A4);
    test_serialize_deserialize("08 96 01 25 04 03 02 01 25 A4 A3 A2 A1", &message);
}

#[test]
fn test_types_singular() {
    let mut message = TestTypesSingular::new();
    message.set_double_field(19f64);
    message.set_float_field(20f32);
    message.set_int32_field(21);
    message.set_int64_field(-22);
    message.set_uint32_field(23);
    message.set_uint64_field(24);
    message.set_sint32_field(-25);
    message.set_sint64_field(26);
    message.set_fixed32_field(27);
    message.set_fixed64_field(28);
    message.set_sfixed32_field(-29);
    message.set_sfixed64_field(30);
    message.set_bool_field(true);
    message.set_string_field("thirty two".to_string());
    message.set_bytes_field([33u8, 34].to_vec());
    message.set_enum_field(TestEnumDescriptor::BLUE);
    test_serialize_deserialize_no_hex(&message);
}

#[test]
fn test_types_repeated() {
    let mut message = TestTypesRepeated::new();
    message.set_double_field([19f64, 20f64].to_vec());
    message.set_float_field([20f32].to_vec());
    message.set_int32_field([21i32, -22, 23].to_vec());
    message.set_int64_field([22i64].to_vec());
    message.set_uint32_field([23u32, 24].to_vec());
    message.set_uint64_field([24u64].to_vec());
    message.set_sint32_field([25i32].to_vec());
    message.set_sint64_field([26i64, -27].to_vec());
    message.set_fixed32_field([27u32].to_vec());
    message.set_fixed64_field([28u64].to_vec());
    message.set_sfixed32_field([29i32, -30].to_vec());
    message.set_sfixed64_field([30i64].to_vec());
    message.set_bool_field([true, true].to_vec());
    message.set_string_field(RepeatedField::from_slice(
        &["thirty two".to_string(), "thirty three".to_string()],
    ));
    message.set_bytes_field(RepeatedField::from_slice(
        &[[33u8, 34].to_vec(), [35u8].to_vec()],
    ));
    message.set_enum_field(
        [TestEnumDescriptor::BLUE, TestEnumDescriptor::GREEN].to_vec(),
    );
    test_serialize_deserialize_no_hex(&message);
}

#[test]
fn test_types_repeated_packed() {
    let mut message = TestTypesRepeatedPacked::new();
    message.set_double_field([19f64, 20f64].to_vec());
    message.set_float_field([20f32].to_vec());
    message.set_int32_field([21i32, -22, 23].to_vec());
    message.set_int64_field([22i64].to_vec());
    message.set_uint32_field([23u32, 24].to_vec());
    message.set_uint64_field([24u64].to_vec());
    message.set_sint32_field([-25i32, 26].to_vec());
    message.set_sint64_field([26i64, -27, 28].to_vec());
    message.set_fixed32_field([27u32].to_vec());
    message.set_fixed64_field([28u64].to_vec());
    message.set_sfixed32_field([29i32, -30].to_vec());
    message.set_sfixed64_field([30i64].to_vec());
    message.set_bool_field([true, true].to_vec());
    message.set_string_field(RepeatedField::from_slice(
        &["thirty two".to_string(), "thirty three".to_string()],
    ));
    message.set_bytes_field(RepeatedField::from_slice(
        &[[33u8, 34].to_vec(), [35u8].to_vec()],
    ));
    message.set_enum_field(
        [TestEnumDescriptor::BLUE, TestEnumDescriptor::GREEN].to_vec(),
    );
    test_serialize_deserialize_no_hex(&message);
}

#[test]
fn test_file_descriptor_proto() {
    let p: &'static descriptor::FileDescriptorProto = file_descriptor_proto();
    assert!(p.has_name());
    assert_eq!("test_basic_pb.proto", p.get_name());
}

#[test]
fn test_default_instance() {
    let d = TestDefaultInstance::new();
    assert_eq!("", d.get_field().get_s());
}

#[test]
fn test_message_descriptor() {
    assert_eq!("TestDescriptor", TestDescriptor::new().descriptor().name());

    let d = reflect::MessageDescriptor::for_type::<TestDescriptor>();
    assert_eq!("TestDescriptor", d.name());
    assert_eq!("basic.TestDescriptor", d.full_name());

    let mut t = TestDescriptor::new();
    t.set_stuff(55);

    let field = d.field_by_name("stuff");
    assert_eq!(55, field.get_i32(&t));
}

#[test]
fn test_enum_descriptor() {
    let d = TestEnumDescriptor::RED.enum_descriptor();
    assert_eq!("TestEnumDescriptor", d.name());
    assert_eq!(
        "TestEnumDescriptor",
        reflect::EnumDescriptor::for_type::<TestEnumDescriptor>().name()
    );
    assert_eq!("GREEN", d.value_by_name("GREEN").name());
}

#[test]
fn test_invalid_tag() {
    // 01 is invalid tag, because field number for that tag would be 0
    let bytes = decode_hex("01 02 03");
    let r = parse_from_bytes::<TestInvalidTag>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_no_varint() {
    // 08 is valid tag that should be followed by varint
    let bytes = decode_hex("08");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_middle_of_varint() {
    // 08 is field 1, wire type varint
    // 96 is non-final byte of varint
    let bytes = decode_hex("08 96");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_middle_of_length_delimited() {
    // 0a is field 1, wire type length delimited
    // 03 is length 3
    let bytes = decode_hex("0a 03 10");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_truncated_repeated_packed() {
    // 12 is field 2, wire type length delimited
    // 04 is length 4
    let bytes = decode_hex("12 04 10 20");
    let r = parse_from_bytes::<TestTruncated>(&bytes);
    assert!(r.is_err());
}

#[test]
fn test_bug_sint() {
    {
        let mut x = TestBugSint::new();
        x.set_s32(-1);
        test_serialize_deserialize("08 01", &x);
    }
    {
        let mut x = TestBugSint::new();
        x.set_s64(-2);
        test_serialize_deserialize("10 03", &x);
    }
}

/// Smoke test which validates that read from the network doesn't block
#[test]
fn test_parse_length_delimited_from_network_smoke() {
    use std::net;
    use std::thread;
    use std::io::Write;

    let listener = net::TcpListener::bind(("127.0.0.1", 0)).expect("bind");
    let addr = listener.local_addr().expect("local_addr");
    thread::spawn(move || {
        let mut test1 = Test1::new();
        test1.set_a(10);
        let bytes = test1.write_length_delimited_to_bytes().expect("bytes");

        let mut stream = listener.accept().expect("accept").0;
        stream.write(&bytes).expect("write");
    });

    let mut tcp_stream = net::TcpStream::connect(addr).expect("connect");
    let test1: Test1 = parse_length_delimited_from_reader(&mut tcp_stream).expect("parse...");
    assert_eq!(10, test1.get_a());
}
<|endoftext|>


<commit_before>#![feature(proc_macro, plugin, custom_attribute, custom_derive, plugin)]
#![plugin(serde_derive)]

extern crate tin_can_telephone as tct;

use std::net::{StdTcpStream, SocketAddr};
use std::io::{Read, Write};

#[test]
fn login() {
    let addr = "127.0.0.1:3000".to_string().parse::<SocketAddr>().unwrap();

    let mut tcp_a = match StdTcpStream::connect(&addr) {
        Ok(stream) => stream,
        Err(_) => panic!("Error, server not available, \
                         try running 'cargo run --example server'"),
    };

    let mut tcp_b = match StdTcpStream::connect(&addr) {
        Ok(stream) => stream,
        Err(_) => panic!("Error, server not available, \
                         try running 'cargo run --example server'"),
    };

    let login_a = "\"LoginCredentials\"{\"user\":\"login_a\"}\n".as_bytes();
    let login_b = "\"LoginCredentials\"{\"user\":\"login_b\"}\n".as_bytes();

    tcp_a.write(login_a);
    tcp_a.flush().unwrap();
    tcp_b.write(login_b);
    tcp_b.flush().unwrap();

    println!("Verify logins via server log, this point means succesful connection");
}

<commit_msg>got rid of warnings<commit_after>#![feature(proc_macro, plugin, custom_attribute, custom_derive, plugin)]
#![plugin(serde_derive)]

extern crate tin_can_telephone as tct;

use std::net::{TcpStream as StdTcpStream, SocketAddr};
use std::io::{
    //Read,
    Write};

#[test]
fn login() {
    let addr = "127.0.0.1:3000".to_string().parse::<SocketAddr>().unwrap();

    let mut tcp_a = match StdTcpStream::connect(&addr) {
        Ok(stream) => stream,
        Err(_) => panic!("Error, server not available, \
                         try running 'cargo run --example server'"),
    };

    let mut tcp_b = match StdTcpStream::connect(&addr) {
        Ok(stream) => stream,
        Err(_) => panic!("Error, server not available, \
                         try running 'cargo run --example server'"),
    };

    let login_a = "\"LoginCredentials\"{\"user\":\"login_a\"}\n".as_bytes();
    let login_b = "\"LoginCredentials\"{\"user\":\"login_b\"}\n".as_bytes();

    tcp_a.write(login_a).unwrap();
    tcp_a.flush().unwrap();
    tcp_b.write(login_b).unwrap();
    tcp_b.flush().unwrap();

    println!("Verify logins via server log, this point means succesful connection");
}

<|endoftext|>


<commit_before>extern crate easystring;

#[cfg(test)]
mod content {
    mod index {
        use easystring::Content;

        #[test]
        fn slice() {
            let content = Content::from("abcde");
            assert_eq!(content, "abcde");
        }
    }

    mod compare {
        use std::ffi::{CString, OsStr, OsString};
        use std::path::{Path, PathBuf};
        use easystring::Content;

        #[test]
        fn with_str() {
            let conent = Content::from("12345");
            assert_eq!(conent, "12345");
        }

        #[test]
        fn with_string() {
            let conent = Content::from("12345");
            let string = String::from("12345");
            assert_eq!(conent, string);
        }

        #[test]
        fn with_osstr() {
            let conent = Content::from("12345");
            let osstr = OsStr::new("12345");
            assert_eq!(conent, osstr);
        }

        #[test]
        fn with_osstring() {
            let content = Content::from("12345");
            let osstring = OsString::from("12345");
            assert_eq!(content, osstring);
        }

        #[test]
        fn with_cstr() {
            let content = Content::from("12345");
            let cstring = CString::new(b"12345".to_vec()).unwrap();
            let cstr = cstring.as_ref();
            assert_eq!(content, cstr);
        }

        #[test]
        fn with_cstring() {
            let content = Content::from("12345");
            let cstring = CString::new(b"12345".to_vec()).unwrap();
            assert_eq!(content, cstring);
        }

        #[test]
        fn with_path() {
            let conent = Content::from("12345");
            let path = Path::new("12345");
            assert_eq!(conent, path);
        }

        #[test]
        fn with_pathbuf() {
            let conent = Content::from("12345");
            let pathbuf = PathBuf::from("12345");
            assert_eq!(conent, pathbuf);
        }
    }
}
<commit_msg>Add another Index test<commit_after>extern crate easystring;

#[cfg(test)]
mod content {
    mod index {
        use easystring::Content;

        #[test]
        fn range_full() {
            let content = Content::from("abcde");
            assert_eq!(&content[..], "abcde");
        }

        #[test]
        fn range() {
            let content = Content::from("abcde");
            assert_eq!(&content[1..3], "bc");
        }
    }

    mod compare {
        use std::ffi::{CString, OsStr, OsString};
        use std::path::{Path, PathBuf};
        use easystring::Content;

        #[test]
        fn with_str() {
            let conent = Content::from("12345");
            assert_eq!(conent, "12345");
        }

        #[test]
        fn with_string() {
            let conent = Content::from("12345");
            let string = String::from("12345");
            assert_eq!(conent, string);
        }

        #[test]
        fn with_osstr() {
            let conent = Content::from("12345");
            let osstr = OsStr::new("12345");
            assert_eq!(conent, osstr);
        }

        #[test]
        fn with_osstring() {
            let content = Content::from("12345");
            let osstring = OsString::from("12345");
            assert_eq!(content, osstring);
        }

        #[test]
        fn with_cstr() {
            let content = Content::from("12345");
            let cstring = CString::new(b"12345".to_vec()).unwrap();
            let cstr = cstring.as_ref();
            assert_eq!(content, cstr);
        }

        #[test]
        fn with_cstring() {
            let content = Content::from("12345");
            let cstring = CString::new(b"12345".to_vec()).unwrap();
            assert_eq!(content, cstring);
        }

        #[test]
        fn with_path() {
            let conent = Content::from("12345");
            let path = Path::new("12345");
            assert_eq!(conent, path);
        }

        #[test]
        fn with_pathbuf() {
            let conent = Content::from("12345");
            let pathbuf = PathBuf::from("12345");
            assert_eq!(conent, pathbuf);
        }
    }
}
<|endoftext|>