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

/// External linking is a complex implementation to be able to serve a clean and easy-to-use
/// interface.
///
/// Internally, there are no such things as "external links" (plural). Each Entry in the store can
/// only have _one_ external link.
///
/// This library does the following therefor: It allows you to have several external links with one
/// entry, which are internally one file in the store for each link, linked with "internal
/// linking".
///
/// This helps us greatly with deduplication of URLs.
///

use std::ops::DerefMut;
use std::collections::BTreeMap;

use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagutil::debug_result::*;

use error::LinkError as LE;
use error::LinkErrorKind as LEK;
use error::MapErrInto;
use result::Result;
use internal::InternalLinker;
use module_path::ModuleEntryPath;

use toml::Value;
use url::Url;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

/// "Link" Type, just an abstraction over `FileLockEntry` to have some convenience internally.
pub struct Link<'a> {
    link: FileLockEntry<'a>
}

impl<'a> Link<'a> {

    pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
        Link { link: fle }
    }

    /// Get a link Url object from a `FileLockEntry`, ignore errors.
    fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
        file.get_header()
            .read("imag.content.url")
            .ok()
            .and_then(|opt| match opt {
                Some(Value::String(s)) => {
                    debug!("Found url, parsing: {:?}", s);
                    Url::parse(&s[..]).ok()
                },
                _ => None
            })
    }

    pub fn get_url(&self) -> Result<Option<Url>> {
        let opt = self.link
            .get_header()
            .read("imag.content.url");

        match opt {
            Ok(Some(Value::String(s))) => {
                Url::parse(&s[..])
                     .map(Some)
                     .map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
            },
            Ok(None) => Ok(None),
            _ => Err(LE::new(LEK::EntryHeaderReadError, None))
        }
    }

}

pub trait ExternalLinker : InternalLinker {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>>;

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

}

pub mod iter {
    //! Iterator helpers for external linking stuff
    //!
    //! Contains also helpers to filter iterators for external/internal links
    //!

    use libimagutil::debug_result::*;
    use libimagstore::store::Store;

    use internal::Link;
    use internal::iter::LinkIter;
    use error::LinkErrorKind as LEK;
    use error::MapErrInto;
    use result::Result;

    use url::Url;

    /// Helper for building `OnlyExternalIter` and `NoExternalIter`
    ///
    /// The boolean value defines, how to interpret the `is_external_link_storeid()` return value
    /// (here as "pred"):
    ///
    ///     pred | bool | xor | take?
    ///     ---- | ---- | --- | ----
    ///        0 |    0 |   0 |   1
    ///        0 |    1 |   1 |   0
    ///        1 |    1 |   1 |   0
    ///        1 |    1 |   0 |   1
    ///
    /// If `bool` says "take if return value is false", we take the element if the `pred` returns
    /// false... and so on.
    ///
    /// As we can see, the operator between these two operants is `!(a ^ b)`.
    struct ExternalFilterIter(LinkIter, bool);

    impl Iterator for ExternalFilterIter {
        type Item = Link;

        fn next(&mut self) -> Option<Self::Item> {
            use super::is_external_link_storeid;

            while let Some(elem) = self.0.next() {
                if !(self.1 ^ is_external_link_storeid(&elem)) {
                    return Some(elem);
                }
            }
            None
        }
    }

    pub struct OnlyExternalIter(ExternalFilterIter);

    impl OnlyExternalIter {
        pub fn new(li: LinkIter) -> OnlyExternalIter {
            OnlyExternalIter(ExternalFilterIter(li, true))
        }

        pub fn urls<'a>(self, store: &'a Store) -> UrlIter<'a> {
            UrlIter(self, store)
        }
    }

    impl Iterator for OnlyExternalIter {
        type Item = Link;

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

    pub struct NoExternalIter(ExternalFilterIter);

    impl NoExternalIter {
        pub fn new(li: LinkIter) -> NoExternalIter {
            NoExternalIter(ExternalFilterIter(li, false))
        }
    }

    impl Iterator for NoExternalIter {
        type Item = Link;

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

    pub trait OnlyExternalLinks : Sized {
        fn only_external_links(self) -> OnlyExternalIter ;

        fn no_internal_links(self) -> OnlyExternalIter {
            self.only_external_links()
        }
    }

    impl OnlyExternalLinks for LinkIter {
        fn only_external_links(self) -> OnlyExternalIter {
            OnlyExternalIter::new(self)
        }
    }

    pub trait OnlyInternalLinks : Sized {
        fn only_internal_links(self) -> NoExternalIter;

        fn no_external_links(self) -> NoExternalIter {
            self.only_internal_links()
        }
    }

    impl OnlyInternalLinks for LinkIter {
        fn only_internal_links(self) -> NoExternalIter {
            NoExternalIter::new(self)
        }
    }

    pub struct UrlIter<'a>(OnlyExternalIter, &'a Store);

    impl<'a> Iterator for UrlIter<'a> {
        type Item = Result<Url>;

        fn next(&mut self) -> Option<Self::Item> {
            use super::get_external_link_from_file;

            self.0
                .next()
                .map(|id| {
                    debug!("Retrieving entry for id: '{:?}'", id);
                    self.1
                        .retrieve(id.clone())
                        .map_err_into(LEK::StoreReadError)
                        .map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
                        .and_then(|f| {
                            debug!("Store::retrieve({:?}) succeeded", id);
                            debug!("getting external link from file now");
                            get_external_link_from_file(&f)
                                .map_dbg_err(|e| format!("URL -> Err = {:?}", e))
                        })
                })
        }

    }

}

/// Check whether the StoreId starts with `/link/external/`
pub fn is_external_link_storeid(id: &StoreId) -> bool {
    debug!("Checking whether this is a 'links/external/': '{:?}'", id);
    id.local().starts_with("links/external")
}

fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
    Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
        .ok_or(LE::new(LEK::StoreReadError, None))
}

/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl ExternalLinker for Entry {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>> {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
            .map(|iter| {
                debug!("Getting external links");
                iter.filter(|l| is_external_link_storeid(l))
                    .map(|id| {
                        debug!("Retrieving entry for id: '{:?}'", id);
                        match store.retrieve(id.clone()) {
                            Ok(f) => {
                                debug!("Store::retrieve({:?}) succeeded", id);
                                debug!("getting external link from file now");
                                get_external_link_from_file(&f)
                                    .map_err(|e| { debug!("URL -> Err = {:?}", e); e })
                            },
                            Err(e) => {
                                debug!("Retrieving entry for id: '{:?}' failed", id);
                                Err(LE::new(LEK::StoreReadError, Some(Box::new(e))))
                            }
                        }
                    })
                    .filter_map(|x| x.ok()) // TODO: Do not ignore error here
                    .collect()
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
        // Take all the links, generate a SHA sum out of each one, filter out the already existing
        // store entries and store the other URIs in the header of one FileLockEntry each, in
        // the path /link/external/<SHA of the URL>

        debug!("Iterating {} links = {:?}", links.len(), links);
        for link in links { // for all links
            let hash = {
                let mut s = Sha1::new();
                s.input_str(&link.as_str()[..]);
                s.result_str()
            };
            let file_id = try!(
                ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
                    .map_err_into(LEK::StoreWriteError)
                    .map_dbg_err(|_| {
                        format!("Failed to build StoreId for this hash '{:?}'", hash)
                    })
                );

            debug!("Link    = '{:?}'", link);
            debug!("Hash    = '{:?}'", hash);
            debug!("StoreId = '{:?}'", file_id);

            // retrieve the file from the store, which implicitely creates the entry if it does not
            // exist
            let mut file = try!(store
                .retrieve(file_id.clone())
                .map_err_into(LEK::StoreWriteError)
                .map_dbg_err(|_| {
                    format!("Failed to create or retrieve an file for this link '{:?}'", link)
                }));

            debug!("Generating header content!");
            {
                let mut hdr = file.deref_mut().get_header_mut();

                let mut table = match hdr.read("imag.content") {
                    Ok(Some(Value::Table(table))) => table,
                    Ok(Some(_)) => {
                        warn!("There is a value at 'imag.content' which is not a table.");
                        warn!("Going to override this value");
                        BTreeMap::new()
                    },
                    Ok(None) => BTreeMap::new(),
                    Err(e)   => return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e)))),
                };

                let v = Value::String(link.into_string());

                debug!("setting URL = '{:?}", v);
                table.insert(String::from("url"), v);

                if let Err(e) = hdr.set("imag.content", Value::Table(table)) {
                    return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
                } else {
                    debug!("Setting URL worked");
                }
            }

            // then add an internal link to the new file or return an error if this fails
            if let Err(e) = self.add_internal_link(file.deref_mut()) {
                debug!("Error adding internal link");
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
            }
        }
        debug!("Ready iterating");
        Ok(())
    }

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, add this one, save them
        debug!("Getting links");
        self.get_external_links(store)
            .and_then(|mut links| {
                debug!("Adding link = '{:?}' to links = {:?}", link, links);
                links.push(link);
                debug!("Setting {} links = {:?}", links.len(), links);
                self.set_external_links(store, links)
            })
    }

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, remove this one, save them
        self.get_external_links(store)
            .and_then(|links| {
                debug!("Removing link = '{:?}' from links = {:?}", link, links);
                let links = links.into_iter()
                    .filter(|l| l.as_str() != link.as_str())
                    .collect();
                self.set_external_links(store, links)
            })
    }

}

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

/// External linking is a complex implementation to be able to serve a clean and easy-to-use
/// interface.
///
/// Internally, there are no such things as "external links" (plural). Each Entry in the store can
/// only have _one_ external link.
///
/// This library does the following therefor: It allows you to have several external links with one
/// entry, which are internally one file in the store for each link, linked with "internal
/// linking".
///
/// This helps us greatly with deduplication of URLs.
///

use std::ops::DerefMut;
use std::collections::BTreeMap;

use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagutil::debug_result::*;

use error::LinkError as LE;
use error::LinkErrorKind as LEK;
use error::MapErrInto;
use result::Result;
use internal::InternalLinker;
use module_path::ModuleEntryPath;

use toml::Value;
use url::Url;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

/// "Link" Type, just an abstraction over `FileLockEntry` to have some convenience internally.
pub struct Link<'a> {
    link: FileLockEntry<'a>
}

impl<'a> Link<'a> {

    pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
        Link { link: fle }
    }

    /// Get a link Url object from a `FileLockEntry`, ignore errors.
    fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
        file.get_header()
            .read("imag.content.url")
            .ok()
            .and_then(|opt| match opt {
                Some(Value::String(s)) => {
                    debug!("Found url, parsing: {:?}", s);
                    Url::parse(&s[..]).ok()
                },
                _ => None
            })
    }

    pub fn get_url(&self) -> Result<Option<Url>> {
        let opt = self.link
            .get_header()
            .read("imag.content.url");

        match opt {
            Ok(Some(Value::String(s))) => {
                Url::parse(&s[..])
                     .map(Some)
                     .map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
            },
            Ok(None) => Ok(None),
            _ => Err(LE::new(LEK::EntryHeaderReadError, None))
        }
    }

}

pub trait ExternalLinker : InternalLinker {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>>;

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

}

pub mod iter {
    //! Iterator helpers for external linking stuff
    //!
    //! Contains also helpers to filter iterators for external/internal links
    //!

    use libimagutil::debug_result::*;
    use libimagstore::store::Store;

    use internal::Link;
    use internal::iter::LinkIter;
    use error::LinkErrorKind as LEK;
    use error::MapErrInto;
    use result::Result;

    use url::Url;

    /// Helper for building `OnlyExternalIter` and `NoExternalIter`
    ///
    /// The boolean value defines, how to interpret the `is_external_link_storeid()` return value
    /// (here as "pred"):
    ///
    ///     pred | bool | xor | take?
    ///     ---- | ---- | --- | ----
    ///        0 |    0 |   0 |   1
    ///        0 |    1 |   1 |   0
    ///        1 |    1 |   1 |   0
    ///        1 |    1 |   0 |   1
    ///
    /// If `bool` says "take if return value is false", we take the element if the `pred` returns
    /// false... and so on.
    ///
    /// As we can see, the operator between these two operants is `!(a ^ b)`.
    pub struct ExternalFilterIter(LinkIter, bool);

    impl Iterator for ExternalFilterIter {
        type Item = Link;

        fn next(&mut self) -> Option<Self::Item> {
            use super::is_external_link_storeid;

            while let Some(elem) = self.0.next() {
                if !(self.1 ^ is_external_link_storeid(&elem)) {
                    return Some(elem);
                }
            }
            None
        }
    }

    /// Helper trait to be implemented on `LinkIter` to select or deselect all external links
    ///
    /// # See also
    ///
    /// Also see `OnlyExternalIter` and `NoExternalIter` and the helper traits/functions
    /// `OnlyInteralLinks`/`only_internal_links()` and `OnlyExternalLinks`/`only_external_links()`.
    pub trait SelectExternal {
        fn select_external_links(self, b: bool) -> ExternalFilterIter;
    }

    impl SelectExternal for LinkIter {
        fn select_external_links(self, b: bool) -> ExternalFilterIter {
            ExternalFilterIter(self, b)
        }
    }

    pub struct OnlyExternalIter(ExternalFilterIter);

    impl OnlyExternalIter {
        pub fn new(li: LinkIter) -> OnlyExternalIter {
            OnlyExternalIter(ExternalFilterIter(li, true))
        }

        pub fn urls<'a>(self, store: &'a Store) -> UrlIter<'a> {
            UrlIter(self, store)
        }
    }

    impl Iterator for OnlyExternalIter {
        type Item = Link;

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

    pub struct NoExternalIter(ExternalFilterIter);

    impl NoExternalIter {
        pub fn new(li: LinkIter) -> NoExternalIter {
            NoExternalIter(ExternalFilterIter(li, false))
        }
    }

    impl Iterator for NoExternalIter {
        type Item = Link;

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

    pub trait OnlyExternalLinks : Sized {
        fn only_external_links(self) -> OnlyExternalIter ;

        fn no_internal_links(self) -> OnlyExternalIter {
            self.only_external_links()
        }
    }

    impl OnlyExternalLinks for LinkIter {
        fn only_external_links(self) -> OnlyExternalIter {
            OnlyExternalIter::new(self)
        }
    }

    pub trait OnlyInternalLinks : Sized {
        fn only_internal_links(self) -> NoExternalIter;

        fn no_external_links(self) -> NoExternalIter {
            self.only_internal_links()
        }
    }

    impl OnlyInternalLinks for LinkIter {
        fn only_internal_links(self) -> NoExternalIter {
            NoExternalIter::new(self)
        }
    }

    pub struct UrlIter<'a>(OnlyExternalIter, &'a Store);

    impl<'a> Iterator for UrlIter<'a> {
        type Item = Result<Url>;

        fn next(&mut self) -> Option<Self::Item> {
            use super::get_external_link_from_file;

            self.0
                .next()
                .map(|id| {
                    debug!("Retrieving entry for id: '{:?}'", id);
                    self.1
                        .retrieve(id.clone())
                        .map_err_into(LEK::StoreReadError)
                        .map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
                        .and_then(|f| {
                            debug!("Store::retrieve({:?}) succeeded", id);
                            debug!("getting external link from file now");
                            get_external_link_from_file(&f)
                                .map_dbg_err(|e| format!("URL -> Err = {:?}", e))
                        })
                })
        }

    }

}

/// Check whether the StoreId starts with `/link/external/`
pub fn is_external_link_storeid(id: &StoreId) -> bool {
    debug!("Checking whether this is a 'links/external/': '{:?}'", id);
    id.local().starts_with("links/external")
}

fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
    Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
        .ok_or(LE::new(LEK::StoreReadError, None))
}

/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl ExternalLinker for Entry {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>> {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
            .map(|iter| {
                debug!("Getting external links");
                iter.filter(|l| is_external_link_storeid(l))
                    .map(|id| {
                        debug!("Retrieving entry for id: '{:?}'", id);
                        match store.retrieve(id.clone()) {
                            Ok(f) => {
                                debug!("Store::retrieve({:?}) succeeded", id);
                                debug!("getting external link from file now");
                                get_external_link_from_file(&f)
                                    .map_err(|e| { debug!("URL -> Err = {:?}", e); e })
                            },
                            Err(e) => {
                                debug!("Retrieving entry for id: '{:?}' failed", id);
                                Err(LE::new(LEK::StoreReadError, Some(Box::new(e))))
                            }
                        }
                    })
                    .filter_map(|x| x.ok()) // TODO: Do not ignore error here
                    .collect()
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
        // Take all the links, generate a SHA sum out of each one, filter out the already existing
        // store entries and store the other URIs in the header of one FileLockEntry each, in
        // the path /link/external/<SHA of the URL>

        debug!("Iterating {} links = {:?}", links.len(), links);
        for link in links { // for all links
            let hash = {
                let mut s = Sha1::new();
                s.input_str(&link.as_str()[..]);
                s.result_str()
            };
            let file_id = try!(
                ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
                    .map_err_into(LEK::StoreWriteError)
                    .map_dbg_err(|_| {
                        format!("Failed to build StoreId for this hash '{:?}'", hash)
                    })
                );

            debug!("Link    = '{:?}'", link);
            debug!("Hash    = '{:?}'", hash);
            debug!("StoreId = '{:?}'", file_id);

            // retrieve the file from the store, which implicitely creates the entry if it does not
            // exist
            let mut file = try!(store
                .retrieve(file_id.clone())
                .map_err_into(LEK::StoreWriteError)
                .map_dbg_err(|_| {
                    format!("Failed to create or retrieve an file for this link '{:?}'", link)
                }));

            debug!("Generating header content!");
            {
                let mut hdr = file.deref_mut().get_header_mut();

                let mut table = match hdr.read("imag.content") {
                    Ok(Some(Value::Table(table))) => table,
                    Ok(Some(_)) => {
                        warn!("There is a value at 'imag.content' which is not a table.");
                        warn!("Going to override this value");
                        BTreeMap::new()
                    },
                    Ok(None) => BTreeMap::new(),
                    Err(e)   => return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e)))),
                };

                let v = Value::String(link.into_string());

                debug!("setting URL = '{:?}", v);
                table.insert(String::from("url"), v);

                if let Err(e) = hdr.set("imag.content", Value::Table(table)) {
                    return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
                } else {
                    debug!("Setting URL worked");
                }
            }

            // then add an internal link to the new file or return an error if this fails
            if let Err(e) = self.add_internal_link(file.deref_mut()) {
                debug!("Error adding internal link");
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
            }
        }
        debug!("Ready iterating");
        Ok(())
    }

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, add this one, save them
        debug!("Getting links");
        self.get_external_links(store)
            .and_then(|mut links| {
                debug!("Adding link = '{:?}' to links = {:?}", link, links);
                links.push(link);
                debug!("Setting {} links = {:?}", links.len(), links);
                self.set_external_links(store, links)
            })
    }

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, remove this one, save them
        self.get_external_links(store)
            .and_then(|links| {
                debug!("Removing link = '{:?}' from links = {:?}", link, links);
                let links = links.into_iter()
                    .filter(|l| l.as_str() != link.as_str())
                    .collect();
                self.set_external_links(store, links)
            })
    }

}

<|endoftext|>


<commit_before><commit_msg>A test that I forgot to git-add<commit_after>fn main() {
    alt @{foo: true, bar: some(10), baz: 20} {
      @{foo: true, bar: some(_), _} {}
      @{foo: false, bar: none, _} {}
    }
}
<|endoftext|>


<commit_before><commit_msg>Add the socket settings example from the README to examples<commit_after>extern crate knob;

use std::io::net::ip::IpAddr;
use knob::Settings;

fn main() {
    let mut settings = Settings::new();
    settings.set("ip", "::0.0.0.1");
    let socket: IpAddr = settings.fetch("ip").unwrap();
    assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
}
<|endoftext|>


<commit_before><commit_msg>dstrules: new example<commit_after>extern crate time;
extern crate zoneinfo;

use zoneinfo::ZoneInfo;
use std::error::Error;

fn main() {
    let regions = ZoneInfo::get_tz_locations();

    for region in regions {
        match ZoneInfo::by_tz(&region) {
            Ok(zoneinfo) => {
                println!("{}: {}", region, zoneinfo.get_dst_specifier());
            },
            Err(error) => {
                println!("{}: unable to parse: {}", region, error.description());
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example for request_open_port<commit_after>extern crate port_scanner;
use port_scanner::request_open_port;

fn main() {
    println!("Port {}", request_open_port().unwrap_or(0));
}
<|endoftext|>


<commit_before><commit_msg>Add file server example<commit_after>extern crate clap;
extern crate fibers;
extern crate futures;
extern crate miasht;
extern crate handy_async;

use std::fs;
use fibers::{Executor, ThreadPoolExecutor, Spawn};
use futures::{Future, BoxFuture};
use miasht::{Server, Status};
use miasht::builtin::servers::{SimpleHttpServer, RawConnection};
use miasht::builtin::headers::ContentLength;
use miasht::builtin::FutureExt;
use miasht::builtin::router::{Router, RouteBuilder};
use handy_async::sync_io::ReadExt;

type TcpRequest = miasht::server::Request<fibers::net::TcpStream>;

fn main() {
    let mut builder = RouteBuilder::new();
    builder.add_callback((), handle_get);
    builder.add_callback((), handle_default);
    let router = builder.finish();

    let mut executor = ThreadPoolExecutor::new().unwrap();
    let addr = "0.0.0.0:3000".parse().unwrap();
    let server = SimpleHttpServer::new(router, route);
    let server = server.start(addr, executor.handle());
    let monitor = executor.spawn_monitor(server.join());
    let result = executor.run_fiber(monitor).unwrap();
    println!("HTTP Server shutdown: {:?}", result);
}

fn route(router: Router<fibers::net::TcpStream>, connection: RawConnection) -> BoxFuture<(), ()> {
    connection.read_request()
        .map_err(|e| {
            println!("Error: {:?}", e);
            ()
        })
        .and_then(move |request| router.handle_request(request))
        .boxed()
}

fn handle_default(_: (), request: TcpRequest) -> Result<BoxFuture<(), ()>, TcpRequest> {
    Ok(request.finish()
        .build_response(Status::NotFound)
        .finish()
        .write_all_bytes("Not Found\n")
        .then(|_| Ok(()))
        .boxed())
}

fn handle_get(_: (), request: TcpRequest) -> Result<BoxFuture<(), ()>, TcpRequest> {
    if miasht::Method::Get != request.method() {
        return Err(request);
    }
    println!("# GET: {}", &request.path()[1..]);
    Ok(match fs::File::open(&request.path()[1..])
        .and_then(|mut f| ReadExt::read_all_bytes(&mut f)) {
        Err(e) => {
            let reason = e.to_string();
            let mut resp = request.finish().build_response(Status::NotFound);
            resp.add_header(&ContentLength(reason.len() as u64));
            resp.finish().write_all_bytes(reason).then(|_| Ok(())).boxed()
        }
        Ok(bytes) => {
            let mut resp = request.finish().build_response(Status::Ok);
            resp.add_header(&ContentLength(bytes.len() as u64));
            resp.finish().write_all_bytes(bytes).then(|_| Ok(())).boxed()
        }
    })
}
<|endoftext|>


<commit_before>fn split<'a, T>(list: &'a [T], n: uint) -> (&'a [T], &'a [T]) {
    (list.slice_to(n), list.slice_from(n))
}

fn main() {
    let list = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
    println!("{:?}", split(list, 3));
}

<commit_msg>Cleanup Problem 17<commit_after>// The author of this work hereby waives all claim of copyright (economic and
// moral) in this work and immediately places it in the public domain; it may
// be used, distorted or destroyed in any manner whatsoever without further
// attribution or notice to the creator.

//! Problem 17: Vectors: split
//!
//! Split a vector into two parts; the length of the first part is given.
//!
//! Your function could have this signature:
//! `fn split<T>(vec: &[T], n: uint) -> (&[T], &[T])`

fn split<'a, T>(vec: &'a [T], n: uint) -> (&'a [T], &'a [T]) {
    (vec.slice_to(n), vec.slice_from(n))
}

#[test]
fn split_ok() {
    let vec = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
    assert_eq!(split(vec, 3),
        (&['a', 'b', 'c'], &['d', 'e', 'f', 'g', 'h', 'i', 'j']));
}

#[test]
fn split_begin() {
    let vec = ['a', 'b', 'c', 'd', 'e'];
    assert_eq!(split(vec, 0),
        (&[], &['a', 'b', 'c', 'd', 'e']));
}

#[test]
fn split_end() {
    let vec = ['a', 'b', 'c', 'd', 'e'];
    assert_eq!(split(vec, 5),
        (&['a', 'b', 'c', 'd', 'e'], &[]));
}
<|endoftext|>


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

// compile-flags: -O -C no-prepopulate-passes

#![crate_type = "lib"]
#![feature(rustc_attrs)]

// CHECK-LABEL: @test
#[no_mangle]
#[rustc_mir] // FIXME #27840 MIR has different codegen.
pub fn test() {
    let a = 0;
    &a; // keep variable in an alloca

// CHECK: [[S_a:%[0-9]+]] = bitcast i32* %a to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_a]])

    {
        let b = &Some(a);
        &b; // keep variable in an alloca

// CHECK: [[S_b:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"** %b to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_b]])

// CHECK: [[S_tmp2:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"* %tmp2 to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_tmp2]])

// CHECK: [[E_tmp2:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"* %tmp2 to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_tmp2]])

// CHECK: [[E_b:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"** %b to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_b]])
    }

    let c = 1;
    &c; // keep variable in an alloca

// CHECK: [[S_c:%[0-9]+]] = bitcast i32* %c to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_c]])

// CHECK: [[E_c:%[0-9]+]] = bitcast i32* %c to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_c]])

// CHECK: [[E_a:%[0-9]+]] = bitcast i32* %a to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_a]])
}
<commit_msg>Fix codegen test (value names changed)<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -O -C no-prepopulate-passes

#![crate_type = "lib"]
#![feature(rustc_attrs)]

// CHECK-LABEL: @test
#[no_mangle]
#[rustc_mir] // FIXME #27840 MIR has different codegen.
pub fn test() {
    let a = 0;
    &a; // keep variable in an alloca

// CHECK: [[S_a:%[0-9]+]] = bitcast i32* %a to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_a]])

    {
        let b = &Some(a);
        &b; // keep variable in an alloca

// CHECK: [[S_b:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"** %b to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_b]])

// CHECK: [[S_local5:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"* %local5 to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_local5]])

// CHECK: [[E_local5:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"* %local5 to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_local5]])

// CHECK: [[E_b:%[0-9]+]] = bitcast %"2.std::option::Option<i32>"** %b to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_b]])
    }

    let c = 1;
    &c; // keep variable in an alloca

// CHECK: [[S_c:%[0-9]+]] = bitcast i32* %c to i8*
// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_c]])

// CHECK: [[E_c:%[0-9]+]] = bitcast i32* %c to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_c]])

// CHECK: [[E_a:%[0-9]+]] = bitcast i32* %a to i8*
// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_a]])
}
<|endoftext|>


<commit_before>use alloc::arc::Arc;

use collections::string::{String, ToString};
use collections::vec::Vec;

use core::cell::UnsafeCell;
use core::ops::DerefMut;
use core::{mem, ptr};

use common::elf::Elf;
use common::memory;

use scheduler::context::{CONTEXT_STACK_SIZE, CONTEXT_STACK_ADDR, context_switch,
context_userspace, Context, ContextMemory};

use schemes::Url;

use sync::Intex;

/// Execute an executable
pub fn execute(url: Url, mut args: Vec<String>) {
    let context_ptr: *mut Context = {
        let mut contexts = ::env().contexts.lock();
        if let Some(mut current) = contexts.current_mut() {
            current.deref_mut()
        } else {
            return
        }
    };

    Context::spawn("kexec ".to_string() + &url.string, box move || {
        if let Ok(mut resource) = url.open() {
            let mut vec: Vec<u8> = Vec::new();
            resource.read_to_end(&mut vec);

            let executable = Elf::from_data(vec.as_ptr() as usize);
            let entry = unsafe { executable.entry() };
            let mut memory = Vec::new();
            unsafe {
                for segment in executable.load_segment().iter() {
                    let virtual_address = segment.vaddr as usize;
                    let virtual_size = segment.mem_len as usize;
                    let physical_address = memory::alloc(virtual_size);

                    if physical_address > 0 {
                        // Copy progbits
                        ::memcpy(physical_address as *mut u8,
                                 (executable.data + segment.off as usize) as *const u8,
                                 segment.file_len as usize);
                        // Zero bss
                        ::memset((physical_address + segment.file_len as usize) as *mut u8,
                        0,
                        segment.mem_len as usize - segment.file_len as usize);

                        memory.push(ContextMemory {
                            physical_address: physical_address,
                            virtual_address: virtual_address,
                            virtual_size: virtual_size,
                            writeable: segment.flags & 2 == 2
                        });
                    }
                }
            }

            if entry > 0 && ! memory.is_empty() {
                args.insert(0, url.to_string());

                let mut context_args: Vec<usize> = Vec::new();
                context_args.push(0); // ENVP
                context_args.push(0); // ARGV NULL
                let mut argc = 0;
                for i in 0..args.len() {
                    let reverse_i = args.len() - i - 1;
                    if let Some(ref mut arg) = args.get_mut(reverse_i) {
                        if ! arg.ends_with('\0') {
                            arg.push('\0');
                        }
                        context_args.push(arg.as_ptr() as usize);
                        argc += 1;
                    }
                }
                context_args.push(argc);

                unsafe {
                    let _intex = Intex::static_lock();

                    let context = &mut *context_ptr;

                    context.name = url.string;

                    context.sp = context.kernel_stack + CONTEXT_STACK_SIZE - 128;

                    context.stack = Some(ContextMemory {
                        physical_address: memory::alloc(CONTEXT_STACK_SIZE),
                        virtual_address: CONTEXT_STACK_ADDR,
                        virtual_size: CONTEXT_STACK_SIZE,
                        writeable: true
                    });

                    context.args = Arc::new(UnsafeCell::new(args));
                    context.cwd = Arc::new(UnsafeCell::new((*context.cwd.get()).clone()));
                    context.memory = Arc::new(UnsafeCell::new(memory));

                    let user_sp = if let Some(ref stack) = context.stack {
                        let mut sp = stack.physical_address + stack.virtual_size - 128;
                        for arg in context_args.iter() {
                            sp -= mem::size_of::<usize>();
                            ptr::write(sp as *mut usize, *arg);
                        }
                        sp - stack.physical_address + stack.virtual_address
                    } else {
                        0
                    };

                    context.push(0x20 | 3);
                    context.push(user_sp);
                    context.push(/*1 << 9*/ 0);
                    context.push(0x18 | 3);
                    context.push(entry);
                    context.push(context_userspace as usize);
                }
            } else {
                debug!("{}: Invalid memory or entry\n", url.string);
            }
        } else {
            debug!("{}: Failed to open\n", url.string);
        }
    });

    loop {
        unsafe { context_switch(false) };
    }
}
<commit_msg>Cleanup in executor<commit_after>use alloc::arc::Arc;

use collections::string::{String, ToString};
use collections::vec::Vec;

use core::cell::UnsafeCell;
use core::ops::DerefMut;
use core::{mem, ptr};

use common::elf::Elf;
use common::memory;

use scheduler::context::{CONTEXT_STACK_SIZE, CONTEXT_STACK_ADDR, context_switch,
context_userspace, Context, ContextMemory};

use schemes::Url;

use sync::Intex;

/// Execute an executable
pub fn execute(url: Url, mut args: Vec<String>) {
    let mut context_ptr: *mut Context = 0 as *mut Context;
    let mut entry: usize = 0;

    if let Ok(mut resource) = url.open() {
        let mut vec: Vec<u8> = Vec::new();
        resource.read_to_end(&mut vec);

        let executable = Elf::from_data(vec.as_ptr() as usize);
        entry = unsafe { executable.entry() };
        let mut memory = Vec::new();
        unsafe {
            for segment in executable.load_segment().iter() {
                let virtual_address = segment.vaddr as usize;
                let virtual_size = segment.mem_len as usize;
                let physical_address = memory::alloc(virtual_size);

                if physical_address > 0 {
                    // Copy progbits
                    ::memcpy(physical_address as *mut u8,
                             (executable.data + segment.off as usize) as *const u8,
                             segment.file_len as usize);
                    // Zero bss
                    ::memset((physical_address + segment.file_len as usize) as *mut u8,
                    0,
                    segment.mem_len as usize - segment.file_len as usize);

                    memory.push(ContextMemory {
                        physical_address: physical_address,
                        virtual_address: virtual_address,
                        virtual_size: virtual_size,
                        writeable: segment.flags & 2 == 2
                    });
                }
            }
        }

        if entry > 0 && ! memory.is_empty() {
            args.insert(0, url.to_string());

            let mut contexts = ::env().contexts.lock();
            if let Some(mut context) = contexts.current_mut() {
                unsafe { context.unmap() };

                context.name = url.string;
                context.args = Arc::new(UnsafeCell::new(args));
                context.cwd = Arc::new(UnsafeCell::new(unsafe { (*context.cwd.get()).clone() }));
                context.memory = Arc::new(UnsafeCell::new(memory));

                unsafe { context.map() };

                context_ptr = context.deref_mut();
            }
        } else {
            debug!("{}: Invalid memory or entry\n", url.string);
        }
    } else {
        debug!("{}: Failed to open\n", url.string);
    }

    if context_ptr as usize > 0 {
        Context::spawn("kexec".to_string(), box move || {
            unsafe {
                let _intex = Intex::static_lock();

                let context = &mut *context_ptr;

                let mut context_args: Vec<usize> = Vec::new();
                context_args.push(0); // ENVP
                context_args.push(0); // ARGV NULL
                let mut argc = 0;
                for i in 0..(*context.args.get()).len() {
                    let reverse_i = (*context.args.get()).len() - i - 1;
                    if let Some(ref mut arg) = (*context.args.get()).get_mut(reverse_i) {
                        if ! arg.ends_with('\0') {
                            arg.push('\0');
                        }
                        context_args.push(arg.as_ptr() as usize);
                        argc += 1;
                    }
                }
                context_args.push(argc);

                context.sp = context.kernel_stack + CONTEXT_STACK_SIZE - 128;

                context.stack = Some(ContextMemory {
                    physical_address: memory::alloc(CONTEXT_STACK_SIZE),
                    virtual_address: CONTEXT_STACK_ADDR,
                    virtual_size: CONTEXT_STACK_SIZE,
                    writeable: true
                });

                let user_sp = if let Some(ref stack) = context.stack {
                    let mut sp = stack.physical_address + stack.virtual_size - 128;
                    for arg in context_args.iter() {
                        sp -= mem::size_of::<usize>();
                        ptr::write(sp as *mut usize, *arg);
                    }
                    sp - stack.physical_address + stack.virtual_address
                } else {
                    0
                };

                context.push(0x20 | 3);
                context.push(user_sp);
                context.push(/*1 << 9*/ 0);
                context.push(0x18 | 3);
                context.push(entry);
                context.push(context_userspace as usize);
            }
        });

        loop {
            unsafe { context_switch(false) };
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example: convolution<commit_after>#![allow(unused)]
#[macro_use(s)]
extern crate ndarray;
extern crate num;

use num::Float;

use ndarray::{
    ArrayView,
    ArrayViewMut,
    OwnedArray,
    Ix,
};

type Ix2 = (Ix, Ix);
const SOBEL_X: [[f32; 3]; 3] = [[-1., 0., 1.], [-2., 0., 2.], [-1., 0., 1.]];
const SOBEL_Y: [[f32; 3]; 3] = [[ 1., 2., 1.], [ 0., 0., 0.], [-1., -2., -1.]];
const SHARPEN: [[f32; 3]; 3] = [[0., -1., 0.], [ -1., 5., -1.], [0., -1., 0.]];

type Kernel3x3<A> = [[A; 3]; 3];

#[inline(never)]
fn conv_3x3<F>(a: &ArrayView<F, Ix2>, out: &mut ArrayViewMut<F, Ix2>, kernel: &Kernel3x3<F>)
    where F: Float,
{
    let (n, m) = a.dim();
    let (np, mp) = out.dim();
    if n < 3 || m < 3 {
        return;
    }
    assert!(np >= n && mp >= m);
    // i, j offset by -1 so that we can use unsigned indices
    unsafe {
        for i in 0..n - 2 {
            for j in 0..m - 2 {
                let mut conv = F::zero();
                for k in 0..3 {
                    for l in 0..3 {
                        conv = conv + *a.uget((i + k, j + l)) * kernel[k][l];
                        //conv += a[[i + k, j + l]] * x_kernel[k][l];
                    }
                }
                *out.uget_mut((i + 1, j + 1)) = conv;
            }
        }
    }
}

fn main() {
    let n = 16;
    let mut a = OwnedArray::zeros((n, n));
    // make a circle
    let c = (8., 8.);
    for ((i, j), elt) in a.indexed_iter_mut() {
        {
            let s = ((i as f32) - c.0).powi(2) + (j as f32 - c.1).powi(2);
            if s.sqrt() > 3. && s.sqrt() < 6. {
                *elt = 1.;
            }
        }
    }
    println!("{:?}", a);
    let mut res = OwnedArray::zeros(a.dim());
    for _ in 0..1000 {
        conv_3x3(&a.view(), &mut res.view_mut(), &SOBEL_X);
    }
    println!("{:?}", res);
}
<|endoftext|>


<commit_before><commit_msg>add macros4 example<commit_after>// Make me compile! Scroll down for hints :)

macro_rules! my_macro {
    () => {
        println!("Check out my macro!");
    }
    ($val:expr) => {
        println!("Look at this other macro: {}", $val);
    }
}

fn main() {
    my_macro!();
    my_macro!(7777);
}

// You only need to add a single character to make this compile.

// The way macros are written, it wants to see something between each "macro arm", so it can
// separate them.
<|endoftext|>


<commit_before><commit_msg>rust: anyhow-bt: add 2nd example<commit_after>use anyhow::Context;

/*
baz() failed:

Caused by:
    0: bar() failed:
    1: foo() failed:
    2: root cause
*/

fn foo() -> anyhow::Result<()> {
    Err(anyhow::anyhow!("root cause"))
}

fn bar() -> anyhow::Result<()> {
    foo().context("foo() failed:")?;
    Ok(())
}

fn baz() -> anyhow::Result<()> {
    bar().context("bar() failed:")?;
    Ok(())
}

fn main() {
    match baz().context("baz() failed:") {
        Ok(value) => value,
        Err(err) => println!("{:?}", err),
    };
}
<|endoftext|>


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

#![feature(reflect_marker)]

use std::any::TypeId;
use std::marker::Reflect;
use std::rc::Rc;

type Fp<T> = Rc<T>;

struct Engine;

trait Component: 'static + Reflect {}
impl Component for Engine {}

trait Env {
    fn get_component_type_id(&self, type_id: TypeId) -> Option<Fp<Component>>;
}

impl<'a> Env+'a {
    fn get_component<T: Component>(&self) -> Option<Fp<T>> {
        let x = self.get_component_type_id(TypeId::of::<T>());
        None
    }
}

trait Figment {
    fn init(&mut self, env: &Env);
}

struct MyFigment;

impl Figment for MyFigment {
    fn init(&mut self, env: &Env) {
        let engine = env.get_component::<Engine>();
    }
}

fn main() {}
<|endoftext|>


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

pub struct Foo {
    x: isize,
    y: isize
}

impl Foo {
    pub extern fn foo_new() -> Foo {
        Foo { x: 21, y: 33 }
    }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Adds Rust Problem 14<commit_after>/// Problem 14
/// The following iterative sequence is defined for the set of positive integers:
///
/// n → n/2 (n is even)
/// n → 3n + 1 (n is odd)
///
/// Using the rule above and starting with 13, we generate the following sequence:
///
/// 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
/// It can be seen that this sequence (starting at 13 and finishing at 1) contains
/// 10 terms. Although it has not been proved yet (Collatz Problem), it is thought
/// that all starting numbers finish at 1.
///
/// Which starting number, under one million, produces the longest chain?
///
/// NOTE: Once the chain starts the terms are allowed to go above one million.
fn main() {
    let top: u64 = 1000000;
    let mut max: u64 = 0;
    let mut num_max: u64 = 0;

    for i in 2..top {
        let c = collatz(i);
        if c > max {
            max = c;
            num_max = i;
            println!("{} -> {}", i, c);
        }
    }

    println!("Answer: {}", num_max);
}

fn collatz(n: u64) -> u64 {
    let mut count = 1;
    let mut num: u64 = n;
    loop {
        if num == 1 {
            break
        }
        count += 1;
        num = match num % 2 {
            0 => num/2,
            1 => 3*num+1,
            _ => 1
        };
    }
    count
}
<|endoftext|>


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

// Test that move restrictions are enforced on overloaded unary operations

fn move_then_borrow<T: Not<T> + Clone>(x: T) {
    !x;

    x.clone();  //~ ERROR: use of moved value
}

fn move_borrowed<T: Not<T>>(x: T, mut y: T) {
    let m = &x;
    let n = &mut y;

    !x;  //~ ERROR: cannot move out of `x` because it is borrowed

    !y;  //~ ERROR: cannot move out of `y` because it is borrowed
}

fn illegal_dereference<T: Not<T>>(mut x: T, y: T) {
    let m = &mut x;
    let n = &y;

    !*m;  //~ ERROR: cannot move out of dereference of `&mut`-pointer

    !*n;  //~ ERROR: cannot move out of dereference of `&`-pointer
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Fix doc<commit_after><|endoftext|>


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

use std::ffi;
use std::ops::Deref;

const SIZE: usize = 38;

/// Like SmallVec but for C strings.
#[derive(Clone)]
pub enum SmallCStr {
    OnStack {
        data: [u8; SIZE],
        len_with_nul: u8,
    },
    OnHeap {
        data: ffi::CString,
    }
}

impl SmallCStr {
    #[inline]
    pub fn new(s: &str) -> SmallCStr {
        if s.len() < SIZE {
            let mut data = [0; SIZE];
            data[.. s.len()].copy_from_slice(s.as_bytes());
            let len_with_nul = s.len() + 1;

            // Make sure once that this is a valid CStr
            if let Err(e) = ffi::CStr::from_bytes_with_nul(&data[.. len_with_nul]) {
                panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
            }

            SmallCStr::OnStack {
                data,
                len_with_nul: len_with_nul as u8,
            }
        } else {
            SmallCStr::OnHeap {
                data: ffi::CString::new(s).unwrap()
            }
        }
    }

    #[inline]
    pub fn as_c_str(&self) -> &ffi::CStr {
        match *self {
            SmallCStr::OnStack { ref data, len_with_nul } => {
                unsafe {
                    let slice = &data[.. len_with_nul as usize];
                    ffi::CStr::from_bytes_with_nul_unchecked(slice)
                }
            }
            SmallCStr::OnHeap { ref data } => {
                data.as_c_str()
            }
        }
    }

    #[inline]
    pub fn len_with_nul(&self) -> usize {
        match *self {
            SmallCStr::OnStack { len_with_nul, .. } => {
                len_with_nul as usize
            }
            SmallCStr::OnHeap { ref data } => {
                data.as_bytes_with_nul().len()
            }
        }
    }
}

impl Deref for SmallCStr {
    type Target = ffi::CStr;

    fn deref(&self) -> &ffi::CStr {
        self.as_c_str()
    }
}

#[test]
fn short() {
    const TEXT: &str = "abcd";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false });
}

#[test]
fn empty() {
    const TEXT: &str = "";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false });
}

#[test]
fn long() {
    const TEXT: &str = "01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(if let SmallCStr::OnHeap { .. } = scs { true } else { false });
}

#[test]
#[should_panic]
fn internal_nul() {
    let _ = SmallCStr::new("abcd\0def");
}
<commit_msg>Rollup merge of #53644 - llogiq:smallvec-for-small-c-str, r=estebank<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ffi;
use std::ops::Deref;

use smallvec::SmallVec;

const SIZE: usize = 36;

/// Like SmallVec but for C strings.
#[derive(Clone)]
pub struct SmallCStr {
    data: SmallVec<[u8; SIZE]>,
}

impl SmallCStr {
    #[inline]
    pub fn new(s: &str) -> SmallCStr {
        let len = s.len();
        let len1 = len + 1;
        let data = if len < SIZE {
            let mut buf = [0; SIZE];
            buf[..len].copy_from_slice(s.as_bytes());
            SmallVec::from_buf_and_len(buf, len1)
        } else {
            let mut data = Vec::with_capacity(len1);
            data.extend_from_slice(s.as_bytes());
            data.push(0);
            SmallVec::from_vec(data)
        };
        if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) {
            panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
        }
        SmallCStr { data }
    }

    #[inline]
    pub fn new_with_nul(s: &str) -> SmallCStr {
        let b = s.as_bytes();
        if let Err(e) = ffi::CStr::from_bytes_with_nul(b) {
            panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
        }
        SmallCStr { data: SmallVec::from_slice(s.as_bytes()) }
    }

    #[inline]
    pub fn as_c_str(&self) -> &ffi::CStr {
        unsafe {
            ffi::CStr::from_bytes_with_nul_unchecked(&self.data[..])
        }
    }

    #[inline]
    pub fn len_with_nul(&self) -> usize {
        self.data.len()
    }

    pub fn spilled(&self) -> bool {
        self.data.spilled()
    }
}

impl Deref for SmallCStr {
    type Target = ffi::CStr;

    fn deref(&self) -> &ffi::CStr {
        self.as_c_str()
    }
}

#[test]
fn short() {
    const TEXT: &str = "abcd";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(!scs.spilled());
}

#[test]
fn empty() {
    const TEXT: &str = "";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(!scs.spilled());
}

#[test]
fn long() {
    const TEXT: &str = "01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(scs.spilled());
}

#[test]
#[should_panic]
fn internal_nul() {
    let _ = SmallCStr::new("abcd\0def");
}
<|endoftext|>


<commit_before>#![feature(rustc_attrs, step_trait, rustc_private)]

#[macro_use] extern crate rustc_data_structures;
extern crate rustc_serialize;

use rustc_data_structures::indexed_vec::Idx;

newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });

use std::mem::size_of;

fn main() {
    assert_eq!(size_of::<MyIdx>(), 4);
    assert_eq!(size_of::<Option<MyIdx>>(), 4);
    assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
<commit_msg>Add missing #![feature(min_const_fn)] to the newtype_index test.<commit_after>#![feature(min_const_fn, rustc_attrs, rustc_private, step_trait)]

#[macro_use] extern crate rustc_data_structures;
extern crate rustc_serialize;

use rustc_data_structures::indexed_vec::Idx;

newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });

use std::mem::size_of;

fn main() {
    assert_eq!(size_of::<MyIdx>(), 4);
    assert_eq!(size_of::<Option<MyIdx>>(), 4);
    assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
<|endoftext|>


<commit_before><commit_msg>Make sure that casting a ptr-integer down to u8 makes it unusable<commit_after>fn main() {
    let x = &1;
    // Casting down to u8 and back up to a pointer loses too much precision; this must not work.
    let x = x as *const i32 as u8;
    let x = x as *const i32; //~ ERROR: a raw memory access tried to access part of a pointer value as raw bytes
    let _ = unsafe { *x };
}
<|endoftext|>


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

// Utilities to support Stratis.
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};

use libudev;

use super::device::is_stratis_device;
use stratis::StratisResult;

/// Takes a libudev device entry and returns the properties as a HashMap.
fn device_as_map(device: &libudev::Device) -> HashMap<String, String> {
    let rc: HashMap<_, _> = device
        .properties()
        .map(|i| {
            (
                String::from(i.name().to_str().expect("Unix is utf-8")),
                String::from(i.value().to_str().expect("Unix is utf-8")),
            )
        })
        .collect();
    rc
}

/// Common function used to retrieve the udev db entry for a block device as a HashMap when found
pub fn get_udev_block_device(
    dev_node_search: &Path,
) -> StratisResult<Option<HashMap<String, String>>> {
    let context = libudev::Context::new()?;
    let mut enumerator = libudev::Enumerator::new(&context)?;
    enumerator.match_subsystem("block")?;

    // Get canonical form to ensure we do correct lookup in udev db
    let canonical = fs::canonicalize(dev_node_search)?;

    let result = enumerator
        .scan_devices()?
        .find(|x| x.devnode().map_or(false, |d| canonical == d))
        .and_then(|dev| Some(device_as_map(&dev)));
    Ok(result)
}

/// Lookup the WWN from the udev db using the device node eg. /dev/sda
pub fn hw_lookup(dev_node_search: &Path) -> StratisResult<Option<String>> {
    let dev = get_udev_block_device(dev_node_search)?;
    Ok(dev.and_then(|dev| dev.get("ID_WWN").and_then(|i| Some(i.clone()))))
}

/// Collect paths for all the block devices which are not individual multipath paths and which
/// appear to be empty from a udev perspective.
fn get_all_empty_devices() -> StratisResult<Vec<PathBuf>> {
    let context = libudev::Context::new()?;
    let mut enumerator = libudev::Enumerator::new(&context)?;
    enumerator.match_subsystem("block")?;

    Ok(enumerator
        .scan_devices()?
        .filter(|dev| {
            dev.property_value("DM_MULTIPATH_DEVICE_PATH").is_none()
                && !((dev.property_value("ID_PART_TABLE_TYPE").is_some()
                    && dev.property_value("ID_PART_ENTRY_DISK").is_none())
                    || dev.property_value("ID_FS_USAGE").is_some())
        })
        .filter_map(|i| i.devnode().map(|d| d.into()))
        .collect())
}

/// Retrieve all the block devices on the system that have a Stratis signature.
pub fn get_stratis_block_devices() -> StratisResult<Vec<PathBuf>> {
    let context = libudev::Context::new()?;
    let mut enumerator = libudev::Enumerator::new(&context)?;
    enumerator.match_subsystem("block")?;
    enumerator.match_property("ID_FS_TYPE", "stratis")?;

    let devices: Vec<PathBuf> = enumerator
        .scan_devices()?
        .filter(|dev| dev.property_value("DM_MULTIPATH_DEVICE_PATH").is_none())
        .filter_map(|i| i.devnode().map(|d| d.into()))
        .collect();

    if devices.is_empty() {
        // Either we don't have any stratis devices or we are using a distribution that doesn't
        // have a version of libblkid that supports stratis, lets make sure.
        // TODO: At some point in the future we can remove this and just return the devices.

        Ok(get_all_empty_devices()?
            .into_iter()
            .filter(|x| is_stratis_device(&x).ok().is_some())
            .collect())
    } else {
        Ok(devices)
    }
}
<commit_msg>Ignore incomplete udev entries during enumeration<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Utilities to support Stratis.
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};

use libudev;

use super::device::is_stratis_device;
use stratis::StratisResult;

/// Takes a libudev device entry and returns the properties as a HashMap.
fn device_as_map(device: &libudev::Device) -> HashMap<String, String> {
    let rc: HashMap<_, _> = device
        .properties()
        .map(|i| {
            (
                String::from(i.name().to_str().expect("Unix is utf-8")),
                String::from(i.value().to_str().expect("Unix is utf-8")),
            )
        })
        .collect();
    rc
}

/// Common function used to retrieve the udev db entry for a block device as a HashMap when found
pub fn get_udev_block_device(
    dev_node_search: &Path,
) -> StratisResult<Option<HashMap<String, String>>> {
    let context = libudev::Context::new()?;
    let mut enumerator = libudev::Enumerator::new(&context)?;
    enumerator.match_subsystem("block")?;

    // Get canonical form to ensure we do correct lookup in udev db
    let canonical = fs::canonicalize(dev_node_search)?;

    let result = enumerator
        .scan_devices()?
        .filter(|dev| dev.is_initialized())
        .find(|x| x.devnode().map_or(false, |d| canonical == d))
        .and_then(|dev| Some(device_as_map(&dev)));
    Ok(result)
}

/// Lookup the WWN from the udev db using the device node eg. /dev/sda
pub fn hw_lookup(dev_node_search: &Path) -> StratisResult<Option<String>> {
    let dev = get_udev_block_device(dev_node_search)?;
    Ok(dev.and_then(|dev| dev.get("ID_WWN").and_then(|i| Some(i.clone()))))
}

/// Collect paths for all the block devices which are not individual multipath paths and which
/// appear to be empty from a udev perspective.
fn get_all_empty_devices() -> StratisResult<Vec<PathBuf>> {
    let context = libudev::Context::new()?;
    let mut enumerator = libudev::Enumerator::new(&context)?;
    enumerator.match_subsystem("block")?;

    Ok(enumerator
        .scan_devices()?
        .filter(|dev| dev.is_initialized())
        .filter(|dev| {
            dev.property_value("DM_MULTIPATH_DEVICE_PATH").is_none()
                && !((dev.property_value("ID_PART_TABLE_TYPE").is_some()
                    && dev.property_value("ID_PART_ENTRY_DISK").is_none())
                    || dev.property_value("ID_FS_USAGE").is_some())
        })
        .filter_map(|i| i.devnode().map(|d| d.into()))
        .collect())
}

/// Retrieve all the block devices on the system that have a Stratis signature.
pub fn get_stratis_block_devices() -> StratisResult<Vec<PathBuf>> {
    let context = libudev::Context::new()?;
    let mut enumerator = libudev::Enumerator::new(&context)?;
    enumerator.match_subsystem("block")?;
    enumerator.match_property("ID_FS_TYPE", "stratis")?;

    let devices: Vec<PathBuf> = enumerator
        .scan_devices()?
        .filter(|dev| dev.is_initialized())
        .filter(|dev| dev.property_value("DM_MULTIPATH_DEVICE_PATH").is_none())
        .filter_map(|i| i.devnode().map(|d| d.into()))
        .collect();

    if devices.is_empty() {
        // We have found no Stratis devices, possible reasons are:
        // 1. We really don't have any
        // 2. We have some, but libblkid is too old to support Stratis, thus we appear empty
        // 3. We ran this code at early boot before we have any udev db entries which are complete
        //    or are complete but fall into reasons 1 & 2 above
        //
        // In this case we will get all the block devices which have complete udev db block device
        // entries and appear "empty" and go out to disk and check them!

        Ok(get_all_empty_devices()?
            .into_iter()
            .filter(|x| is_stratis_device(&x).ok().is_some())
            .collect())
    } else {
        Ok(devices)
    }
}
<|endoftext|>


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

use LinkerFlavor;
use target::{Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::solaris_base::opts();
    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
    // llvm calls this "v9"
    base.cpu = "v9".to_string();
    base.max_atomic_width = Some(64);

    Ok(Target {
        llvm_target: "sparcv9-sun-solaris".to_string(),
        target_endian: "big".to_string(),
        target_pointer_width: "64".to_string(),
        target_c_int_width: "32".to_string(),
        data_layout: "E-m:e-i64:64-n32:64-S128".to_string(),
        // Use "sparc64" instead of "sparcv9" here, since the former is already
        // used widely in the source base.  If we ever needed ABI
        // differentiation from the sparc64, we could, but that would probably
        // just be confusing.
        arch: "sparc64".to_string(),
        target_os: "solaris".to_string(),
        target_env: "".to_string(),
        target_vendor: "sun".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: base,
    })
}
<commit_msg>Disable jemalloc for sparcv9-sun-solaris<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::solaris_base::opts();
    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
    // llvm calls this "v9"
    base.cpu = "v9".to_string();
    base.max_atomic_width = Some(64);
    base.exe_allocation_crate = None;

    Ok(Target {
        llvm_target: "sparcv9-sun-solaris".to_string(),
        target_endian: "big".to_string(),
        target_pointer_width: "64".to_string(),
        target_c_int_width: "32".to_string(),
        data_layout: "E-m:e-i64:64-n32:64-S128".to_string(),
        // Use "sparc64" instead of "sparcv9" here, since the former is already
        // used widely in the source base.  If we ever needed ABI
        // differentiation from the sparc64, we could, but that would probably
        // just be confusing.
        arch: "sparc64".to_string(),
        target_os: "solaris".to_string(),
        target_env: "".to_string(),
        target_vendor: "sun".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: base,
    })
}
<|endoftext|>


<commit_before><commit_msg>Remove let binding for unit value<commit_after><|endoftext|>


<commit_before><commit_msg>initial commit - implement handshake<commit_after>//! A Web Socket server

#[crate_id = "rust-ws"];

extern mod extra;
extern mod http;
extern mod rust_crypto = "rust-crypto";

use rust_crypto::sha1::Sha1;
use rust_crypto::digest::Digest;
use extra::base64::{ToBase64, STANDARD};

use std::io::net::ip::{SocketAddr, Ipv4Addr};
use std::io::Writer;
use extra::time;

use http::server::{Config, Server, Request, ResponseWriter};
use http::status::SwitchingProtocols;
use http::headers::HeaderEnum;
use http::headers::response::ExtensionHeader;
use http::headers::content_type::MediaType;
use http::headers::connection::Token;
use http::method::Get;

static WEBSOCKET_SALT: &'static str = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

#[deriving(Clone)]
struct WebSocketServer;

impl Server for WebSocketServer {
    fn get_config(&self) -> Config {
        Config { bind_address: SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8001 } }
    }

    fn handle_request(&self, r: &Request, w: &mut ResponseWriter) {
        match (&r.method, &r.headers.upgrade){
          // (&Get, &Some(~"websocket"), &Some(~[Token(~"Upgrade")])) => { // FIXME this doesn't work. but client must have the header "Connection: Upgrade"
          (&Get, &Some(~"websocket")) => { // TODO client must have the header "Connection: Upgrade"
            w.status = SwitchingProtocols;
            w.headers.upgrade = Some(~"websocket");

            // w.headers.transfer_encoding = None;
            w.headers.content_length = Some(0);

            w.headers.connection = Some(~[Token(~"Upgrade")]);

            // FIXME must we iter?
            for header in r.headers.iter() {
              match (header.header_name(), header.header_value()) {
                (~"Sec-Websocket-Key", val) => {
                  //  NOTE from RFC 6455
                  //  As an example, if the value of the |Sec-WebSocket-Key|
                  //  header field in the client's handshake were
                  //  "dGhlIHNhbXBsZSBub25jZQ==", the server would append the
                  //  string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to form the
                  //  string "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-
                  //  C5AB0DC85B11".  The server would then take the SHA-1 hash
                  //  of this string, giving the value 0xb3 0x7a 0x4f 0x2c 0xc0
                  //  0x62 0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf 0x38 0x59 0x45
                  //  0xb2 0xbe 0xc4 0xea.  This value is then base64-encoded,
                  //  to give the value "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", which
                  //  would be returned in the |Sec-WebSocket-Accept| header
                  //  field.

                  let mut sh = Sha1::new();
                  let mut out = [0u8, ..20];
                  sh.input_str(val + WEBSOCKET_SALT);
                  sh.result(out);
                  let sec_websocket_accept = out.to_base64(STANDARD);
                  debug!("sec websocket accept: {}", sec_websocket_accept);
                  w.headers.insert(ExtensionHeader(~"Sec-WebSocket-Accept", sec_websocket_accept));
                }
                (name, val) => {
                  debug!("{}: {}", name, val);
                }
              }
            }

            return;
          },
          (&_, &Some(_)) => {}, // handle other upgrade - this is rare apparently, but may be used for TLS for example. not sure if browsers actually implement it though.
          (&_, &None) => {} // TODO regular http server should handle this request
        }

        w.headers.date = Some(time::now_utc());
        w.headers.content_type = Some(MediaType {
            type_: ~"text",
            subtype: ~"html",
            parameters: ~[(~"charset", ~"UTF-8")]
        });
        w.headers.server = Some(~"Rust Thingummy/0.0-pre");
        w.write(bytes!("<!DOCTYPE html><title>Rust HTTP server</title>"));

        w.write(bytes!("
Request
"));
        let s = format!("

Method

{}

Host

{:?}

Upgrade

{:?}

Request URI

{:?}

HTTP version

{:?}

Close connection

{}

",
            r.method,
            r.headers.host,
            r.headers.upgrade,
            r.request_uri,
            r.version,
            r.close_connection);
        w.write(s.as_bytes());
        w.write(bytes!("
Extension headers
"));
        w.write(bytes!("

Name	Value

"));
        for header in r.headers.iter() {
            let line = format!("
{}	{}
",
                               header.header_name(),
                               header.header_value());
            w.write(line.as_bytes());
        }
        w.write(bytes!("

"));
        w.write(bytes!("
Body

"));
        w.write(r.body.as_bytes());
        w.write(bytes!("
"));

        w.write(bytes!("
Response
"));
        let s = format!("

Status

{}

", w.status);
        w.write(s.as_bytes());
        w.write(bytes!("
Headers
"));
        w.write(bytes!("

Name	Value

"));
        {
            let h = w.headers.clone();
            for header in h.iter() {
                let line = format!("
{}	{}
",
                                header.header_name(),
                                header.header_value());
                w.write(line.as_bytes());
            }
        }
        w.write(bytes!("

"));
    }
}

fn main() {
    WebSocketServer.serve_forever();
}
<|endoftext|>


<commit_before><commit_msg>Fix: Use unwrap_or_else(panic!(...)) as recommended by clippy<commit_after><|endoftext|>


<commit_before><commit_msg>add test for misaligned pointer loads<commit_after>fn main() {
    let x = &2u16;
    let x = x as *const _ as *const *const u8;
    // This must fail because alignment is violated.  Test specifically for loading pointers, which have special code
    // in miri's memory.
    let _x = unsafe { *x }; //~ ERROR: tried to access memory with alignment 2, but alignment
}
<|endoftext|>


<commit_before><commit_msg>finished testing bits<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests<commit_after>// run-pass

#[repr(align(4))]
struct Foo;

static FOO: Foo = Foo;

fn main() {
    let x: &'static () = &();
    assert_eq!(x as *const () as usize, 1);
    let x: &'static Foo = &Foo;
    assert_eq!(x as *const Foo as usize, 4);

    // statics must have a unique address
    assert_ne!(&FOO as *const Foo as usize, 4);

    assert_eq!(<Vec<i32>>::new().as_ptr(), <&[i32]>::default().as_ptr());
    assert_eq!(<Box<[i32]>>::default().as_ptr(), (&[]).as_ptr());
}
<|endoftext|>


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

//! A task that sniffs data
use std::comm::{channel, Receiver, Sender, Disconnected};
use std::task::TaskBuilder;
use resource_task::{LoadResponse};

pub type SnifferTask = Sender<LoadResponse>;

pub fn new_sniffer_task(next_rx: Sender<LoadResponse>) -> SnifferTask {
    let (sen, rec) = channel();
    let builder = TaskBuilder::new().named("SnifferManager");
    builder.spawn(proc() {
        SnifferManager::new(rec).start(next_rx);
    });
    sen
}

struct SnifferManager {
    data_receiver: Receiver<LoadResponse>,
}

impl SnifferManager {
    fn new(data_receiver: Receiver<LoadResponse>) -> SnifferManager {
        SnifferManager {
            data_receiver: data_receiver,
        }
    }
}

impl SnifferManager {
    fn start(&self, next_rx: Sender<LoadResponse>) {
        loop {
            match self.data_receiver.try_recv() {
                Ok(snif_data) => next_rx.send(snif_data),
                Err(Disconnected) => break,
                Err(_) => (),
            }
        }
    }
}
<commit_msg>auto merge of #4070 : kparaju/servo/master-mime-sniffer-failing-4046, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A task that sniffs data
use std::comm::{channel, Receiver, Sender, Disconnected};
use std::task::TaskBuilder;
use resource_task::{LoadResponse};

pub type SnifferTask = Sender<LoadResponse>;

pub fn new_sniffer_task(next_rx: Sender<LoadResponse>) -> SnifferTask {
    let (sen, rec) = channel();
    let builder = TaskBuilder::new().named("SnifferManager");
    builder.spawn(proc() {
        SnifferManager::new(rec).start(next_rx);
    });
    sen
}

struct SnifferManager {
    data_receiver: Receiver<LoadResponse>,
}

impl SnifferManager {
    fn new(data_receiver: Receiver<LoadResponse>) -> SnifferManager {
        SnifferManager {
            data_receiver: data_receiver,
        }
    }
}

impl SnifferManager {
    fn start(self, next_rx: Sender<LoadResponse>) {
        loop {
            match self.data_receiver.try_recv() {
                Ok(snif_data) => {
                    let result = next_rx.send_opt(snif_data);
                    if result.is_err() {
                        break;
                    }
                }
                Err(Disconnected) => break,
                Err(_) => (),
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add test<commit_after>// ignore-tidy-linelength

pub trait MyTrait {
    type Assoc;
    const VALUE: u32;
    fn trait_function(&self);
    fn defaulted(&self) {}
    fn defaulted_override(&self) {}
}

impl MyTrait for String {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-1"]//a[@class="anchor"]/@href' #associatedtype.Assoc-1
    type Assoc = ();
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-1"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-1
    const VALUE: u32 = 5;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-1"]//a[@class="anchor"]/@href' #method.defaulted_override-1
    fn defaulted_override(&self) {}
}

impl MyTrait for Vec<u8> {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-2"]//a[@class="anchor"]/@href' #associatedtype.Assoc-2
    type Assoc = ();
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-2"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-2
    const VALUE: u32 = 5;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-1"]//a[@class="anchor"]/@href' #method.trait_function-1
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-2"]//a[@class="anchor"]/@href' #method.defaulted_override-2
    fn defaulted_override(&self) {}
}

impl MyTrait for MyStruct {
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="type"]/@href' #associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedtype.Assoc-3"]//a[@class="anchor"]/@href' #associatedtype.Assoc-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="type"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedtype.Assoc
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedtype.Assoc"]//a[@class="anchor"]/@href' #associatedtype.Assoc
    type Assoc = bool;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="constant"]/@href' #associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="associatedconstant.VALUE-3"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#associatedconstant.VALUE
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
    const VALUE: u32 = 20;
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="fnname"]/@href' #tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.trait_function-2"]//a[@class="anchor"]/@href' #method.trait_function-2
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#tymethod.trait_function
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
    fn trait_function(&self) {}
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="fnname"]/@href' #method.defaulted_override
    // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//h4[@id="method.defaulted_override-3"]//a[@class="anchor"]/@href' #method.defaulted_override-3
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="fnname"]/@href' ../trait_impl_items_links_and_anchors/trait.MyTrait.html#method.defaulted_override
    // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//h4[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override
    fn defaulted_override(&self) {}
}

pub struct MyStruct;
<|endoftext|>


<commit_before><commit_msg>add arielby's example<commit_after>fn main() {
    let x = &mut 0u32;
    let p = x as *mut u32;
    foo(x, p);
}

fn foo(a: &mut u32, y: *mut u32) -> u32 {
    *a = 1;
    let _b = &*a;
    unsafe { *y = 2; } //~ ERROR: borrow stack
    return *a;
}
<|endoftext|>