<commit_before>use super::mode::{
    Mode,
};
use super::util;
use std::old_io as io;

pub use self::Doc::{
    Nil,
    Append,
    Group,
    Nest,
    Newline,
    Text,
};

#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Doc {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Group(Box<Doc>),
    Nest(u64, Box<Doc>),
    Newline,
    Text(String),
}

type Cmd<'a> = (u64, Mode, &'a Doc);

#[inline]
fn fitting<'a>(
       next:          Cmd<'a>,
      bcmds: &    Vec<Cmd<'a>>,
      fcmds: &mut Vec<Cmd<'a>>,
    mut rem: i64
) -> bool {
    let mut bidx = bcmds.len();
    let mut fits = true;

    fcmds.clear();      // clear from previous calls from best
    fcmds.push(next);

    loop {
        if rem < 0 {
            fits = false;
            break;
        }
        match fcmds.pop() {
            None => {
                if bidx == 0 {
                    break;
                } else {
                    fcmds.push(bcmds[ bidx - 1 ]);
                    bidx -= 1;
                }
            },
            Some((ind, mode, doc)) => match doc {
                &Nil => {
                },
                &Append(ref ldoc, ref rdoc) => {
                    fcmds.push((ind, mode, rdoc));
                    fcmds.push((ind, mode, ldoc));
                },
                &Group(ref doc) => {
                    fcmds.push((ind, mode, doc));
                },
                &Nest(off, ref doc) => {
                    fcmds.push((ind + off, mode, doc));
                },
                &Newline => {
                    fits = true;
                },
                &Text(ref str) => {
                    rem -= str.len() as i64;
                },
            }
        }
    }

    fits
}

#[inline]
pub fn best<W: io::Writer>(
      doc: &Doc,
    width: u64,
      out: &mut W
) -> io::IoResult<()> {
    let mut res   = Ok(());
    let mut pos   = 0;
    let mut bcmds = vec![(0, Mode::Break, doc)];
    let mut fcmds = vec![];

    while res.is_ok() {
        match bcmds.pop() {
            None => {
                break;
            },
            Some((ind, mode, doc)) => match doc {
                &Nil => {
                },
                &Append(ref ldoc, ref rdoc) => {
                    bcmds.push((ind, mode, rdoc));
                    bcmds.push((ind, mode, ldoc));
                },
                &Group(ref doc) => match mode {
                    Mode::Flat => {
                        bcmds.push((ind, Mode::Flat, doc));
                    },
                    Mode::Break => {
                        let next = (ind, Mode::Flat, &**doc);
                        let rem  = width as i64 - pos as i64;
                        if fitting(next, &bcmds, &mut fcmds, rem) {
                            bcmds.push(next);
                        } else {
                            bcmds.push((ind, Mode::Break, doc));
                        }
                    }
                },
                &Nest(off, ref doc) => {
                    bcmds.push((ind + off, mode, doc));
                },
                &Newline => {
                    res = out.write_str(&util::string::nl_spaces(ind as usize));
                    pos = ind;
                },
                &Text(ref s) => {
                    res  = out.write_str(&s);
                    pos += s.len() as u64;
                },
            }
        }
    }

    res
}
<commit_msg>Use literal suffixes<commit_after>use super::mode::{
    Mode,
};
use super::util;
use std::old_io as io;

pub use self::Doc::{
    Nil,
    Append,
    Group,
    Nest,
    Newline,
    Text,
};

#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Doc {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Group(Box<Doc>),
    Nest(u64, Box<Doc>),
    Newline,
    Text(String),
}

type Cmd<'a> = (u64, Mode, &'a Doc);

#[inline]
fn fitting<'a>(
       next:          Cmd<'a>,
      bcmds: &    Vec<Cmd<'a>>,
      fcmds: &mut Vec<Cmd<'a>>,
    mut rem: i64
) -> bool {
    let mut bidx = bcmds.len();
    let mut fits = true;

    fcmds.clear();      // clear from previous calls from best
    fcmds.push(next);

    loop {
        if rem < 0 {
            fits = false;
            break;
        }
        match fcmds.pop() {
            None => {
                if bidx == 0 {
                    break;
                } else {
                    fcmds.push(bcmds[ bidx - 1 ]);
                    bidx -= 1;
                }
            },
            Some((ind, mode, doc)) => match doc {
                &Nil => {
                },
                &Append(ref ldoc, ref rdoc) => {
                    fcmds.push((ind, mode, rdoc));
                    fcmds.push((ind, mode, ldoc));
                },
                &Group(ref doc) => {
                    fcmds.push((ind, mode, doc));
                },
                &Nest(off, ref doc) => {
                    fcmds.push((ind + off, mode, doc));
                },
                &Newline => {
                    fits = true;
                },
                &Text(ref str) => {
                    rem -= str.len() as i64;
                },
            }
        }
    }

    fits
}

#[inline]
pub fn best<W: io::Writer>(
      doc: &Doc,
    width: u64,
      out: &mut W
) -> io::IoResult<()> {
    let mut res   = Ok(());
    let mut pos   = 0u64;
    let mut bcmds = vec![(0u64, Mode::Break, doc)];
    let mut fcmds = vec![];

    while res.is_ok() {
        match bcmds.pop() {
            None => {
                break;
            },
            Some((ind, mode, doc)) => match doc {
                &Nil => {
                },
                &Append(ref ldoc, ref rdoc) => {
                    bcmds.push((ind, mode, rdoc));
                    bcmds.push((ind, mode, ldoc));
                },
                &Group(ref doc) => match mode {
                    Mode::Flat => {
                        bcmds.push((ind, Mode::Flat, doc));
                    },
                    Mode::Break => {
                        let next = (ind, Mode::Flat, &**doc);
                        let rem  = width as i64 - pos as i64;
                        if fitting(next, &bcmds, &mut fcmds, rem) {
                            bcmds.push(next);
                        } else {
                            bcmds.push((ind, Mode::Break, doc));
                        }
                    }
                },
                &Nest(off, ref doc) => {
                    bcmds.push((ind + off, mode, doc));
                },
                &Newline => {
                    res = out.write_str(&util::string::nl_spaces(ind as usize));
                    pos = ind;
                },
                &Text(ref s) => {
                    res  = out.write_str(&s);
                    pos += s.len() as u64;
                },
            }
        }
    }

    res
}
<|endoftext|>


<commit_before>extern crate globset;

use globset::{GlobBuilder, GlobSet, GlobSetBuilder};
use std::fs;
use std::io;
use std::io::Read;
use std::path::{Path, PathBuf};

pub fn load(path: &Path) -> Option<GitignoreFile> {
    let mut p = path.to_owned();

    loop {
        let gitignore_path = p.join(".gitignore");
        if gitignore_path.exists() {
            return GitignoreFile::new(&gitignore_path).ok();
        }

        // Stop if we see a .git directory
        if let Ok(metadata) = p.join(".git").metadata() {
            if metadata.is_dir() {
                break;
            }
        }

        if p.parent().is_none() {
            break;
        }

        p.pop();
    }

    None

}

pub struct GitignoreFile {
    set: GlobSet,
    patterns: Vec<Pattern>,
    root: PathBuf,
}

#[derive(Debug)]
pub enum Error {
    GlobSet(globset::Error),
    Io(io::Error),
}

struct Pattern {
    pattern: String,
    pattern_type: PatternType,
    anchored: bool,
}

enum PatternType {
    Ignore,
    Whitelist,
}

impl GitignoreFile {
    pub fn new(path: &Path) -> Result<GitignoreFile, Error> {
        let mut file = try!(fs::File::open(path));
        let mut contents = String::new();
        try!(file.read_to_string(&mut contents));

        let lines = contents.lines().collect();
        let root = path.parent().unwrap();

        GitignoreFile::from_strings(lines, root)
    }

    pub fn from_strings(strs: Vec<&str>, root: &Path) -> Result<GitignoreFile, Error> {
        let mut builder = GlobSetBuilder::new();
        let mut patterns = vec![];

        let parsed_patterns = GitignoreFile::parse(strs);
        for p in parsed_patterns {
            let mut pat = String::from(p.pattern.clone());
            if !p.anchored && !pat.starts_with("**/") {
                pat = "**/".to_string() + &pat;
            }

            if !pat.ends_with("/**") {
                pat = pat + "/**";
            }

            let glob = try!(GlobBuilder::new(&pat)
                            .literal_separator(true)
                            .build());

            builder.add(glob);
            patterns.push(p);
        }

        Ok(GitignoreFile {
            set: try!(builder.build()),
            patterns: patterns,
            root: root.to_owned(),
        })

    }

    pub fn is_excluded(&self, path: &Path) -> bool {
        let stripped = path.strip_prefix(&self.root);
        if !stripped.is_ok() {
            return false;
        }

        let matches = self.set.matches(stripped.unwrap());

        for &i in matches.iter().rev() {
            let pattern = &self.patterns[i];
            return match pattern.pattern_type {
                PatternType::Whitelist  => false,
                PatternType::Ignore     => true,
            }
        }

        false
    }

    fn parse(contents: Vec<&str>) -> Vec<Pattern> {
        contents.iter()
            .filter(|l| !l.is_empty())
            .filter(|l| !l.starts_with('#'))
            .map(|l| Pattern::parse(l))
            .collect()
    }
}

impl Pattern {
    fn parse(pattern: &str) -> Pattern {
        let mut normalized = String::from(pattern);

        let pattern_type = if normalized.starts_with('!') {
            normalized.remove(0);
            PatternType::Whitelist
        } else {
            PatternType::Ignore
        };

        let anchored = if normalized.starts_with('/') {
            normalized.remove(0);
            true
        } else {
            false
        };

        if normalized.ends_with('/') {
            normalized.pop();
        }

        if normalized.starts_with("\\#") || normalized.starts_with("\\!") {
            normalized.remove(0);
        }

        Pattern {
            pattern: normalized,
            pattern_type: pattern_type,
            anchored: anchored,
        }
    }
}

impl From<globset::Error> for Error {
    fn from(error: globset::Error) -> Error {
        Error::GlobSet(error)
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Error {
        Error::Io(error)
    }
}

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

    fn base_dir() -> PathBuf {
        PathBuf::from("/home/user/dir")
    }

    fn build_gitignore(pattern: &str) -> GitignoreFile {
        GitignoreFile::from_strings(vec![pattern], &base_dir()).unwrap()
    }

    #[test]
    fn test_matches_exact() {
        let file = build_gitignore("Cargo.toml");

        assert!(file.is_excluded(&base_dir().join("Cargo.toml")));
    }

    #[test]
    fn test_does_not_match() {
        let file = build_gitignore("Cargo.toml");

        assert!(!file.is_excluded(&base_dir().join("src").join("main.rs")));
    }

    #[test]
    fn test_matches_simple_wildcard() {
        let file = build_gitignore("targ*");

        assert!(file.is_excluded(&base_dir().join("target")));
    }

    #[test]
    fn test_matches_subdir_exact() {
        let file = build_gitignore("target");

        assert!(file.is_excluded(&base_dir().join("target/")));
    }

    #[test]
    fn test_matches_subdir() {
        let file = build_gitignore("target");

        assert!(file.is_excluded(&base_dir().join("target").join("file")));
        assert!(file.is_excluded(&base_dir().join("target").join("subdir").join("file")));
    }

    #[test]
    fn test_wildcard_with_dir() {
        let file = build_gitignore("target/f*");

        assert!(file.is_excluded(&base_dir().join("target").join("file")));
        assert!(!file.is_excluded(&base_dir().join("target").join("subdir").join("file")));
    }

    #[test]
    fn test_leading_slash() {
        let file = build_gitignore("/*.c");

        assert!(file.is_excluded(&base_dir().join("cat-file.c")));
        assert!(!file.is_excluded(&base_dir().join("mozilla-sha1").join("sha1.c")));
    }

    #[test]
    fn test_leading_double_wildcard() {
        let file = build_gitignore("**/foo");

        assert!(file.is_excluded(&base_dir().join("foo")));
        assert!(file.is_excluded(&base_dir().join("target").join("foo")));
        assert!(file.is_excluded(&base_dir().join("target").join("subdir").join("foo")));
    }

    #[test]
    fn test_trailing_double_wildcard() {
        let file = build_gitignore("abc/**");

        assert!(!file.is_excluded(&base_dir().join("def").join("foo")));
        assert!(file.is_excluded(&base_dir().join("abc").join("foo")));
        assert!(file.is_excluded(&base_dir().join("abc").join("subdir").join("foo")));
    }

    #[test]
    fn test_sandwiched_double_wildcard() {
        let file = build_gitignore("a/**/b");

        assert!(file.is_excluded(&base_dir().join("a").join("b")));
        assert!(file.is_excluded(&base_dir().join("a").join("x").join("b")));
        assert!(file.is_excluded(&base_dir().join("a").join("x").join("y").join("b")));
    }

    #[test]
    fn test_empty_file_never_excludes() {
        let file = GitignoreFile::from_strings(vec![], &base_dir()).unwrap();

        assert!(!file.is_excluded(&base_dir().join("target")));
    }

    #[test]
    fn test_checks_all_patterns() {
        let patterns = vec!["target", "target2"];
        let file = GitignoreFile::from_strings(patterns, &base_dir()).unwrap();

        assert!(file.is_excluded(&base_dir().join("target").join("foo.txt")));
        assert!(file.is_excluded(&base_dir().join("target2").join("bar.txt")));
    }

    #[test]
    fn test_handles_whitelisting() {
        let patterns = vec!["target", "!target/foo.txt"];
        let file = GitignoreFile::from_strings(patterns, &base_dir()).unwrap();

        assert!(!file.is_excluded(&base_dir().join("target").join("foo.txt")));
        assert!(file.is_excluded(&base_dir().join("target").join("blah.txt")));
    }
}

<commit_msg>rustfmt<commit_after>extern crate globset;

use globset::{GlobBuilder, GlobSet, GlobSetBuilder};
use std::fs;
use std::io;
use std::io::Read;
use std::path::{Path, PathBuf};

pub fn load(path: &Path) -> Option<GitignoreFile> {
    let mut p = path.to_owned();

    loop {
        let gitignore_path = p.join(".gitignore");
        if gitignore_path.exists() {
            return GitignoreFile::new(&gitignore_path).ok();
        }

        // Stop if we see a .git directory
        if let Ok(metadata) = p.join(".git").metadata() {
            if metadata.is_dir() {
                break;
            }
        }

        if p.parent().is_none() {
            break;
        }

        p.pop();
    }

    None

}

pub struct GitignoreFile {
    set: GlobSet,
    patterns: Vec<Pattern>,
    root: PathBuf,
}

#[derive(Debug)]
pub enum Error {
    GlobSet(globset::Error),
    Io(io::Error),
}

struct Pattern {
    pattern: String,
    pattern_type: PatternType,
    anchored: bool,
}

enum PatternType {
    Ignore,
    Whitelist,
}

impl GitignoreFile {
    pub fn new(path: &Path) -> Result<GitignoreFile, Error> {
        let mut file = try!(fs::File::open(path));
        let mut contents = String::new();
        try!(file.read_to_string(&mut contents));

        let lines = contents.lines().collect();
        let root = path.parent().unwrap();

        GitignoreFile::from_strings(lines, root)
    }

    pub fn from_strings(strs: Vec<&str>, root: &Path) -> Result<GitignoreFile, Error> {
        let mut builder = GlobSetBuilder::new();
        let mut patterns = vec![];

        let parsed_patterns = GitignoreFile::parse(strs);
        for p in parsed_patterns {
            let mut pat = String::from(p.pattern.clone());
            if !p.anchored && !pat.starts_with("**/") {
                pat = "**/".to_string() + &pat;
            }

            if !pat.ends_with("/**") {
                pat = pat + "/**";
            }

            let glob = try!(GlobBuilder::new(&pat)
                .literal_separator(true)
                .build());

            builder.add(glob);
            patterns.push(p);
        }

        Ok(GitignoreFile {
            set: try!(builder.build()),
            patterns: patterns,
            root: root.to_owned(),
        })

    }

    pub fn is_excluded(&self, path: &Path) -> bool {
        let stripped = path.strip_prefix(&self.root);
        if !stripped.is_ok() {
            return false;
        }

        let matches = self.set.matches(stripped.unwrap());

        for &i in matches.iter().rev() {
            let pattern = &self.patterns[i];
            return match pattern.pattern_type {
                PatternType::Whitelist => false,
                PatternType::Ignore => true,
            };
        }

        false
    }

    fn parse(contents: Vec<&str>) -> Vec<Pattern> {
        contents.iter()
            .filter(|l| !l.is_empty())
            .filter(|l| !l.starts_with('#'))
            .map(|l| Pattern::parse(l))
            .collect()
    }
}

impl Pattern {
    fn parse(pattern: &str) -> Pattern {
        let mut normalized = String::from(pattern);

        let pattern_type = if normalized.starts_with('!') {
            normalized.remove(0);
            PatternType::Whitelist
        } else {
            PatternType::Ignore
        };

        let anchored = if normalized.starts_with('/') {
            normalized.remove(0);
            true
        } else {
            false
        };

        if normalized.ends_with('/') {
            normalized.pop();
        }

        if normalized.starts_with("\\#") || normalized.starts_with("\\!") {
            normalized.remove(0);
        }

        Pattern {
            pattern: normalized,
            pattern_type: pattern_type,
            anchored: anchored,
        }
    }
}

impl From<globset::Error> for Error {
    fn from(error: globset::Error) -> Error {
        Error::GlobSet(error)
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Error {
        Error::Io(error)
    }
}

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

    fn base_dir() -> PathBuf {
        PathBuf::from("/home/user/dir")
    }

    fn build_gitignore(pattern: &str) -> GitignoreFile {
        GitignoreFile::from_strings(vec![pattern], &base_dir()).unwrap()
    }

    #[test]
    fn test_matches_exact() {
        let file = build_gitignore("Cargo.toml");

        assert!(file.is_excluded(&base_dir().join("Cargo.toml")));
    }

    #[test]
    fn test_does_not_match() {
        let file = build_gitignore("Cargo.toml");

        assert!(!file.is_excluded(&base_dir().join("src").join("main.rs")));
    }

    #[test]
    fn test_matches_simple_wildcard() {
        let file = build_gitignore("targ*");

        assert!(file.is_excluded(&base_dir().join("target")));
    }

    #[test]
    fn test_matches_subdir_exact() {
        let file = build_gitignore("target");

        assert!(file.is_excluded(&base_dir().join("target/")));
    }

    #[test]
    fn test_matches_subdir() {
        let file = build_gitignore("target");

        assert!(file.is_excluded(&base_dir().join("target").join("file")));
        assert!(file.is_excluded(&base_dir().join("target").join("subdir").join("file")));
    }

    #[test]
    fn test_wildcard_with_dir() {
        let file = build_gitignore("target/f*");

        assert!(file.is_excluded(&base_dir().join("target").join("file")));
        assert!(!file.is_excluded(&base_dir().join("target").join("subdir").join("file")));
    }

    #[test]
    fn test_leading_slash() {
        let file = build_gitignore("/*.c");

        assert!(file.is_excluded(&base_dir().join("cat-file.c")));
        assert!(!file.is_excluded(&base_dir().join("mozilla-sha1").join("sha1.c")));
    }

    #[test]
    fn test_leading_double_wildcard() {
        let file = build_gitignore("**/foo");

        assert!(file.is_excluded(&base_dir().join("foo")));
        assert!(file.is_excluded(&base_dir().join("target").join("foo")));
        assert!(file.is_excluded(&base_dir().join("target").join("subdir").join("foo")));
    }

    #[test]
    fn test_trailing_double_wildcard() {
        let file = build_gitignore("abc/**");

        assert!(!file.is_excluded(&base_dir().join("def").join("foo")));
        assert!(file.is_excluded(&base_dir().join("abc").join("foo")));
        assert!(file.is_excluded(&base_dir().join("abc").join("subdir").join("foo")));
    }

    #[test]
    fn test_sandwiched_double_wildcard() {
        let file = build_gitignore("a/**/b");

        assert!(file.is_excluded(&base_dir().join("a").join("b")));
        assert!(file.is_excluded(&base_dir().join("a").join("x").join("b")));
        assert!(file.is_excluded(&base_dir().join("a").join("x").join("y").join("b")));
    }

    #[test]
    fn test_empty_file_never_excludes() {
        let file = GitignoreFile::from_strings(vec![], &base_dir()).unwrap();

        assert!(!file.is_excluded(&base_dir().join("target")));
    }

    #[test]
    fn test_checks_all_patterns() {
        let patterns = vec!["target", "target2"];
        let file = GitignoreFile::from_strings(patterns, &base_dir()).unwrap();

        assert!(file.is_excluded(&base_dir().join("target").join("foo.txt")));
        assert!(file.is_excluded(&base_dir().join("target2").join("bar.txt")));
    }

    #[test]
    fn test_handles_whitelisting() {
        let patterns = vec!["target", "!target/foo.txt"];
        let file = GitignoreFile::from_strings(patterns, &base_dir()).unwrap();

        assert!(!file.is_excluded(&base_dir().join("target").join("foo.txt")));
        assert!(file.is_excluded(&base_dir().join("target").join("blah.txt")));
    }
}
<|endoftext|>


<commit_before>use super::super::{in_coroutine};

use std::sync::mpsc;

use super::notify;
use super::broadcast;

/// Channel receiving end
///
/// Create with `channel()`
pub struct Receiver<T>{
    rx: Option<mpsc::Receiver<T>>,
    notify_rx: notify::Receiver,
}

impl<T> Receiver<T>
    where T: 'static
{
    /// Receive `T` sent using corresponding `Sender::send()`.
    ///
    /// Will block coroutine if no elements are available.
    pub fn recv(&self) -> Result<T, mpsc::RecvError> {
        if in_coroutine() {
            loop {
                self.notify_rx.reset();

                let recv = self.try_recv();

                match recv {
                    Err(mpsc::TryRecvError::Empty) =>
                        self.notify_rx.wait(),
                    Err(mpsc::TryRecvError::Disconnected) => return Err(mpsc::RecvError),
                    Ok(t) => {
                        return Ok(t)
                    },
                }
            }
        } else {
            let recv = self.rx.as_ref().unwrap().recv();

                match recv {
                    Err(e) => Err(e),
                    Ok(t) => {
                        return Ok(t)
                    },
                }
        }
    }

    /// Try reading data from the queue.
    ///
    /// This will not block.
    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
        let recv = self.rx.as_ref().unwrap().try_recv();
        match recv {
            Err(e) => Err(e),
            Ok(t) => {
                return Ok(t)
            },
        }
    }
}

/// Channel sending end
///
/// Use this inside mioco coroutines or outside of mioco itself to send data
/// asynchronously to the receiving end.
///
/// Create with `channel()`
pub struct Sender<T> {
    tx: Option<mpsc::Sender<T>>,
    notif_tx: notify::Sender,
}

impl<T> Clone for Sender<T> {
    fn clone(&self) -> Self {
        Sender {
            tx: self.tx.clone(),
            notif_tx: self.notif_tx.clone(),
        }
    }
}

impl<T> Sender<T> {
    /// Deliver `T` to the other end of the channel.
    ///
    /// Channel behaves like a queue.
    ///
    /// This is non-blocking operation.
    pub fn send(&self, t: T) -> Result<(), mpsc::SendError<T>> {
        try!(self.tx.as_ref().unwrap().send(t));
        self.notif_tx.notify();
        Ok(())
    }
}

/// Channel receiving end
///
/// Create with `channel()`
pub struct SyncReceiver<T>{
    rx: Option<mpsc::Receiver<T>>,
    broadcast_tx: broadcast::Sender,
    broadcast_rx: broadcast::Receiver,
}

impl<T> SyncReceiver<T>
    where T: 'static
{
    /// Receive `T` sent using corresponding `Sender::send()`.
    ///
    /// Will block coroutine if no elements are available.
    pub fn recv(&self) -> Result<T, mpsc::RecvError> {
        if in_coroutine() {
            loop {
                self.broadcast_rx.reset();

                let recv = self.try_recv();

                match recv {
                    Err(mpsc::TryRecvError::Empty) => self.broadcast_rx.wait(),
                    Err(mpsc::TryRecvError::Disconnected) => return Err(mpsc::RecvError),
                    Ok(t) => {
                        // wake up sender fiber in case it context switched
                        // because of channel full error
                        self.broadcast_tx.notify();
                        return Ok(t)
                    },
                }
            }
        } else {
            let recv = self.rx.as_ref().unwrap().recv();

                match recv {
                    Err(e) => Err(e),
                    Ok(t) => return Ok(t),
                }
        }
    }

    /// Try reading data from the queue.
    ///
    /// This will not block.
    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
        let recv = self.rx.as_ref().unwrap().try_recv();
        match recv {
            Err(e) => Err(e),
            Ok(t) => {
                return Ok(t)
            },
        }
    }
}

/// Channel sync sending end
///
/// Use this inside mioco coroutines or outside of mioco itself to send data
/// asynchronously to the receiving end.
///
/// Create with `sync_channel()`
pub struct SyncSender<T> {
    tx: Option<mpsc::SyncSender<T>>,
    broadcast_rx: broadcast::Receiver,
    broadcast_tx: broadcast::Sender,
}

impl<T> SyncSender<T> {
    pub fn send(&self, mut t: T) -> Result<(), mpsc::SendError<T>> {
        if in_coroutine() {
            loop {
                t = match self.try_send(t) {
                    Ok(t) => return Ok(t),
                    Err(mpsc::TrySendError::Full(t)) => {
                        self.broadcast_rx.wait();
                        t
                    },
                    Err(mpsc::TrySendError::Disconnected(v)) => return Err(mpsc::SendError(v))
                };
            }
        } else {
            // previous send's notify() will make sure 'rx' will be notified
            // and there will be space for this send at some point
            self.tx.as_ref().unwrap().send(t)?;
        }
        self.broadcast_tx.notify();
        Ok(())
    }

    /// Deliver `T` to the other end of the channel.
    ///
    /// Channel behaves like a queue.
    ///
    /// This is non-blocking operation.
    pub fn try_send(&self, t: T) -> Result<(), mpsc::TrySendError<T>> {
        self.tx.as_ref().unwrap().try_send(t)?;
        self.broadcast_tx.notify();
        Ok(())
    }
}

/// Create a channel
///
/// Channel can be used to deliver data via MPSC queue.
///
/// Channel is modeled after `std::sync::mpsc::channel()`, only
/// supporting mioco-aware sending and receiving.
///
/// When receiving end is outside of coroutine, channel will behave just
/// like `std::sync::mpsc::channel()`.
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {

    let (n_tx, n_rx) = notify::channel();
    let (tx, rx) = mpsc::channel();
    (Sender {
        tx: Some(tx),
        notif_tx: n_tx,
    },
        Receiver {
            rx: Some(rx),
            notify_rx: n_rx,
        })
}

impl<T> Drop for Sender<T> {
    fn drop(&mut self) {
        {
            self.tx.take();
        }
        self.notif_tx.notify()
    }
}

pub fn sync_channel<T>(size: usize) -> (SyncSender<T>, SyncReceiver<T>) {

    let (btx, brx) = broadcast::channel();
    let (tx, rx) = mpsc::sync_channel(size);
    (   SyncSender {
            tx: Some(tx),
            broadcast_tx: btx.clone(),
            broadcast_rx: brx.clone(),
        },
        SyncReceiver {
            rx: Some(rx),
            broadcast_tx: btx,
            broadcast_rx: brx,
        }
    )
}

impl<T> Drop for SyncSender<T> {
    fn drop(&mut self) {
        {
            self.tx.take();
        }
        self.broadcast_tx.notify()
    }
}
<commit_msg>reset before try_send<commit_after>use super::super::{in_coroutine};

use std::sync::mpsc;

use super::notify;
use super::broadcast;

/// Channel receiving end
///
/// Create with `channel()`
pub struct Receiver<T>{
    rx: Option<mpsc::Receiver<T>>,
    notify_rx: notify::Receiver,
}

impl<T> Receiver<T>
    where T: 'static
{
    /// Receive `T` sent using corresponding `Sender::send()`.
    ///
    /// Will block coroutine if no elements are available.
    pub fn recv(&self) -> Result<T, mpsc::RecvError> {
        if in_coroutine() {
            loop {
                self.notify_rx.reset();

                let recv = self.try_recv();

                match recv {
                    Err(mpsc::TryRecvError::Empty) =>
                        self.notify_rx.wait(),
                    Err(mpsc::TryRecvError::Disconnected) => return Err(mpsc::RecvError),
                    Ok(t) => {
                        return Ok(t)
                    },
                }
            }
        } else {
            let recv = self.rx.as_ref().unwrap().recv();

                match recv {
                    Err(e) => Err(e),
                    Ok(t) => {
                        return Ok(t)
                    },
                }
        }
    }

    /// Try reading data from the queue.
    ///
    /// This will not block.
    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
        let recv = self.rx.as_ref().unwrap().try_recv();
        match recv {
            Err(e) => Err(e),
            Ok(t) => {
                return Ok(t)
            },
        }
    }
}

/// Channel sending end
///
/// Use this inside mioco coroutines or outside of mioco itself to send data
/// asynchronously to the receiving end.
///
/// Create with `channel()`
pub struct Sender<T> {
    tx: Option<mpsc::Sender<T>>,
    notif_tx: notify::Sender,
}

impl<T> Clone for Sender<T> {
    fn clone(&self) -> Self {
        Sender {
            tx: self.tx.clone(),
            notif_tx: self.notif_tx.clone(),
        }
    }
}

impl<T> Sender<T> {
    /// Deliver `T` to the other end of the channel.
    ///
    /// Channel behaves like a queue.
    ///
    /// This is non-blocking operation.
    pub fn send(&self, t: T) -> Result<(), mpsc::SendError<T>> {
        try!(self.tx.as_ref().unwrap().send(t));
        self.notif_tx.notify();
        Ok(())
    }
}

/// Channel receiving end
///
/// Create with `channel()`
pub struct SyncReceiver<T>{
    rx: Option<mpsc::Receiver<T>>,
    broadcast_tx: broadcast::Sender,
    broadcast_rx: broadcast::Receiver,
}

impl<T> SyncReceiver<T>
    where T: 'static
{
    /// Receive `T` sent using corresponding `Sender::send()`.
    ///
    /// Will block coroutine if no elements are available.
    pub fn recv(&self) -> Result<T, mpsc::RecvError> {
        if in_coroutine() {
            loop {
                self.broadcast_rx.reset();

                let recv = self.try_recv();

                match recv {
                    Err(mpsc::TryRecvError::Empty) => self.broadcast_rx.wait(),
                    Err(mpsc::TryRecvError::Disconnected) => return Err(mpsc::RecvError),
                    Ok(t) => {
                        // wake up sender fiber in case it context switched
                        // because of channel full error
                        self.broadcast_tx.notify();
                        return Ok(t)
                    },
                }
            }
        } else {
            let recv = self.rx.as_ref().unwrap().recv();

                match recv {
                    Err(e) => Err(e),
                    Ok(t) => return Ok(t),
                }
        }
    }

    /// Try reading data from the queue.
    ///
    /// This will not block.
    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
        let recv = self.rx.as_ref().unwrap().try_recv();
        match recv {
            Err(e) => Err(e),
            Ok(t) => {
                return Ok(t)
            },
        }
    }
}

/// Channel sync sending end
///
/// Use this inside mioco coroutines or outside of mioco itself to send data
/// asynchronously to the receiving end.
///
/// Create with `sync_channel()`
pub struct SyncSender<T> {
    tx: Option<mpsc::SyncSender<T>>,
    broadcast_rx: broadcast::Receiver,
    broadcast_tx: broadcast::Sender,
}

impl<T> SyncSender<T> {
    pub fn send(&self, mut t: T) -> Result<(), mpsc::SendError<T>> {
        if in_coroutine() {
            loop {
                self.broadcast_rx.reset();
                t = match self.try_send(t) {
                    Ok(t) => return Ok(t),
                    Err(mpsc::TrySendError::Full(t)) => {
                        self.broadcast_rx.wait();
                        t
                    },
                    Err(mpsc::TrySendError::Disconnected(v)) => return Err(mpsc::SendError(v))
                };
            }
        } else {
            // previous send's notify() will make sure 'rx' will be notified
            // and there will be space for this send at some point
            self.tx.as_ref().unwrap().send(t)?;
        }
        self.broadcast_tx.notify();
        Ok(())
    }

    /// Deliver `T` to the other end of the channel.
    ///
    /// Channel behaves like a queue.
    ///
    /// This is non-blocking operation.
    pub fn try_send(&self, t: T) -> Result<(), mpsc::TrySendError<T>> {
        self.tx.as_ref().unwrap().try_send(t)?;
        self.broadcast_tx.notify();
        Ok(())
    }
}

/// Create a channel
///
/// Channel can be used to deliver data via MPSC queue.
///
/// Channel is modeled after `std::sync::mpsc::channel()`, only
/// supporting mioco-aware sending and receiving.
///
/// When receiving end is outside of coroutine, channel will behave just
/// like `std::sync::mpsc::channel()`.
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {

    let (n_tx, n_rx) = notify::channel();
    let (tx, rx) = mpsc::channel();
    (Sender {
        tx: Some(tx),
        notif_tx: n_tx,
    },
        Receiver {
            rx: Some(rx),
            notify_rx: n_rx,
        })
}

impl<T> Drop for Sender<T> {
    fn drop(&mut self) {
        {
            self.tx.take();
        }
        self.notif_tx.notify()
    }
}

pub fn sync_channel<T>(size: usize) -> (SyncSender<T>, SyncReceiver<T>) {

    let (btx, brx) = broadcast::channel();
    let (tx, rx) = mpsc::sync_channel(size);
    (   SyncSender {
            tx: Some(tx),
            broadcast_tx: btx.clone(),
            broadcast_rx: brx.clone(),
        },
        SyncReceiver {
            rx: Some(rx),
            broadcast_tx: btx,
            broadcast_rx: brx,
        }
    )
}

impl<T> Drop for SyncSender<T> {
    fn drop(&mut self) {
        {
            self.tx.take();
        }
        self.broadcast_tx.notify()
    }
}
<|endoftext|>


<commit_before>//! Various spin lock definitions

use core::cell::UnsafeCell;

use core::ops::{Deref, DerefMut};
use core::sync::atomic::{AtomicBool, Ordering};

use hal::{local_irq_save, local_irq_restore};

pub use spin::Mutex as SpinLock;
pub use spin::MutexGuard as SpinGuard;

pub use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};

pub struct InterruptSpinLock<T> {
    data: UnsafeCell<T>,
    pub lock: AtomicBool,
}

pub struct InterruptSpinGuard<'a, T: 'a> {
    lock: &'a AtomicBool,
    data: &'a UnsafeCell<T>,
    irq_state: usize,
}

impl<T> InterruptSpinLock<T> {
    pub const fn new(data: T) -> Self {
        InterruptSpinLock {
            data: UnsafeCell::new(data),
            lock: AtomicBool::new(false),
        }
    }

    pub fn lock<'a>(&'a self) -> InterruptSpinGuard<'a, T> {
        let state = local_irq_save();

        while self.lock.compare_and_swap(false, true, Ordering::SeqCst) {
        }

        InterruptSpinGuard {
            lock: &self.lock,
            data: &self.data,
            irq_state: state,
        }
    }
}

unsafe impl<T> Send for InterruptSpinLock<T> {}
unsafe impl<T> Sync for InterruptSpinLock<T> {}

impl<'a, T> Deref for InterruptSpinGuard<'a, T> {
    type Target = T;

    fn deref<'b>(&'b self) -> &'b T {
        unsafe { & *self.data.get() }
    }
}

impl<'a, T> DerefMut for InterruptSpinGuard<'a, T> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        unsafe { &mut *self.data.get() }
    }
}

impl<'a, T> Drop for InterruptSpinGuard<'a, T> {
    fn drop(&mut self) {
        self.lock.store(false, Ordering::SeqCst);
        local_irq_restore(self.irq_state);
    }
}
<commit_msg>sync/spin: Fix some issues detected by clippy<commit_after>//! Various spin lock definitions

use core::cell::UnsafeCell;

use core::ops::{Deref, DerefMut};
use core::sync::atomic::{AtomicBool, Ordering};

use hal::{local_irq_save, local_irq_restore};

pub use spin::Mutex as SpinLock;
pub use spin::MutexGuard as SpinGuard;

pub use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};

pub struct InterruptSpinLock<T> {
    data: UnsafeCell<T>,
    pub lock: AtomicBool,
}

pub struct InterruptSpinGuard<'a, T: 'a> {
    lock: &'a AtomicBool,
    data: &'a UnsafeCell<T>,
    irq_state: usize,
}

impl<T> InterruptSpinLock<T> {
    pub const fn new(data: T) -> Self {
        InterruptSpinLock {
            data: UnsafeCell::new(data),
            lock: AtomicBool::new(false),
        }
    }

    pub fn lock(&self) -> InterruptSpinGuard<T> {
        let state = local_irq_save();

        while self.lock.compare_and_swap(false, true, Ordering::SeqCst) {
        }

        InterruptSpinGuard {
            lock: &self.lock,
            data: &self.data,
            irq_state: state,
        }
    }
}

unsafe impl<T> Send for InterruptSpinLock<T> {}
unsafe impl<T> Sync for InterruptSpinLock<T> {}

impl<'a, T> Deref for InterruptSpinGuard<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { & *self.data.get() }
    }
}

impl<'a, T> DerefMut for InterruptSpinGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

impl<'a, T> Drop for InterruptSpinGuard<'a, T> {
    fn drop(&mut self) {
        self.lock.store(false, Ordering::SeqCst);
        local_irq_restore(self.irq_state);
    }
}
<|endoftext|>


<commit_before>//! Tables making up a font file.

#![allow(non_camel_case_types, non_snake_case)]

macro_rules! spec {
    ($(#[$attribute:meta])* pub $structure:ident {
        $($field:ident ($($kind:tt)+) $(|$($argument:ident),+| $body:block)*,)+
    }) => (
        declare! {
            $(#[$attribute])* pub $structure {
                $($field ($($kind)+),)+
            }
        }
        implement! {
            pub $structure {
                $($field ($($kind)+) $(|$($argument),+| $body)*,)+
            }
        }
    );
}

macro_rules! declare {
    ($(#[$attribute:meta])* pub $structure:ident {
        $($field:ident ($kind:ty),)+
    }) => (itemize! {
        $(#[$attribute])*
        #[derive(Clone, Debug, Default, Eq, PartialEq)]
        pub struct $structure {
            $(pub $field: $kind,)+
        }
    });
}

macro_rules! implement {
    (pub $structure:ident {
        $($field:ident ($($kind:tt)+) $(|$($argument:ident),+| $body:block)*,)+
    }) => (
        impl ::band::Value for $structure {
            fn read<T: ::band::Band>(band: &mut T) -> ::Result<Self> {
                let mut table = $structure::default();
                $(
                    table.$field = read_field!($structure, band, table, [$($kind)+]
                                               $(|$($argument),+| $body)*);
                )+
                Ok(table)
            }
        }
    );
}

macro_rules! itemize(
    ($code:item) => ($code);
);

macro_rules! read_field(
    ($structure:ident, $band:ident, $table:ident, [$kind:ty]
                                                  |$gang:ident, $chair:ident| $body:block) => ({
        #[inline(always)]
        #[allow(unused_variables)]
        fn read<T: ::band::Band>($gang: &mut T, $chair: &$structure) -> ::Result<$kind> $body
        try!(read($band, &$table))
    });
    ($structure:ident, $band:expr, $table:expr, [$kind:ty]) => ({
        try!(::band::Value::read($band))
    });
);

macro_rules! read_vector(
    ($band:ident, $count:expr) => ({
        let count = $count as usize;
        let mut values = Vec::with_capacity(count);
        for _ in 0..count {
            values.push(try!(::band::Value::read($band)));
        }
        Ok(values)
    });
);

mod char_mapping;
mod font_header;
mod horizontal_header;
mod horizontal_metrics;
mod maximum_profile;
mod naming_table;
mod offset_table;
mod postscript;
mod windows_metrics;

pub use self::char_mapping::{CharMapping, CharMappingHeader, CharMappingRecord};
pub use self::char_mapping::{CharMappingEncoding, CharMappingEncoding4, CharMappingEncoding6};
pub use self::font_header::FontHeader;
pub use self::horizontal_header::HorizontalHeader;
pub use self::horizontal_metrics::HorizontalMetrics;
pub use self::maximum_profile::{MaximumProfile, MaximumProfile05, MaximumProfile10};
pub use self::naming_table::{NamingTable, NamingTable0, NamingTable1};
pub use self::naming_table::{NameRecord, LanguageTagRecord};
pub use self::offset_table::{OffsetTable, OffsetTableHeader, OffsetTableRecord};
pub use self::postscript::{PostScript, PostScript10, PostScript30};
pub use self::windows_metrics::{WindowsMetrics, WindowsMetrics3, WindowsMetrics5};
<commit_msg>Export LongHorizontalMetric<commit_after>//! Tables making up a font file.

#![allow(non_camel_case_types, non_snake_case)]

macro_rules! spec {
    ($(#[$attribute:meta])* pub $structure:ident {
        $($field:ident ($($kind:tt)+) $(|$($argument:ident),+| $body:block)*,)+
    }) => (
        declare! {
            $(#[$attribute])* pub $structure {
                $($field ($($kind)+),)+
            }
        }
        implement! {
            pub $structure {
                $($field ($($kind)+) $(|$($argument),+| $body)*,)+
            }
        }
    );
}

macro_rules! declare {
    ($(#[$attribute:meta])* pub $structure:ident {
        $($field:ident ($kind:ty),)+
    }) => (itemize! {
        $(#[$attribute])*
        #[derive(Clone, Debug, Default, Eq, PartialEq)]
        pub struct $structure {
            $(pub $field: $kind,)+
        }
    });
}

macro_rules! implement {
    (pub $structure:ident {
        $($field:ident ($($kind:tt)+) $(|$($argument:ident),+| $body:block)*,)+
    }) => (
        impl ::band::Value for $structure {
            fn read<T: ::band::Band>(band: &mut T) -> ::Result<Self> {
                let mut table = $structure::default();
                $(
                    table.$field = read_field!($structure, band, table, [$($kind)+]
                                               $(|$($argument),+| $body)*);
                )+
                Ok(table)
            }
        }
    );
}

macro_rules! itemize(
    ($code:item) => ($code);
);

macro_rules! read_field(
    ($structure:ident, $band:ident, $table:ident, [$kind:ty]
                                                  |$gang:ident, $chair:ident| $body:block) => ({
        #[inline(always)]
        #[allow(unused_variables)]
        fn read<T: ::band::Band>($gang: &mut T, $chair: &$structure) -> ::Result<$kind> $body
        try!(read($band, &$table))
    });
    ($structure:ident, $band:expr, $table:expr, [$kind:ty]) => ({
        try!(::band::Value::read($band))
    });
);

macro_rules! read_vector(
    ($band:ident, $count:expr) => ({
        let count = $count as usize;
        let mut values = Vec::with_capacity(count);
        for _ in 0..count {
            values.push(try!(::band::Value::read($band)));
        }
        Ok(values)
    });
);

mod char_mapping;
mod font_header;
mod horizontal_header;
mod horizontal_metrics;
mod maximum_profile;
mod naming_table;
mod offset_table;
mod postscript;
mod windows_metrics;

pub use self::char_mapping::{CharMapping, CharMappingHeader, CharMappingRecord};
pub use self::char_mapping::{CharMappingEncoding, CharMappingEncoding4, CharMappingEncoding6};
pub use self::font_header::FontHeader;
pub use self::horizontal_header::HorizontalHeader;
pub use self::horizontal_metrics::{HorizontalMetrics, LongHorizontalMetric};
pub use self::maximum_profile::{MaximumProfile, MaximumProfile05, MaximumProfile10};
pub use self::naming_table::{NamingTable, NamingTable0, NamingTable1};
pub use self::naming_table::{NameRecord, LanguageTagRecord};
pub use self::offset_table::{OffsetTable, OffsetTableHeader, OffsetTableRecord};
pub use self::postscript::{PostScript, PostScript10, PostScript30};
pub use self::windows_metrics::{WindowsMetrics, WindowsMetrics3, WindowsMetrics5};
<|endoftext|>


<commit_before>use crate::utils::span_lint;
use rustc::hir;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use syntax::ast;
use syntax::source_map::Span;

declare_clippy_lint! {
    /// **What it does:** it lints if an exported function, method, trait method with default impl,
    /// or trait method impl is not `#[inline]`.
    ///
    /// **Why is this bad?** In general, it is not. Functions can be inlined across
    /// crates when that's profitable as long as any form of LTO is used. When LTO is disabled,
    /// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates
    /// might intend for most of the methods in their public API to be able to be inlined across
    /// crates even when LTO is disabled. For these types of crates, enabling this lint might make
    /// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and
    /// then opt out for specific methods where this might not make sense.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// pub fn foo() {} // missing #[inline]
    /// fn ok() {} // ok
    /// #[inline] pub fn bar() {} // ok
    /// #[inline(always)] pub fn baz() {} // ok
    ///
    /// pub trait Bar {
    ///   fn bar(); // ok
    ///   fn def_bar() {} // missing #[inline]
    /// }
    ///
    /// struct Baz;
    /// impl Baz {
    ///    fn priv() {} // ok
    /// }
    ///
    /// impl Bar for Baz {
    ///   fn bar() {} // ok - Baz is not exported
    /// }
    ///
    /// pub struct PubBaz;
    /// impl PubBaz {
    ///    fn priv() {} // ok
    ///    pub not_ptriv() {} // missing #[inline]
    /// }
    ///
    /// impl Bar for PubBaz {
    ///    fn bar() {} // missing #[inline]
    ///    fn def_bar() {} // missing #[inline]
    /// }
    /// ```
    pub MISSING_INLINE_IN_PUBLIC_ITEMS,
    restriction,
    "detects missing #[inline] attribute for public callables (functions, trait methods, methods...)"
}

fn check_missing_inline_attrs(cx: &LateContext<'_, '_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
    let has_inline = attrs.iter().any(|a| a.check_name(sym!(inline)));
    if !has_inline {
        span_lint(
            cx,
            MISSING_INLINE_IN_PUBLIC_ITEMS,
            sp,
            &format!("missing `#[inline]` for {}", desc),
        );
    }
}

fn is_executable<'a>(cx: &LateContext<'a, '_>) -> bool {
    use rustc::session::config::CrateType;

    cx.tcx.sess.crate_types.get().iter().any(|t: &CrateType| match t {
        CrateType::Executable => true,
        _ => false,
    })
}

declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline {
    fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item) {
        if is_executable(cx) {
            return;
        }

        if !cx.access_levels.is_exported(it.hir_id) {
            return;
        }
        match it.node {
            hir::ItemKind::Fn(..) => {
                let desc = "a function";
                check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
            },
            hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, ref _bounds, ref trait_items) => {
                // note: we need to check if the trait is exported so we can't use
                // `LateLintPass::check_trait_item` here.
                for tit in trait_items {
                    let tit_ = cx.tcx.hir().trait_item(tit.id);
                    match tit_.node {
                        hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
                        hir::TraitItemKind::Method(..) => {
                            if tit.defaultness.has_value() {
                                // trait method with default body needs inline in case
                                // an impl is not provided
                                let desc = "a default trait method";
                                let item = cx.tcx.hir().expect_trait_item(tit.id.hir_id);
                                check_missing_inline_attrs(cx, &item.attrs, item.span, desc);
                            }
                        },
                    }
                }
            },
            hir::ItemKind::Const(..)
            | hir::ItemKind::Enum(..)
            | hir::ItemKind::Mod(..)
            | hir::ItemKind::Static(..)
            | hir::ItemKind::Struct(..)
            | hir::ItemKind::TraitAlias(..)
            | hir::ItemKind::GlobalAsm(..)
            | hir::ItemKind::Ty(..)
            | hir::ItemKind::Union(..)
            | hir::ItemKind::Existential(..)
            | hir::ItemKind::ExternCrate(..)
            | hir::ItemKind::ForeignMod(..)
            | hir::ItemKind::Impl(..)
            | hir::ItemKind::Use(..) => {},
        };
    }

    fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem) {
        use rustc::ty::{ImplContainer, TraitContainer};
        if is_executable(cx) {
            return;
        }

        // If the item being implemented is not exported, then we don't need #[inline]
        if !cx.access_levels.is_exported(impl_item.hir_id) {
            return;
        }

        let desc = match impl_item.node {
            hir::ImplItemKind::Method(..) => "a method",
            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) | hir::ImplItemKind::Existential(_) => return,
        };

        let def_id = cx.tcx.hir().local_def_id_from_hir_id(impl_item.hir_id);
        let trait_def_id = match cx.tcx.associated_item(def_id).container {
            TraitContainer(cid) => Some(cid),
            ImplContainer(cid) => cx.tcx.impl_trait_ref(cid).map(|t| t.def_id),
        };

        if let Some(trait_def_id) = trait_def_id {
            if cx.tcx.hir().as_local_node_id(trait_def_id).is_some() && !cx.access_levels.is_exported(impl_item.hir_id)
            {
                // If a trait is being implemented for an item, and the
                // trait is not exported, we don't need #[inline]
                return;
            }
        }

        check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc);
    }
}
<commit_msg>Remove another unnecessary lifetime<commit_after>use crate::utils::span_lint;
use rustc::hir;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use syntax::ast;
use syntax::source_map::Span;

declare_clippy_lint! {
    /// **What it does:** it lints if an exported function, method, trait method with default impl,
    /// or trait method impl is not `#[inline]`.
    ///
    /// **Why is this bad?** In general, it is not. Functions can be inlined across
    /// crates when that's profitable as long as any form of LTO is used. When LTO is disabled,
    /// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates
    /// might intend for most of the methods in their public API to be able to be inlined across
    /// crates even when LTO is disabled. For these types of crates, enabling this lint might make
    /// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and
    /// then opt out for specific methods where this might not make sense.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// pub fn foo() {} // missing #[inline]
    /// fn ok() {} // ok
    /// #[inline] pub fn bar() {} // ok
    /// #[inline(always)] pub fn baz() {} // ok
    ///
    /// pub trait Bar {
    ///   fn bar(); // ok
    ///   fn def_bar() {} // missing #[inline]
    /// }
    ///
    /// struct Baz;
    /// impl Baz {
    ///    fn priv() {} // ok
    /// }
    ///
    /// impl Bar for Baz {
    ///   fn bar() {} // ok - Baz is not exported
    /// }
    ///
    /// pub struct PubBaz;
    /// impl PubBaz {
    ///    fn priv() {} // ok
    ///    pub not_ptriv() {} // missing #[inline]
    /// }
    ///
    /// impl Bar for PubBaz {
    ///    fn bar() {} // missing #[inline]
    ///    fn def_bar() {} // missing #[inline]
    /// }
    /// ```
    pub MISSING_INLINE_IN_PUBLIC_ITEMS,
    restriction,
    "detects missing #[inline] attribute for public callables (functions, trait methods, methods...)"
}

fn check_missing_inline_attrs(cx: &LateContext<'_, '_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
    let has_inline = attrs.iter().any(|a| a.check_name(sym!(inline)));
    if !has_inline {
        span_lint(
            cx,
            MISSING_INLINE_IN_PUBLIC_ITEMS,
            sp,
            &format!("missing `#[inline]` for {}", desc),
        );
    }
}

fn is_executable(cx: &LateContext<'_, '_>) -> bool {
    use rustc::session::config::CrateType;

    cx.tcx.sess.crate_types.get().iter().any(|t: &CrateType| match t {
        CrateType::Executable => true,
        _ => false,
    })
}

declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline {
    fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item) {
        if is_executable(cx) {
            return;
        }

        if !cx.access_levels.is_exported(it.hir_id) {
            return;
        }
        match it.node {
            hir::ItemKind::Fn(..) => {
                let desc = "a function";
                check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
            },
            hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, ref _bounds, ref trait_items) => {
                // note: we need to check if the trait is exported so we can't use
                // `LateLintPass::check_trait_item` here.
                for tit in trait_items {
                    let tit_ = cx.tcx.hir().trait_item(tit.id);
                    match tit_.node {
                        hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
                        hir::TraitItemKind::Method(..) => {
                            if tit.defaultness.has_value() {
                                // trait method with default body needs inline in case
                                // an impl is not provided
                                let desc = "a default trait method";
                                let item = cx.tcx.hir().expect_trait_item(tit.id.hir_id);
                                check_missing_inline_attrs(cx, &item.attrs, item.span, desc);
                            }
                        },
                    }
                }
            },
            hir::ItemKind::Const(..)
            | hir::ItemKind::Enum(..)
            | hir::ItemKind::Mod(..)
            | hir::ItemKind::Static(..)
            | hir::ItemKind::Struct(..)
            | hir::ItemKind::TraitAlias(..)
            | hir::ItemKind::GlobalAsm(..)
            | hir::ItemKind::Ty(..)
            | hir::ItemKind::Union(..)
            | hir::ItemKind::Existential(..)
            | hir::ItemKind::ExternCrate(..)
            | hir::ItemKind::ForeignMod(..)
            | hir::ItemKind::Impl(..)
            | hir::ItemKind::Use(..) => {},
        };
    }

    fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem) {
        use rustc::ty::{ImplContainer, TraitContainer};
        if is_executable(cx) {
            return;
        }

        // If the item being implemented is not exported, then we don't need #[inline]
        if !cx.access_levels.is_exported(impl_item.hir_id) {
            return;
        }

        let desc = match impl_item.node {
            hir::ImplItemKind::Method(..) => "a method",
            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) | hir::ImplItemKind::Existential(_) => return,
        };

        let def_id = cx.tcx.hir().local_def_id_from_hir_id(impl_item.hir_id);
        let trait_def_id = match cx.tcx.associated_item(def_id).container {
            TraitContainer(cid) => Some(cid),
            ImplContainer(cid) => cx.tcx.impl_trait_ref(cid).map(|t| t.def_id),
        };

        if let Some(trait_def_id) = trait_def_id {
            if cx.tcx.hir().as_local_node_id(trait_def_id).is_some() && !cx.access_levels.is_exported(impl_item.hir_id)
            {
                // If a trait is being implemented for an item, and the
                // trait is not exported, we don't need #[inline]
                return;
            }
        }

        check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc);
    }
}
<|endoftext|>


<commit_before>//! The actual Turing machine
//!

use std::hash::Hash;
use super::transition::{Lookup, Transitions, TransitionKey};
use super::tape::{Tape, ConcreteTape};
use super::movement::Movement;

/// The actual Turing machine
pub struct Machine<Q, S> where Q: Clone + Eq + Hash, S: Clone + Eq + Hash  {
    state: Q,
    tape: ConcreteTape<S>,
    transitions: Transitions<Q, S>,
}

impl <Q, S> Machine<Q, S> where S: Clone + Eq + Hash, Q: Clone + Eq + Hash {
    /// Step the machine through one transition.
    pub fn step(&self) -> Option<Machine<Q, S>> {
        let symbol = self.tape.read();
        let key = TransitionKey::new(self.state.clone(), symbol);
        match self.transitions.lookup(&key) {
            Some(next) => {
                Some(Machine {
                    state : next.state.clone(),
                    tape : match next.movement {
                        Movement::Left => self.tape.write(next.symbol.clone()).left(),

                        Movement::Right => self.tape.write(next.symbol.clone()).right(),
                    },
                    transitions: self.transitions.clone(),
                })
            }
            None => None
        }
    }
}
<commit_msg>Test step function<commit_after>//! The actual Turing machine
//!

use std::hash::Hash;
use super::transition::{Lookup, Transitions, TransitionKey};
use super::tape::{Tape, ConcreteTape};
use super::movement::Movement;

/// The actual Turing machine
pub struct Machine<Q, S> where Q: Clone + Eq + Hash, S: Clone + Eq + Hash  {
    state: Q,
    tape: ConcreteTape<S>,
    transitions: Transitions<Q, S>,
}

impl <Q, S> Machine<Q, S> where S: Clone + Eq + Hash, Q: Clone + Eq + Hash {
    /// Create a Turing machine from a initial state, a tape and transistions
    pub fn new(q: Q, tape: ConcreteTape<S>, transitions: Transitions<Q, S>) -> Machine<Q, S> {
        Machine {
            state: q,
            tape: tape,
            transitions: transitions,
        }
    }

    /// Step the machine through one transition.
    pub fn step(&self) -> Option<Machine<Q, S>> {
        let symbol = self.tape.read();
        let key = TransitionKey::new(self.state.clone(), symbol);
        match self.transitions.lookup(&key) {
            Some(next) => {
                Some(Machine {
                    state : next.state.clone(),
                    tape : match next.movement {
                        Movement::Left => self.tape.write(next.symbol.clone()).left(),

                        Movement::Right => self.tape.write(next.symbol.clone()).right(),
                    },
                    transitions: self.transitions.clone(),
                })
            }
            None => None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::movement::Movement;
    use super::super::tape::TapeBuilder;
    use super::super::transition::{Transitions, TransitionKey, TransitionValue};

    #[test]
    fn should_step_through_a_program() {
        let m = Machine::new(
            0,
            TapeBuilder::with_blank("_")
                .with_current("I")
                .with_right_tape(vec!["I", "I"])
                .build(),
            Transitions::new()
                .insert(
                    TransitionKey::new(0, "I"),
                    TransitionValue::new(0, "I", Movement::Right))
                .insert(
                    TransitionKey::new(0, "_"),
                    TransitionValue::new(1, "I", Movement::Left))
                .insert(
                    TransitionKey::new(1, "I"),
                    TransitionValue::new(1, "I", Movement::Left))
                .insert(
                    TransitionKey::new(1, "_"),
                    TransitionValue::new(2, "_", Movement::Right))
        );

        match m.step() {
            Some(_) => assert!(true),
            None => assert!(false),
        }
    }
}
<|endoftext|>


<commit_before>use token::Token;
use error::Result;

use std::str::CharIndices;

pub struct Tokenizer<'a> {
    text: &'a str,
    chars: CharIndices<'a>,
    offset: usize,
}

impl<'a> Iterator for Tokenizer<'a> {
    type Item = Result<Token>;

    fn next(&mut self) -> Option<Result<Token>> {
        match self.parse() {
            Ok(Some(t)) => Some(Ok(t)),
            Ok(None) => None,
            Err(e) => Some(Err(e)),
        }
    }
}

impl<'a> Tokenizer<'a> {
    pub fn new(text: &str) -> Tokenizer {
        Tokenizer {
            text: text,
            chars: text.char_indices(),
            offset: 0,
        }
    }

    pub fn parse(&mut self) -> Result<Option<Token>> {
        let mut value = String::new();
        let mut start;
        while let Some((char_offset, curr_char)) = self.chars.next() {
            // Skip leading whitespace
            if curr_char.is_whitespace() {
                continue;
            } else {
                // First non-whitespace - save its offset to be the Token's offset
                value.push(curr_char);
                start = char_offset;
                while let Some((char_offset, curr_char)) = self.chars.next() {
                    // Stop when we reach whitespace
                    if curr_char.is_whitespace() {
                        break;
                    } else {
                        value.push(curr_char);
                    }
                }
            }
            return Ok(Some(Token { value: value, offset: Some(start) }))
        }
        return Ok(None)
    }
}

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

    #[test]
    fn it_returns_none_for_empty_string() {
        let mut tokenizer = Tokenizer::new("");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_none_for_only_whitespace() {
        let mut tokenizer = Tokenizer::new("     ");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_words() {
        // Without regard to Sass word validity
        let mut tokenizer = Tokenizer::new(" \n  div   aoeu  ");
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("div", 4))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("aoeu", 10))));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_curly_braces() {
        // Without regard to matching
        let mut tokenizer = Tokenizer::new("}a{");
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("}", 0))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("a", 1))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("{", 2))));
        assert_eq!(tokenizer.next(), None);
    }
}
<commit_msg>Tokenize single-character sass tokens like curly braces<commit_after>use token::Token;
use error::Result;

use std::str::CharIndices;
use std::iter::Peekable;

pub struct Tokenizer<'a> {
    text: &'a str,
    chars: Peekable<CharIndices<'a>>,
}

impl<'a> Iterator for Tokenizer<'a> {
    type Item = Result<Token>;

    fn next(&mut self) -> Option<Result<Token>> {
        match self.parse() {
            Ok(Some(t)) => Some(Ok(t)),
            Ok(None) => None,
            Err(e) => Some(Err(e)),
        }
    }
}

impl<'a> Tokenizer<'a> {
    pub fn new(text: &str) -> Tokenizer {
        Tokenizer {
            text: text,
            chars: text.char_indices().peekable(),
        }
    }

    pub fn parse(&mut self) -> Result<Option<Token>> {
        let mut value = String::new();
        let mut start;
        while let Some((char_offset, curr_char)) = self.chars.next() {
            // Skip leading whitespace
            if curr_char.is_whitespace() {
                continue;
            } else {
                if is_single_char_token(curr_char) {
                    return Ok(Some(Token {
                        value: curr_char.to_string(),
                        offset: Some(char_offset),
                    }))
                } else {
                    // Start of a multi-char token
                    // First non-whitespace - save its offset to be the Token's offset
                    value.push(curr_char);
                    start = char_offset;
                    while let Some(&(next_char_offset, next_char)) = self.chars.peek() {
                        // Stop when we reach a non-word char
                        if next_char.is_whitespace() || is_single_char_token(next_char) {
                            break;
                        } else {
                            value.push(next_char);
                            self.chars.next();
                        }
                    }
                    return Ok(Some(Token { value: value, offset: Some(start) }))
                }
            }
        }
        return Ok(None)
    }
}

fn is_single_char_token(ch: char) -> bool {
    "{}:".chars().any(|c| c == ch)
}

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

    #[test]
    fn it_returns_none_for_empty_string() {
        let mut tokenizer = Tokenizer::new("");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_none_for_only_whitespace() {
        let mut tokenizer = Tokenizer::new("     ");
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_returns_words() {
        // Without regard to Sass word validity
        let mut tokenizer = Tokenizer::new(" \n  div   aoeu  ");
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("div", 4))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("aoeu", 10))));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_curly_braces() {
        // Without regard to matching
        let mut tokenizer = Tokenizer::new("{}}a{ blue}");
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("{", 0))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("}", 1))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("}", 2))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("a", 3))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("{", 4))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("blue", 6))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("}", 10))));
        assert_eq!(tokenizer.next(), None);
    }

    #[test]
    fn it_separates_colon() {
        let mut tokenizer = Tokenizer::new(":invalid: property::");
        assert_eq!(tokenizer.next(), Some(Ok(Token::new(":", 0))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("invalid", 1))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new(":", 8))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new("property", 10))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new(":", 18))));
        assert_eq!(tokenizer.next(), Some(Ok(Token::new(":", 19))));
        assert_eq!(tokenizer.next(), None);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;

use approx::ApproxEq;
use matrix::{Matrix, Matrix4, ToMatrix4};
use num::{BaseNum, BaseFloat, zero, one};
use point::{Point, Point3};
use ray::Ray;
use rotation::{Rotation, Rotation3};
use vector::{Vector, Vector3};

/// A trait representing an [affine
/// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that
/// can be applied to points or vectors. An affine transformation is one which
pub trait Transform<S: BaseNum, V: Vector<S>, P: Point<S,V>>: Sized {
    /// Create an identity transformation. That is, a transformation which
    /// does nothing.
    fn identity() -> Self;

    /// Create a transformation that rotates a vector to look at `center` from
    /// `eye`, using `up` for orientation.
    fn look_at(eye: &P, center: &P, up: &V) -> Self;

    /// Transform a vector using this transform.
    fn transform_vector(&self, vec: &V) -> V;

    /// Transform a point using this transform.
    fn transform_point(&self, point: &P) -> P;

    /// Transform a ray using this transform.
    #[inline]
    fn transform_ray(&self, ray: &Ray<P,V>) -> Ray<P,V> {
        Ray::new(self.transform_point(&ray.origin), self.transform_vector(&ray.direction))
    }

    /// Transform a vector as a point using this transform.
    #[inline]
    fn transform_as_point(&self, vec: &V) -> V {
        self.transform_point(&Point::from_vec(vec)).to_vec()
    }

    /// Combine this transform with another, yielding a new transformation
    /// which has the effects of both.
    fn concat(&self, other: &Self) -> Self;

    /// Create a transform that "un-does" this one.
    fn invert(&self) -> Option<Self>;

    /// Combine this transform with another, in-place.
    #[inline]
    fn concat_self(&mut self, other: &Self) {
        *self = Transform::concat(self, other);
    }

    /// Invert this transform in-place, failing if the transformation is not
    /// invertible.
    #[inline]
    fn invert_self(&mut self) {
        *self = self.invert().unwrap()
    }
}

/// A generic transformation consisting of a rotation,
/// displacement vector and scale amount.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Decomposed<S, V, R> {
    pub scale: S,
    pub rot: R,
    pub disp: V,
}

impl<S: BaseFloat, V: Vector<S>, P: Point<S, V>, R: Rotation<S, V, P>> Transform<S, V, P> for Decomposed<S, V, R> {
    #[inline]
    fn identity() -> Decomposed<S, V, R> {
        Decomposed {
            scale: one(),
            rot: Rotation::identity(),
            disp: zero(),
        }
    }

    #[inline]
    fn look_at(eye: &P, center: &P, up: &V) -> Decomposed<S, V, R> {
        let origin: P = Point::origin();
        let rot: R = Rotation::look_at(&center.sub_p(eye), up);
        let disp: V = rot.rotate_vector(&origin.sub_p(eye));
        Decomposed {
            scale: one(),
            rot: rot,
            disp: disp,
        }
    }

    #[inline]
    fn transform_vector(&self, vec: &V) -> V {
        self.rot.rotate_vector(&vec.mul_s(self.scale.clone()))
    }

    #[inline]
    fn transform_point(&self, point: &P) -> P {
        self.rot.rotate_point(&point.mul_s(self.scale.clone())).add_v(&self.disp)
    }

    fn concat(&self, other: &Decomposed<S, V, R>) -> Decomposed<S, V, R> {
        Decomposed {
            scale: self.scale * other.scale,
            rot: self.rot.concat(&other.rot),
            disp: self.transform_as_point(&other.disp),
        }
    }

    fn invert(&self) -> Option<Decomposed<S, V, R>> {
        if self.scale.approx_eq(&zero()) {
            None
        } else {
            let s = one::<S>() / self.scale;
            let r = self.rot.invert();
            let d = r.rotate_vector(&self.disp).mul_s(-s);
            Some(Decomposed {
                scale: s,
                rot: r,
                disp: d,
            })
        }
    }
}

pub trait Transform3<S>: Transform<S, Vector3<S>, Point3<S>>+ ToMatrix4<S> {}

impl<S: BaseFloat + 'static, R: Rotation3<S>> ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
    fn to_matrix4(&self) -> Matrix4<S> {
        let mut m = self.rot.to_matrix3().mul_s(self.scale.clone()).to_matrix4();
        m.w = self.disp.extend(one());
        m
    }
}

impl<S: BaseFloat, R: Rotation3<S>> Transform3<S> for Decomposed<S,Vector3<S>,R> where S: 'static {}

impl<S: BaseFloat, R: fmt::Debug + Rotation3<S>> fmt::Debug for Decomposed<S,Vector3<S>,R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "(scale({:?}), rot({:?}), disp{:?})",
            self.scale, self.rot, self.disp)
    }
}

/// A homogeneous transformation matrix.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct AffineMatrix3<S> {
    pub mat: Matrix4<S>,
}

impl<S: BaseFloat + 'static> Transform<S, Vector3<S>, Point3<S>> for AffineMatrix3<S> {
    #[inline]
    fn identity() -> AffineMatrix3<S> {
       AffineMatrix3 { mat: Matrix4::identity() }
    }

    #[inline]
    fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> AffineMatrix3<S> {
        AffineMatrix3 { mat: Matrix4::look_at(eye, center, up) }
    }

    #[inline]
    fn transform_vector(&self, vec: &Vector3<S>) -> Vector3<S> {
        self.mat.mul_v(&vec.extend(zero())).truncate()
    }

    #[inline]
    fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
        Point3::from_homogeneous(&self.mat.mul_v(&point.to_homogeneous()))
    }

    #[inline]
    fn concat(&self, other: &AffineMatrix3<S>) -> AffineMatrix3<S> {
        AffineMatrix3 { mat: self.mat.mul_m(&other.mat) }
    }

    #[inline]
    fn invert(&self) -> Option<AffineMatrix3<S>> {
        self.mat.invert().map(|m| AffineMatrix3{ mat: m })
    }
}

impl<S: BaseNum> ToMatrix4<S> for AffineMatrix3<S> {
    #[inline] fn to_matrix4(&self) -> Matrix4<S> { self.mat.clone() }
}

impl<S: BaseFloat> Transform3<S> for AffineMatrix3<S> where S: 'static {}
<commit_msg>Add a phantom type annotation on Transform.<commit_after>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;

use approx::ApproxEq;
use matrix::{Matrix, Matrix4, ToMatrix4};
use num::{BaseNum, BaseFloat, zero, one};
use point::{Point, Point3};
use ray::Ray;
use rotation::{Rotation, Rotation3};
use std::marker::PhantomFn;
use vector::{Vector, Vector3};

/// A trait representing an [affine
/// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that
/// can be applied to points or vectors. An affine transformation is one which
pub trait Transform<S: BaseNum, V: Vector<S>, P: Point<S,V>>: Sized + PhantomFn<S> {
    /// Create an identity transformation. That is, a transformation which
    /// does nothing.
    fn identity() -> Self;

    /// Create a transformation that rotates a vector to look at `center` from
    /// `eye`, using `up` for orientation.
    fn look_at(eye: &P, center: &P, up: &V) -> Self;

    /// Transform a vector using this transform.
    fn transform_vector(&self, vec: &V) -> V;

    /// Transform a point using this transform.
    fn transform_point(&self, point: &P) -> P;

    /// Transform a ray using this transform.
    #[inline]
    fn transform_ray(&self, ray: &Ray<P,V>) -> Ray<P,V> {
        Ray::new(self.transform_point(&ray.origin), self.transform_vector(&ray.direction))
    }

    /// Transform a vector as a point using this transform.
    #[inline]
    fn transform_as_point(&self, vec: &V) -> V {
        self.transform_point(&Point::from_vec(vec)).to_vec()
    }

    /// Combine this transform with another, yielding a new transformation
    /// which has the effects of both.
    fn concat(&self, other: &Self) -> Self;

    /// Create a transform that "un-does" this one.
    fn invert(&self) -> Option<Self>;

    /// Combine this transform with another, in-place.
    #[inline]
    fn concat_self(&mut self, other: &Self) {
        *self = Transform::concat(self, other);
    }

    /// Invert this transform in-place, failing if the transformation is not
    /// invertible.
    #[inline]
    fn invert_self(&mut self) {
        *self = self.invert().unwrap()
    }
}

/// A generic transformation consisting of a rotation,
/// displacement vector and scale amount.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Decomposed<S, V, R> {
    pub scale: S,
    pub rot: R,
    pub disp: V,
}

impl<S: BaseFloat, V: Vector<S>, P: Point<S, V>, R: Rotation<S, V, P>> Transform<S, V, P> for Decomposed<S, V, R> {
    #[inline]
    fn identity() -> Decomposed<S, V, R> {
        Decomposed {
            scale: one(),
            rot: Rotation::identity(),
            disp: zero(),
        }
    }

    #[inline]
    fn look_at(eye: &P, center: &P, up: &V) -> Decomposed<S, V, R> {
        let origin: P = Point::origin();
        let rot: R = Rotation::look_at(&center.sub_p(eye), up);
        let disp: V = rot.rotate_vector(&origin.sub_p(eye));
        Decomposed {
            scale: one(),
            rot: rot,
            disp: disp,
        }
    }

    #[inline]
    fn transform_vector(&self, vec: &V) -> V {
        self.rot.rotate_vector(&vec.mul_s(self.scale.clone()))
    }

    #[inline]
    fn transform_point(&self, point: &P) -> P {
        self.rot.rotate_point(&point.mul_s(self.scale.clone())).add_v(&self.disp)
    }

    fn concat(&self, other: &Decomposed<S, V, R>) -> Decomposed<S, V, R> {
        Decomposed {
            scale: self.scale * other.scale,
            rot: self.rot.concat(&other.rot),
            disp: self.transform_as_point(&other.disp),
        }
    }

    fn invert(&self) -> Option<Decomposed<S, V, R>> {
        if self.scale.approx_eq(&zero()) {
            None
        } else {
            let s = one::<S>() / self.scale;
            let r = self.rot.invert();
            let d = r.rotate_vector(&self.disp).mul_s(-s);
            Some(Decomposed {
                scale: s,
                rot: r,
                disp: d,
            })
        }
    }
}

pub trait Transform3<S>: Transform<S, Vector3<S>, Point3<S>>+ ToMatrix4<S> {}

impl<S: BaseFloat + 'static, R: Rotation3<S>> ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
    fn to_matrix4(&self) -> Matrix4<S> {
        let mut m = self.rot.to_matrix3().mul_s(self.scale.clone()).to_matrix4();
        m.w = self.disp.extend(one());
        m
    }
}

impl<S: BaseFloat, R: Rotation3<S>> Transform3<S> for Decomposed<S,Vector3<S>,R> where S: 'static {}

impl<S: BaseFloat, R: fmt::Debug + Rotation3<S>> fmt::Debug for Decomposed<S,Vector3<S>,R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "(scale({:?}), rot({:?}), disp{:?})",
            self.scale, self.rot, self.disp)
    }
}

/// A homogeneous transformation matrix.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct AffineMatrix3<S> {
    pub mat: Matrix4<S>,
}

impl<S: BaseFloat + 'static> Transform<S, Vector3<S>, Point3<S>> for AffineMatrix3<S> {
    #[inline]
    fn identity() -> AffineMatrix3<S> {
       AffineMatrix3 { mat: Matrix4::identity() }
    }

    #[inline]
    fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> AffineMatrix3<S> {
        AffineMatrix3 { mat: Matrix4::look_at(eye, center, up) }
    }

    #[inline]
    fn transform_vector(&self, vec: &Vector3<S>) -> Vector3<S> {
        self.mat.mul_v(&vec.extend(zero())).truncate()
    }

    #[inline]
    fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
        Point3::from_homogeneous(&self.mat.mul_v(&point.to_homogeneous()))
    }

    #[inline]
    fn concat(&self, other: &AffineMatrix3<S>) -> AffineMatrix3<S> {
        AffineMatrix3 { mat: self.mat.mul_m(&other.mat) }
    }

    #[inline]
    fn invert(&self) -> Option<AffineMatrix3<S>> {
        self.mat.invert().map(|m| AffineMatrix3{ mat: m })
    }
}

impl<S: BaseNum> ToMatrix4<S> for AffineMatrix3<S> {
    #[inline] fn to_matrix4(&self) -> Matrix4<S> { self.mat.clone() }
}

impl<S: BaseFloat> Transform3<S> for AffineMatrix3<S> where S: 'static {}
<|endoftext|>


<commit_before>//! Transports for communicating with the docker daemon

extern crate hyper;
extern crate mime;
extern crate unix_socket;

use hyper::Client;
use hyper::client;
use self::hyper::buffer::BufReader;
use self::hyper::http::{ parse_response, RawStatus };
use self::hyper::http::HttpReader::EofReader;
use self::hyper::header::ContentType;
use self::hyper::status::StatusCode;
use hyper::method::Method;
use self::mime::{ Attr, Mime, Value };
use self::mime::TopLevel::Application;
use self::mime::SubLevel::Json;
use std::ops::DerefMut;
use std::io::{ Error, ErrorKind, Read, Result, Write };
use unix_socket::UnixStream;

fn lift_status_err(status: u16) -> Result<Box<Read>> {
  match status {
    400 => Err(Error::new(ErrorKind::InvalidInput, "bad parameter")),
    404 => Err(Error::new(ErrorKind::InvalidInput, "not found")),
    406 => Err(Error::new(ErrorKind::InvalidInput, "not acceptable")),
    409 => Err(Error::new(ErrorKind::InvalidInput, "conflict found")),
    500 => Err(Error::new(ErrorKind::InvalidInput, "interal server error")),
     _  => unreachable!()
  }
}

#[doc(hidden)]
pub struct Body<'a> {
 read: &'a mut Box<&'a mut Read>,
 size: u64
}

impl<'a> Body<'a> {
  /// Create a new body instance
  pub fn new(read: &'a mut Box<&'a mut Read>, size: u64) -> Body<'a> {
    Body { read: read, size: size }
  }
}

/// Primary interface for communicating with docker daemon
pub trait Transport {
  fn request(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<String> {
    let mut res = match self.stream(method, endpoint, body) {
      Ok(r) => r,
      Err(e) => panic!("failed request {:?}", e)
    };
    let mut body = String::new();
    res.read_to_string(&mut body).map(|_| body)
  }

  fn stream(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<Box<Read>>;
}

impl Transport for UnixStream {
  fn stream(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<Box<Read>> {
    let method_str = match method {
      Method::Put    => "PUT",
      Method::Post   => "POST",
      Method::Delete => "DELETE",
               _     => "GET"
    };
    let req = format!("{} {} HTTP/1.0\r\n\r\n", method_str, endpoint);
    try!(self.write_all(req.as_bytes()));
    // read the body -- https://github.com/hyperium/hyper/blob/06d072bca1b4af3507af370cbd0ca2ac8f64fc00/src/client/response.rs#L36-L74
    let cloned = try!(self.try_clone());
    let mut stream = BufReader::new(cloned);
    let res = parse_response(&mut stream).unwrap();
    match res.subject {
      RawStatus(200, _) | RawStatus(201, _) | RawStatus(101, _) =>
        Ok(Box::new(EofReader(stream))),
      RawStatus(204, _) =>
        Ok(Box::new(BufReader::new("".as_bytes()))),
      RawStatus(status, _) =>
        lift_status_err(status)
    }
  }
}

impl Transport for (Client, String) {
  fn stream(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<Box<Read>> {
    let uri = format!("{}{}", self.1, endpoint);
    let req = match method {
      Method::Put    => self.0.put(&uri[..]),
      Method::Post   => self.0.post(&uri[..]),
      Method::Delete => self.0.delete(&uri[..]),
                   _ => self.0.get(&uri[..])
    };
    let embodied = match body {
      Some(Body { read: r, size: l }) => {
        let reader: &mut Read = *r.deref_mut();
        let content_type: Mime = Mime(Application, Json, vec![(Attr::Charset, Value::Utf8)]);
        req.header(ContentType(content_type)).body(client::Body::SizedBody(reader, l))
      },
      _ => req
    };
    let res = match embodied.send() {
      Ok(r) => r,
      Err(e) => panic!("failed request {:?}", e)
    };
    println!("status {:?}", res.status);
    match res.status {
      StatusCode::Ok | StatusCode::Created | StatusCode::SwitchingProtocols =>
        Ok(Box::new(res)),
      StatusCode::NoContent =>
        Ok(Box::new(BufReader::new("".as_bytes()))),
      status =>
        lift_status_err(status.to_u16())
    }
  }
}
<commit_msg>rm print<commit_after>//! Transports for communicating with the docker daemon

extern crate hyper;
extern crate mime;
extern crate unix_socket;

use hyper::Client;
use hyper::client;
use self::hyper::buffer::BufReader;
use self::hyper::http::{ parse_response, RawStatus };
use self::hyper::http::HttpReader::EofReader;
use self::hyper::header::ContentType;
use self::hyper::status::StatusCode;
use hyper::method::Method;
use self::mime::{ Attr, Mime, Value };
use self::mime::TopLevel::Application;
use self::mime::SubLevel::Json;
use std::ops::DerefMut;
use std::io::{ Error, ErrorKind, Read, Result, Write };
use unix_socket::UnixStream;

fn lift_status_err(status: u16) -> Result<Box<Read>> {
  match status {
    400 => Err(Error::new(ErrorKind::InvalidInput, "bad parameter")),
    404 => Err(Error::new(ErrorKind::InvalidInput, "not found")),
    406 => Err(Error::new(ErrorKind::InvalidInput, "not acceptable")),
    409 => Err(Error::new(ErrorKind::InvalidInput, "conflict found")),
    500 => Err(Error::new(ErrorKind::InvalidInput, "interal server error")),
     _  => unreachable!()
  }
}

#[doc(hidden)]
pub struct Body<'a> {
 read: &'a mut Box<&'a mut Read>,
 size: u64
}

impl<'a> Body<'a> {
  /// Create a new body instance
  pub fn new(read: &'a mut Box<&'a mut Read>, size: u64) -> Body<'a> {
    Body { read: read, size: size }
  }
}

/// Primary interface for communicating with docker daemon
pub trait Transport {
  fn request(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<String> {
    let mut res = match self.stream(method, endpoint, body) {
      Ok(r) => r,
      Err(e) => panic!("failed request {:?}", e)
    };
    let mut body = String::new();
    res.read_to_string(&mut body).map(|_| body)
  }

  fn stream(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<Box<Read>>;
}

impl Transport for UnixStream {
  fn stream(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<Box<Read>> {
    let method_str = match method {
      Method::Put    => "PUT",
      Method::Post   => "POST",
      Method::Delete => "DELETE",
               _     => "GET"
    };
    let req = format!("{} {} HTTP/1.0\r\n\r\n", method_str, endpoint);
    try!(self.write_all(req.as_bytes()));
    // read the body -- https://github.com/hyperium/hyper/blob/06d072bca1b4af3507af370cbd0ca2ac8f64fc00/src/client/response.rs#L36-L74
    let cloned = try!(self.try_clone());
    let mut stream = BufReader::new(cloned);
    let res = parse_response(&mut stream).unwrap();
    match res.subject {
      RawStatus(200, _) | RawStatus(201, _) | RawStatus(101, _) =>
        Ok(Box::new(EofReader(stream))),
      RawStatus(204, _) =>
        Ok(Box::new(BufReader::new("".as_bytes()))),
      RawStatus(status, _) =>
        lift_status_err(status)
    }
  }
}

impl Transport for (Client, String) {
  fn stream(&mut self, method: Method, endpoint: &str, body: Option<Body>) -> Result<Box<Read>> {
    let uri = format!("{}{}", self.1, endpoint);
    let req = match method {
      Method::Put    => self.0.put(&uri[..]),
      Method::Post   => self.0.post(&uri[..]),
      Method::Delete => self.0.delete(&uri[..]),
                   _ => self.0.get(&uri[..])
    };
    let embodied = match body {
      Some(Body { read: r, size: l }) => {
        let reader: &mut Read = *r.deref_mut();
        let content_type: Mime = Mime(Application, Json, vec![(Attr::Charset, Value::Utf8)]);
        req.header(ContentType(content_type)).body(client::Body::SizedBody(reader, l))
      },
      _ => req
    };
    let res = match embodied.send() {
      Ok(r) => r,
      Err(e) => panic!("failed request {:?}", e)
    };
    match res.status {
      StatusCode::Ok | StatusCode::Created | StatusCode::SwitchingProtocols =>
        Ok(Box::new(res)),
      StatusCode::NoContent =>
        Ok(Box::new(BufReader::new("".as_bytes()))),
      status =>
        lift_status_err(status.to_u16())
    }
  }
}
<|endoftext|>


<commit_before>
use vertex::{Vertex, VertexProxy};
use edge::{Edge, EdgeProxy};
// define a traversal as a series of stages

struct VertexVisit {
    vertex: VertexProxy
}

struct EdgeVisit {
    edge: EdgeProxy
}

enum TraversalStage {

}

pub enum GraphIterable {
    Vertex(VertexProxy),
    Edge(EdgeProxy)
}

// used to track a single graph traversal
//
struct Path {
    path: GraphIterable
}

impl Path {
    fn new(vertex: VertexProxy)  {
    }
}

pub struct GraphQuery {
    paths: Vec<GraphIterable>
}

impl GraphQuery {
    pub fn new(vertices: Vec<VertexProxy>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let paths = Vec::new();
        let path: Path;
        for p in vertices {

            //paths.push(path)
        }
        GraphQuery{paths:paths}
    }
    pub fn empty() -> GraphQuery {
        // return an empty graph query
        let v: Vec<GraphIterable> = Vec::new();
        GraphQuery{paths:v}
    }

    fn map(closure: &Fn() -> i32) -> GraphQuery  {
        GraphQuery{paths:Vec::new()}

    }
    pub fn outV(&self) -> GraphQuery {
        let g = GraphQuery::empty();
        g
    }
}

<commit_msg>a graph query now holds a Vec of Path<commit_after>
use vertex::{Vertex, VertexProxy};
use edge::{Edge, EdgeProxy};
// define a traversal as a series of stages

struct VertexVisit {
    vertex: VertexProxy
}

struct EdgeVisit {
    edge: EdgeProxy
}

enum TraversalStage {

}

pub enum GraphIterable {
    Vertex(VertexProxy),
    Edge(EdgeProxy)
}

// used to track a single graph traversal
// will be used in conjunction with a GraphQuery

struct Path {
    path: Vec<GraphIterable>
}

impl Path {
    fn new(vertex: VertexProxy)  {
    }
}

pub struct GraphQuery {
	// many paths
    paths: Vec<Path>
}

impl GraphQuery {
    pub fn new(vertices: Vec<VertexProxy>) -> GraphQuery {
        // create a new path for each proxy, add the proxy
        let paths = Vec::new();
        let path: Path;
        for p in vertices {

            //paths.push(path)
        }
        GraphQuery{paths:paths}
    }

    pub fn empty() -> GraphQuery {
        // return an empty graph query
        GraphQuery{paths:Vec::new()}
    }

    fn map(closure: &Fn() -> Path) -> GraphQuery  {
        GraphQuery{paths:Vec::new()}

    }
    pub fn outV(&self) -> GraphQuery {
        let g = GraphQuery::empty();
        g
    }
}

<|endoftext|>