<commit_before>extern crate gj;
extern crate gjio;
extern crate byteorder;
extern crate slab;

use std::io::{Error, ErrorKind};
use std::rc::Rc;
use std::cell::{Cell, RefCell};
use byteorder::{LittleEndian, ByteOrder};
use slab::Slab;
use gj::{EventLoop, Promise, TaskReaper, TaskSet};
use gjio::{SocketStream, AsyncRead, AsyncWrite};

struct WriteQueue {
    // TODO
}

fn handle_publisher(mut stream: SocketStream, messages_received: u64,
                    subscribers: Rc<RefCell<Slab<WriteQueue>>>) -> Promise<(), Error> {
    stream.try_read(vec![0], 1).then(move |(buf, n)| {
        if n == 0 {
            // EOF
            let mut word = vec![0u8; 8];
            <LittleEndian as ByteOrder>::write_u64(&mut word, messages_received);
            stream.write(word).map(|_| Ok(()))
        } else {
            let len = buf[0] as usize;
            let body = vec![0u8; len];
            stream.read(body, len).then(move |(buf, _)| {
                // TODO send buf to subscribers
                handle_publisher(stream, messages_received + 1, subscribers)
            })
        }
    })
}

fn handle_connection(mut stream: SocketStream,
                     subscribers: Rc<RefCell<Slab<WriteQueue>>>)
                     -> Promise<(), Error> {
    stream.read(vec![0], 1).then(move |(buf, _)| {
        match buf[0] {
            0 => {
                // publisher
                handle_publisher(stream, 0, subscribers)
            }
            1 => {
                // subscriber

                let write_queue = WriteQueue {};

                if !subscribers.borrow().has_available() {
                    let len = subscribers.borrow().len();
                    subscribers.borrow_mut().reserve_exact(len);
                }
                let idx = match subscribers.borrow_mut().insert(write_queue) {
                    Ok(idx) => idx,
                    Err(_) => unreachable!(),
                };

                unimplemented!()

//                handle_subscriber(stream).map_else(move |_| {
//                    subscribers.borrow_mut().remove(idx).unwrap();
//                    Ok(())
//                })
            }
            _ => {
                Promise::err(Error::new(ErrorKind::Other, "expected 0 or 1"))
            }
        }
    })
}

fn accept_loop(listener: gjio::SocketListener,
               mut task_set: TaskSet<(), ::std::io::Error>,
               subscribers: Rc<RefCell<Slab<WriteQueue>>>)
               -> Promise<(), ::std::io::Error>
{
     listener.accept().then(move |stream| {
         task_set.add(handle_connection(stream, subscribers.clone()));
         accept_loop(listener, task_set, subscribers)
    })
}

struct Reaper;

impl TaskReaper<(), ::std::io::Error> for Reaper {
    fn task_failed(&mut self, error: ::std::io::Error) {
        println!("Task failed: {}", error);
    }
}

pub fn main() {
    let args: Vec<String> = ::std::env::args().collect();
    if args.len() != 2 {
        println!("usage: {} HOST:PORT", args[0]);
        return;
    }

    EventLoop::top_level(move |wait_scope| -> Result<(), ::std::io::Error> {
        use std::net::ToSocketAddrs;
        let mut event_port = try!(gjio::EventPort::new());
        let network = event_port.get_network();
        let addr = try!(args[1].to_socket_addrs()).next().expect("could not parse address");
        let mut address = network.get_tcp_address(addr);
        let listener = try!(address.listen());
        let reaper = Box::new(Reaper);

        let subscribers: Rc<RefCell<Slab<WriteQueue>>> =
            Rc::new(RefCell::new(Slab::with_capacity(1024)));

        accept_loop(listener, TaskSet::new(reaper), subscribers).wait(wait_scope, &mut event_port)
    }).expect("top level");

}
<commit_msg>work on WriteQueue<commit_after>extern crate gj;
extern crate gjio;
extern crate byteorder;
extern crate slab;

use std::io::{Error, ErrorKind};
use std::rc::{Rc, Weak};
use std::cell::{Cell, RefCell};
use byteorder::{LittleEndian, ByteOrder};
use slab::Slab;
use gj::{EventLoop, Promise, TaskReaper, TaskSet};
use gjio::{SocketStream, AsyncRead, AsyncWrite};

struct WriteQueue {
    task: Promise<Bomb, Error>,
    len: Rc<Cell<usize>>,
    stream: SocketStream,
}

impl WriteQueue {
    fn new(stream: SocketStream) -> WriteQueue {
        WriteQueue {
            task: Promise::err(Error::new(ErrorKind::Other, "uninitialized")),
            len: Rc::new(Cell::new(0)),
            stream: stream,
        }
    }

    fn init(&mut self, idx: usize, subscribers: &Rc<RefCell<Slab<WriteQueue>>>) {
        self.task = Promise::ok(Bomb {
            subscribers: Rc::downgrade(subscribers),
            idx: idx
        });
    }

    fn len(&self) -> usize {
        self.len.get()
    }

    fn send(&mut self, message: Vec<u8>) {
        unimplemented!()
    }
}

struct Bomb {
    subscribers: Weak<RefCell<Slab<WriteQueue>>>,
    idx: usize,
}

impl Drop for Bomb {
    fn drop(&mut self) {
        match self.subscribers.upgrade() {
            Some(s) => {
                s.borrow_mut().remove(self.idx).unwrap();
            }
            None => (),
        }
    }
}

fn handle_publisher(mut stream: SocketStream, messages_received: u64,
                    subscribers: Rc<RefCell<Slab<WriteQueue>>>) -> Promise<(), Error> {
    stream.try_read(vec![0], 1).then(move |(buf, n)| {
        if n == 0 {
            // EOF
            let mut word = vec![0u8; 8];
            <LittleEndian as ByteOrder>::write_u64(&mut word, messages_received);
            stream.write(word).map(|_| Ok(()))
        } else {
            let len = buf[0] as usize;
            let body = vec![0u8; len];
            stream.read(body, len).then(move |(buf, _)| {
                // TODO send buf to subscribers
                handle_publisher(stream, messages_received + 1, subscribers)
            })
        }
    })
}

fn handle_connection(mut stream: SocketStream,
                     subscribers: Rc<RefCell<Slab<WriteQueue>>>)
                     -> Promise<(), Error> {
    stream.read(vec![0], 1).then(move |(buf, _)| {
        match buf[0] {
            0 => {
                // publisher
                handle_publisher(stream, 0, subscribers)
            }
            1 => {
                // subscriber

                let write_queue = WriteQueue::new(stream);

                if !subscribers.borrow().has_available() {
                    let len = subscribers.borrow().len();
                    subscribers.borrow_mut().reserve_exact(len);
                }
                let idx = match subscribers.borrow_mut().insert(write_queue) {
                    Ok(idx) => idx,
                    Err(_) => unreachable!(),
                };

                match subscribers.borrow_mut().get_mut(idx) {
                    Some(ref mut q) => q.init(idx, &subscribers),
                    None => unreachable!(),
                }

                // TODO: wait for EOF on read half?
                Promise::ok(())
            }
            _ => {
                Promise::err(Error::new(ErrorKind::Other, "expected 0 or 1"))
            }
        }
    })
}

fn accept_loop(listener: gjio::SocketListener,
               mut task_set: TaskSet<(), ::std::io::Error>,
               subscribers: Rc<RefCell<Slab<WriteQueue>>>)
               -> Promise<(), ::std::io::Error>
{
     listener.accept().then(move |stream| {
         task_set.add(handle_connection(stream, subscribers.clone()));
         accept_loop(listener, task_set, subscribers)
    })
}

struct Reaper;

impl TaskReaper<(), ::std::io::Error> for Reaper {
    fn task_failed(&mut self, error: ::std::io::Error) {
        println!("Task failed: {}", error);
    }
}

pub fn main() {
    let args: Vec<String> = ::std::env::args().collect();
    if args.len() != 2 {
        println!("usage: {} HOST:PORT", args[0]);
        return;
    }

    EventLoop::top_level(move |wait_scope| -> Result<(), ::std::io::Error> {
        use std::net::ToSocketAddrs;
        let mut event_port = try!(gjio::EventPort::new());
        let network = event_port.get_network();
        let addr = try!(args[1].to_socket_addrs()).next().expect("could not parse address");
        let mut address = network.get_tcp_address(addr);
        let listener = try!(address.listen());
        let reaper = Box::new(Reaper);

        let subscribers: Rc<RefCell<Slab<WriteQueue>>> =
            Rc::new(RefCell::new(Slab::with_capacity(1024)));

        accept_loop(listener, TaskSet::new(reaper), subscribers).wait(wait_scope, &mut event_port)
    }).expect("top level");

}
<|endoftext|>


<commit_before>#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate imap_proto;

// UTF-8
fuzz_target!(|data: &[u8]| {
    use imap_proto::parse_response;
    if let Ok(string_data) = std::str::from_utf8(data) {
        let _ = parse_response(string_data.as_bytes());
    }
});
<commit_msg>Update fuzz target code<commit_after>#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate imap_proto;

// UTF-8
fuzz_target!(|data: &[u8]| {
    let _ = imap_proto::Response::from_bytes(data);
});
<|endoftext|>


<commit_before>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
#[cfg(test)]
extern crate serialize;
use ffi;
use libc::c_ulonglong;
use std::intrinsics::volatile_set_memory;
use std::iter::repeat;

pub const SEEDBYTES: usize = ffi::crypto_sign_ed25519_SEEDBYTES as usize;
pub const SECRETKEYBYTES: usize = ffi::crypto_sign_ed25519_SECRETKEYBYTES as usize;
pub const PUBLICKEYBYTES: usize = ffi::crypto_sign_ed25519_PUBLICKEYBYTES as usize;
pub const SIGNATUREBYTES: usize = ffi::crypto_sign_ed25519_BYTES as usize;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed(pub [u8; SEEDBYTES]);

newtype_drop!(Seed);
newtype_clone!(Seed);
newtype_impl!(Seed, SEEDBYTES);

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey(pub [u8; SECRETKEYBYTES]);

newtype_drop!(SecretKey);
newtype_clone!(SecretKey);
newtype_impl!(SecretKey, SECRETKEYBYTES);

/**
 * `PublicKey` for signatures
 */
#[derive(Copy)]
pub struct PublicKey(pub [u8; PUBLICKEYBYTES]);

newtype_clone!(PublicKey);
newtype_impl!(PublicKey, PUBLICKEYBYTES);

/**
 * Detached signature
 */
#[derive(Copy)]
pub struct Signature(pub [u8; SIGNATUREBYTES]);

newtype_clone!(Signature);
newtype_impl!(Signature, SIGNATUREBYTES);

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8; PUBLICKEYBYTES];
        let mut sk = [0u8; SECRETKEYBYTES];
        ffi::crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8; PUBLICKEYBYTES];
        let mut sk = [0u8; SECRETKEYBYTES];
        ffi::crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> Vec<u8> {
    unsafe {
        let mut sm: Vec<u8> = repeat(0u8).take(m.len() + SIGNATUREBYTES).collect();
        let mut smlen = 0;
        ffi::crypto_sign_ed25519(sm.as_mut_ptr(),
                                 &mut smlen,
                                 m.as_ptr(),
                                 m.len() as c_ulonglong,
                                 sk.as_ptr());
        sm.truncate(smlen as usize);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<Vec<u8>> {
    unsafe {
        let mut m: Vec<u8> = repeat(0u8).take(sm.len()).collect();
        let mut mlen = 0;
        if ffi::crypto_sign_ed25519_open(m.as_mut_ptr(),
                                         &mut mlen,
                                         sm.as_ptr(),
                                         sm.len() as c_ulonglong,
                                         pk.as_ptr()) == 0 {
            m.truncate(mlen as usize);
            Some(m)
        } else {
            None
        }
    }
}

/**
 * `sign_detached()` signs a message `m` using the signer's secret key `sk`.
 * `sign_detached()` returns the resulting signature `sig`.
 */
pub fn sign_detached(m: &[u8],
                     &SecretKey(sk): &SecretKey) -> Signature {
    unsafe {
        let mut sig = [0u8; SIGNATUREBYTES];
        let mut siglen: c_ulonglong = 0;
        ffi::crypto_sign_ed25519_detached(sig.as_mut_ptr(),
                                          &mut siglen,
                                          m.as_ptr(),
                                          m.len() as c_ulonglong,
                                          sk.as_ptr());
        assert_eq!(siglen, SIGNATUREBYTES as c_ulonglong);
        Signature(sig)
    }
}

/**
 * `verify_detached()` verifies the signature in `sig` against the message `m`
 * and the signer's public key `pk`.
 * `verify_detached()` returns true if the signature is valid, false otherwise.
 */
pub fn verify_detached(&Signature(sig): &Signature,
                       m: &[u8],
                       &PublicKey(pk): &PublicKey) -> bool {
    unsafe {
        0 == ffi::crypto_sign_ed25519_verify_detached(sig.as_ptr(),
                                                      m.as_ptr(),
                                                      m.len() as c_ulonglong,
                                                      pk.as_ptr())
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in (0..256us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in (0..32us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in (0..sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_detached() {
    use randombytes::randombytes;
    for i in (0..256us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let sig = sign_detached(m.as_slice(), &sk);
        assert!(verify_detached(&sig, m.as_slice(), &pk));
    }
}

#[test]
fn test_sign_verify_detached_tamper() {
    use randombytes::randombytes;
    for i in (0..32us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let Signature(mut sig) = sign_detached(m.as_slice(), &sk);
        for j in (0..SIGNATUREBYTES) {
            sig[j] ^= 0x20;
            assert!(!verify_detached(&Signature(sig), m.as_slice(), &pk));
            sig[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in (0..256us) {
        let mut seedbuf = [0; 32];
        randombytes_into(&mut seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in (0..32us) {
        let mut seedbuf = [0; 32];
        randombytes_into(&mut seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in (0..sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // from the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.as_slice().split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8; SEEDBYTES];
        for (s, b) in seedbuf.iter_mut().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m.as_slice(), &sk);
        verify(sm.as_slice(), &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.as_slice().to_hex().as_slice());
        assert!(x3 == sm.as_slice().to_hex().as_slice());
    }
}

#[cfg(test)]
mod bench {
    extern crate test;
    use randombytes::randombytes;
    use super::*;

    const BENCH_SIZES: [usize; 14] = [0, 1, 2, 4, 8, 16, 32, 64,
                                      128, 256, 512, 1024, 2048, 4096];

    #[bench]
    fn bench_sign(b: &mut test::Bencher) {
        let (_, sk) = gen_keypair();
        let ms: Vec<Vec<u8>> = BENCH_SIZES.iter().map(|s| {
            randombytes(*s)
        }).collect();
        b.iter(|| {
            for m in ms.iter() {
                sign(m.as_slice(), &sk);
            }
        });
    }

    #[bench]
    fn bench_verify(b: &mut test::Bencher) {
        let (pk, sk) = gen_keypair();
        let sms: Vec<Vec<u8>> = BENCH_SIZES.iter().map(|s| {
            let m = randombytes(*s);
            sign(m.as_slice(), &sk)
        }).collect();
        b.iter(|| {
            for sm in sms.iter() {
                verify(sm.as_slice(), &pk);
            }
        });
    }
}
<commit_msg>Added test-vector tests for ed25519 detached signatures<commit_after>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
#[cfg(test)]
extern crate serialize;
use ffi;
use libc::c_ulonglong;
use std::intrinsics::volatile_set_memory;
use std::iter::repeat;

pub const SEEDBYTES: usize = ffi::crypto_sign_ed25519_SEEDBYTES as usize;
pub const SECRETKEYBYTES: usize = ffi::crypto_sign_ed25519_SECRETKEYBYTES as usize;
pub const PUBLICKEYBYTES: usize = ffi::crypto_sign_ed25519_PUBLICKEYBYTES as usize;
pub const SIGNATUREBYTES: usize = ffi::crypto_sign_ed25519_BYTES as usize;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed(pub [u8; SEEDBYTES]);

newtype_drop!(Seed);
newtype_clone!(Seed);
newtype_impl!(Seed, SEEDBYTES);

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey(pub [u8; SECRETKEYBYTES]);

newtype_drop!(SecretKey);
newtype_clone!(SecretKey);
newtype_impl!(SecretKey, SECRETKEYBYTES);

/**
 * `PublicKey` for signatures
 */
#[derive(Copy)]
pub struct PublicKey(pub [u8; PUBLICKEYBYTES]);

newtype_clone!(PublicKey);
newtype_impl!(PublicKey, PUBLICKEYBYTES);

/**
 * Detached signature
 */
#[derive(Copy)]
pub struct Signature(pub [u8; SIGNATUREBYTES]);

newtype_clone!(Signature);
newtype_impl!(Signature, SIGNATUREBYTES);

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8; PUBLICKEYBYTES];
        let mut sk = [0u8; SECRETKEYBYTES];
        ffi::crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8; PUBLICKEYBYTES];
        let mut sk = [0u8; SECRETKEYBYTES];
        ffi::crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> Vec<u8> {
    unsafe {
        let mut sm: Vec<u8> = repeat(0u8).take(m.len() + SIGNATUREBYTES).collect();
        let mut smlen = 0;
        ffi::crypto_sign_ed25519(sm.as_mut_ptr(),
                                 &mut smlen,
                                 m.as_ptr(),
                                 m.len() as c_ulonglong,
                                 sk.as_ptr());
        sm.truncate(smlen as usize);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<Vec<u8>> {
    unsafe {
        let mut m: Vec<u8> = repeat(0u8).take(sm.len()).collect();
        let mut mlen = 0;
        if ffi::crypto_sign_ed25519_open(m.as_mut_ptr(),
                                         &mut mlen,
                                         sm.as_ptr(),
                                         sm.len() as c_ulonglong,
                                         pk.as_ptr()) == 0 {
            m.truncate(mlen as usize);
            Some(m)
        } else {
            None
        }
    }
}

/**
 * `sign_detached()` signs a message `m` using the signer's secret key `sk`.
 * `sign_detached()` returns the resulting signature `sig`.
 */
pub fn sign_detached(m: &[u8],
                     &SecretKey(sk): &SecretKey) -> Signature {
    unsafe {
        let mut sig = [0u8; SIGNATUREBYTES];
        let mut siglen: c_ulonglong = 0;
        ffi::crypto_sign_ed25519_detached(sig.as_mut_ptr(),
                                          &mut siglen,
                                          m.as_ptr(),
                                          m.len() as c_ulonglong,
                                          sk.as_ptr());
        assert_eq!(siglen, SIGNATUREBYTES as c_ulonglong);
        Signature(sig)
    }
}

/**
 * `verify_detached()` verifies the signature in `sig` against the message `m`
 * and the signer's public key `pk`.
 * `verify_detached()` returns true if the signature is valid, false otherwise.
 */
pub fn verify_detached(&Signature(sig): &Signature,
                       m: &[u8],
                       &PublicKey(pk): &PublicKey) -> bool {
    unsafe {
        0 == ffi::crypto_sign_ed25519_verify_detached(sig.as_ptr(),
                                                      m.as_ptr(),
                                                      m.len() as c_ulonglong,
                                                      pk.as_ptr())
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in (0..256us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in (0..32us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in (0..sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_detached() {
    use randombytes::randombytes;
    for i in (0..256us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let sig = sign_detached(m.as_slice(), &sk);
        assert!(verify_detached(&sig, m.as_slice(), &pk));
    }
}

#[test]
fn test_sign_verify_detached_tamper() {
    use randombytes::randombytes;
    for i in (0..32us) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let Signature(mut sig) = sign_detached(m.as_slice(), &sk);
        for j in (0..SIGNATUREBYTES) {
            sig[j] ^= 0x20;
            assert!(!verify_detached(&Signature(sig), m.as_slice(), &pk));
            sig[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in (0..256us) {
        let mut seedbuf = [0; 32];
        randombytes_into(&mut seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in (0..32us) {
        let mut seedbuf = [0; 32];
        randombytes_into(&mut seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in (0..sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // from the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.as_slice().split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8; SEEDBYTES];
        for (s, b) in seedbuf.iter_mut().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m.as_slice(), &sk);
        verify(sm.as_slice(), &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.as_slice().to_hex().as_slice());
        assert!(x3 == sm.as_slice().to_hex().as_slice());
    }
}

#[test]
fn test_vectors_detached() {
    // test vectors from the Python implementation
    // from the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.as_slice().split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8; SEEDBYTES];
        for (s, b) in seedbuf.iter_mut().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sig = sign_detached(m.as_slice(), &sk);
        assert!(verify_detached(&sig, m.as_slice(), &pk));
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.as_slice().to_hex().as_slice());
        let sm = sig.as_slice().to_hex() + x2; // x2 is m hex encoded
        assert!(x3 == sm);
    }
}

#[cfg(test)]
mod bench {
    extern crate test;
    use randombytes::randombytes;
    use super::*;

    const BENCH_SIZES: [usize; 14] = [0, 1, 2, 4, 8, 16, 32, 64,
                                      128, 256, 512, 1024, 2048, 4096];

    #[bench]
    fn bench_sign(b: &mut test::Bencher) {
        let (_, sk) = gen_keypair();
        let ms: Vec<Vec<u8>> = BENCH_SIZES.iter().map(|s| {
            randombytes(*s)
        }).collect();
        b.iter(|| {
            for m in ms.iter() {
                sign(m.as_slice(), &sk);
            }
        });
    }

    #[bench]
    fn bench_verify(b: &mut test::Bencher) {
        let (pk, sk) = gen_keypair();
        let sms: Vec<Vec<u8>> = BENCH_SIZES.iter().map(|s| {
            let m = randombytes(*s);
            sign(m.as_slice(), &sk)
        }).collect();
        b.iter(|| {
            for sm in sms.iter() {
                verify(sm.as_slice(), &pk);
            }
        });
    }
}
<|endoftext|>


<commit_before>use decoders::*;
use decoders::cfa::*;
use imageops;

/// All the data needed to process this raw image, including the image data itself as well
/// as all the needed metadata
#[derive(Debug, Clone)]
pub struct RawImage {
  /// camera make as encoded in the file
  pub make: String,
  /// camera model as encoded in the file
  pub model: String,
  /// make cleaned up to be consistent and short
  pub clean_make: String,
  /// model cleaned up to be consistent and short
  pub clean_model: String,
  /// width of the full image
  pub width: usize,
  /// height of the full image
  pub height: usize,
  /// number of components per pixel (1 for bayer, 3 for RGB images)
  pub cpp: usize,
  /// whitebalance coefficients encoded in the file in RGBE order
  pub wb_coeffs: [f32;4],
  /// image whitelevels in RGBE order
  pub whitelevels: [u16;4],
  /// image blacklevels in RGBE order
  pub blacklevels: [u16;4],
  /// matrix to convert XYZ to camera RGBE
  pub xyz_to_cam: [[f32;3];4],
  /// color filter array
  pub cfa: CFA,
  /// how much to crop the image to get all the usable area, order is top, right, bottom, left
  pub crops: [usize;4],
  /// image data itself, has width*height*cpp elements
  pub data: Vec<u16>,
}

/// A RawImage processed into a full RGB image with levels and gamma
///
/// The data is a Vec<f32> width width*height*3 elements, where each element is a value
/// between 0 and 1 with the intensity of the color channel
#[derive(Debug, Clone)]
pub struct RGBImage {
  pub width: usize,
  pub height: usize,
  pub data: Vec<f32>,
}

impl RawImage {
  #[doc(hidden)] pub fn new(camera: &Camera, width: usize, height: usize, wb_coeffs: [f32;4], image: Vec<u16>) -> RawImage {
    let blacks = if camera.blackareah.1 != 0 || camera.blackareav.1 != 0 {
      let mut avg = [0 as f32; 4];
      let mut count = [0 as f32; 4];
      for row in camera.blackareah.0 .. camera.blackareah.0+camera.blackareah.1 {
        for col in 0..width {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      for row in 0..height {
        for col in camera.blackareav.0 .. camera.blackareav.0+camera.blackareav.1 {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      [(avg[0]/count[0]) as u16,
       (avg[1]/count[1]) as u16,
       (avg[2]/count[2]) as u16,
       (avg[3]/count[3]) as u16]
    } else {
      camera.blacklevels
    };

    RawImage {
      make: camera.make.clone(),
      model: camera.model.clone(),
      clean_make: camera.clean_make.clone(),
      clean_model: camera.clean_model.clone(),
      width: width,
      height: height,
      cpp: 1,
      wb_coeffs: wb_coeffs,
      data: image,
      blacklevels: blacks,
      whitelevels: camera.whitelevels,
      xyz_to_cam: camera.xyz_to_cam,
      cfa: camera.cfa.clone(),
      crops: camera.crops,
    }
  }

  /// Outputs the inverted matrix that converts pixels in the camera colorspace into
  /// XYZ components. Those can then be easily used to convert to Lab or a RGB output space
  pub fn cam_to_xyz(&self) -> [[f32;4];3] {
    let (cam_to_xyz, _) = self.xyz_matrix_and_neutralwb();
    cam_to_xyz
  }

  /// Not all cameras encode a whitebalance so in those cases just using a 6500K neutral one
  /// is a good compromise
  pub fn neutralwb(&self) -> [f32;4] {
    let (_, neutralwb) = self.xyz_matrix_and_neutralwb();
    [neutralwb[0]/neutralwb[1],
     neutralwb[1]/neutralwb[1],
     neutralwb[2]/neutralwb[1],
     neutralwb[3]/neutralwb[1]]
  }

  fn xyz_matrix_and_neutralwb(&self) -> ([[f32;4];3],[f32;4]) {
    let d65_white = [0.9547,1.0,1.08883];
    let rgb_to_xyz = [
    // sRGB D65
      [ 0.412453, 0.357580, 0.180423 ],
      [ 0.212671, 0.715160, 0.072169 ],
      [ 0.019334, 0.119193, 0.950227 ],
    ];

    // Multiply RGB matrix
    let mut rgb_to_cam = [[0.0;3];4];
    for i in 0..4 {
      for j in 0..3 {
        rgb_to_cam[i][j] = 0.0;
        for k in 0..3 {
          rgb_to_cam[i][j] += self.xyz_to_cam[i][k] * rgb_to_xyz[k][j];
        }
      }
    }

    let mut neutralwb = [0 as f32; 4];
    // Normalize rgb_to_cam so that rgb_to_cam * (1,1,1) is (1,1,1,1)
    for i in 0..4 {
      let mut num = 0.0;
      for j in 0..3 {
        num += rgb_to_cam[i][j];
      }
      for j in 0..3 {
        rgb_to_cam[i][j] = if num == 0.0 {
          0.0
        }  else {
          rgb_to_cam[i][j] / num
        };
      }
      neutralwb[i] = 1.0 / num;
    }

    let cam_to_rgb = self.pseudoinverse(rgb_to_cam);
    let mut cam_to_xyz = [[0.0;4];3];
    // Multiply RGB matrix and adjust white to get a cam_to_xyz
    for i in 0..3 {
      for j in 0..4 {
        cam_to_xyz[i][j] = 0.0;
        for k in 0..3 {
          cam_to_xyz[i][j] += cam_to_rgb[k][j] * rgb_to_xyz[i][k] / d65_white[i];
        }
      }
    }

    (cam_to_xyz, neutralwb)
  }

  fn pseudoinverse(&self, inm: [[f32;3];4]) -> [[f32;4];3] {
    let mut temp: [[f32;6];3] = [[0.0; 6];3];

    for i in 0..3 {
      for j in 0..6 {
        temp[i][j] = if j == i+3 { 1.0 } else { 0.0 };
      }
      for j in 0..3 {
        for k in 0..4 {
          temp[i][j] += inm[k][i] * inm[k][j];
        }
      }
    }

    for i in 0..3 {
      let mut num = temp[i][i];
      for j in 0..6 {
        temp[i][j] /= num;
      }
      for k in 0..3 {
        if k == i { continue }
        num = temp[k][i];
        for j in 0..6 {
          temp[k][j] -= temp[i][j] * num;
        }
      }
    }

    let mut out: [[f32;4];3] = [[0.0; 4];3];

    for i in 0..4 {
      for j in 0..3 {
        out[j][i] = 0.0;
        for k in 0..3 {
          out[j][i] += temp[j][k+3] * inm[i][k];
        }
      }
    }

    out
  }

  /// Convert the image to a RGB image by doing a demosaic and applying levels whitebalance
  /// The maxwidth and maxheight values specify maximum dimensions for the final image. If
  /// the original image is smaller this will not scale up but otherwise you will get an
  /// image that is either maxwidth wide or maxheight tall and maintains the image ratio.
  /// Pass in maxwidth and maxheight as 0 if you want the maximum possible image size.
  pub fn to_rgb(&self, maxwidth: usize, maxheight: usize) -> Result<RGBImage,String> {
    let buffer = imageops::simple_decode(self, maxwidth, maxheight);

    Ok(RGBImage{
      width: buffer.width,
      height: buffer.height,
      data: buffer.data,
    })
  }

  /// Convert the image to a RGB image by doing a demosaic and applying levels whitebalance
  /// The maxwidth and maxheight values specify maximum dimensions for the final image. If
  /// the original image is smaller this will not scale up but otherwise you will get an
  /// image that is either maxwidth wide or maxheight tall and maintains the image ratio.
  /// Pass in maxwidth and maxheight as 0 if you want the maximum possible image size.
  pub fn to_linear_rgb(&self, maxwidth: usize, maxheight: usize) -> Result<RGBImage,String> {
    let buffer = imageops::simple_decode_linear(self, maxwidth, maxheight);

    Ok(RGBImage{
      width: buffer.width,
      height: buffer.height,
      data: buffer.data,
    })
  }
}
<commit_msg>image: improve rgb functions documentation<commit_after>use decoders::*;
use decoders::cfa::*;
use imageops;

/// All the data needed to process this raw image, including the image data itself as well
/// as all the needed metadata
#[derive(Debug, Clone)]
pub struct RawImage {
  /// camera make as encoded in the file
  pub make: String,
  /// camera model as encoded in the file
  pub model: String,
  /// make cleaned up to be consistent and short
  pub clean_make: String,
  /// model cleaned up to be consistent and short
  pub clean_model: String,
  /// width of the full image
  pub width: usize,
  /// height of the full image
  pub height: usize,
  /// number of components per pixel (1 for bayer, 3 for RGB images)
  pub cpp: usize,
  /// whitebalance coefficients encoded in the file in RGBE order
  pub wb_coeffs: [f32;4],
  /// image whitelevels in RGBE order
  pub whitelevels: [u16;4],
  /// image blacklevels in RGBE order
  pub blacklevels: [u16;4],
  /// matrix to convert XYZ to camera RGBE
  pub xyz_to_cam: [[f32;3];4],
  /// color filter array
  pub cfa: CFA,
  /// how much to crop the image to get all the usable area, order is top, right, bottom, left
  pub crops: [usize;4],
  /// image data itself, has width*height*cpp elements
  pub data: Vec<u16>,
}

/// A RawImage processed into a full RGB image with levels and gamma
///
/// The data is a Vec<f32> width width*height*3 elements, where each element is a value
/// between 0 and 1 with the intensity of the color channel
#[derive(Debug, Clone)]
pub struct RGBImage {
  pub width: usize,
  pub height: usize,
  pub data: Vec<f32>,
}

impl RawImage {
  #[doc(hidden)] pub fn new(camera: &Camera, width: usize, height: usize, wb_coeffs: [f32;4], image: Vec<u16>) -> RawImage {
    let blacks = if camera.blackareah.1 != 0 || camera.blackareav.1 != 0 {
      let mut avg = [0 as f32; 4];
      let mut count = [0 as f32; 4];
      for row in camera.blackareah.0 .. camera.blackareah.0+camera.blackareah.1 {
        for col in 0..width {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      for row in 0..height {
        for col in camera.blackareav.0 .. camera.blackareav.0+camera.blackareav.1 {
          let color = camera.cfa.color_at(row,col);
          avg[color] += image[row*width+col] as f32;
          count[color] += 1.0;
        }
      }
      [(avg[0]/count[0]) as u16,
       (avg[1]/count[1]) as u16,
       (avg[2]/count[2]) as u16,
       (avg[3]/count[3]) as u16]
    } else {
      camera.blacklevels
    };

    RawImage {
      make: camera.make.clone(),
      model: camera.model.clone(),
      clean_make: camera.clean_make.clone(),
      clean_model: camera.clean_model.clone(),
      width: width,
      height: height,
      cpp: 1,
      wb_coeffs: wb_coeffs,
      data: image,
      blacklevels: blacks,
      whitelevels: camera.whitelevels,
      xyz_to_cam: camera.xyz_to_cam,
      cfa: camera.cfa.clone(),
      crops: camera.crops,
    }
  }

  /// Outputs the inverted matrix that converts pixels in the camera colorspace into
  /// XYZ components. Those can then be easily used to convert to Lab or a RGB output space
  pub fn cam_to_xyz(&self) -> [[f32;4];3] {
    let (cam_to_xyz, _) = self.xyz_matrix_and_neutralwb();
    cam_to_xyz
  }

  /// Not all cameras encode a whitebalance so in those cases just using a 6500K neutral one
  /// is a good compromise
  pub fn neutralwb(&self) -> [f32;4] {
    let (_, neutralwb) = self.xyz_matrix_and_neutralwb();
    [neutralwb[0]/neutralwb[1],
     neutralwb[1]/neutralwb[1],
     neutralwb[2]/neutralwb[1],
     neutralwb[3]/neutralwb[1]]
  }

  fn xyz_matrix_and_neutralwb(&self) -> ([[f32;4];3],[f32;4]) {
    let d65_white = [0.9547,1.0,1.08883];
    let rgb_to_xyz = [
    // sRGB D65
      [ 0.412453, 0.357580, 0.180423 ],
      [ 0.212671, 0.715160, 0.072169 ],
      [ 0.019334, 0.119193, 0.950227 ],
    ];

    // Multiply RGB matrix
    let mut rgb_to_cam = [[0.0;3];4];
    for i in 0..4 {
      for j in 0..3 {
        rgb_to_cam[i][j] = 0.0;
        for k in 0..3 {
          rgb_to_cam[i][j] += self.xyz_to_cam[i][k] * rgb_to_xyz[k][j];
        }
      }
    }

    let mut neutralwb = [0 as f32; 4];
    // Normalize rgb_to_cam so that rgb_to_cam * (1,1,1) is (1,1,1,1)
    for i in 0..4 {
      let mut num = 0.0;
      for j in 0..3 {
        num += rgb_to_cam[i][j];
      }
      for j in 0..3 {
        rgb_to_cam[i][j] = if num == 0.0 {
          0.0
        }  else {
          rgb_to_cam[i][j] / num
        };
      }
      neutralwb[i] = 1.0 / num;
    }

    let cam_to_rgb = self.pseudoinverse(rgb_to_cam);
    let mut cam_to_xyz = [[0.0;4];3];
    // Multiply RGB matrix and adjust white to get a cam_to_xyz
    for i in 0..3 {
      for j in 0..4 {
        cam_to_xyz[i][j] = 0.0;
        for k in 0..3 {
          cam_to_xyz[i][j] += cam_to_rgb[k][j] * rgb_to_xyz[i][k] / d65_white[i];
        }
      }
    }

    (cam_to_xyz, neutralwb)
  }

  fn pseudoinverse(&self, inm: [[f32;3];4]) -> [[f32;4];3] {
    let mut temp: [[f32;6];3] = [[0.0; 6];3];

    for i in 0..3 {
      for j in 0..6 {
        temp[i][j] = if j == i+3 { 1.0 } else { 0.0 };
      }
      for j in 0..3 {
        for k in 0..4 {
          temp[i][j] += inm[k][i] * inm[k][j];
        }
      }
    }

    for i in 0..3 {
      let mut num = temp[i][i];
      for j in 0..6 {
        temp[i][j] /= num;
      }
      for k in 0..3 {
        if k == i { continue }
        num = temp[k][i];
        for j in 0..6 {
          temp[k][j] -= temp[i][j] * num;
        }
      }
    }

    let mut out: [[f32;4];3] = [[0.0; 4];3];

    for i in 0..4 {
      for j in 0..3 {
        out[j][i] = 0.0;
        for k in 0..3 {
          out[j][i] += temp[j][k+3] * inm[i][k];
        }
      }
    }

    out
  }

  /// Convert the image to a sRGB image by doing a demosaic and applying levels,
  /// whitebalance, a base curve, color conversions and gamma.
  ///
  /// The maxwidth and maxheight values specify maximum dimensions for the final image. If
  /// the original image is smaller this will not scale up but otherwise you will get an
  /// image that is either maxwidth wide or maxheight tall and maintains the image ratio.
  /// Pass in maxwidth and maxheight as 0 if you want the maximum possible image size.
  pub fn to_rgb(&self, maxwidth: usize, maxheight: usize) -> Result<RGBImage,String> {
    let buffer = imageops::simple_decode(self, maxwidth, maxheight);

    Ok(RGBImage{
      width: buffer.width,
      height: buffer.height,
      data: buffer.data,
    })
  }

  /// Convert the image to a linear sRGB image by doing a demosaic and applying levels and
  /// whitebalance, a base curve and color conversions.
  ///
  /// The maxwidth and maxheight values specify maximum dimensions for the final image. If
  /// the original image is smaller this will not scale up but otherwise you will get an
  /// image that is either maxwidth wide or maxheight tall and maintains the image ratio.
  /// Pass in maxwidth and maxheight as 0 if you want the maximum possible image size.
  pub fn to_linear_rgb(&self, maxwidth: usize, maxheight: usize) -> Result<RGBImage,String> {
    let buffer = imageops::simple_decode_linear(self, maxwidth, maxheight);

    Ok(RGBImage{
      width: buffer.width,
      height: buffer.height,
      data: buffer.data,
    })
  }
}
<|endoftext|>


<commit_before>use num::{Num, NumCast, One, Zero};
use std::ops::{Add, Mul, Neg, Sub};

use crate::geometry::ops::{Dot, Interpolate, Magnitude, Normalize};

pub trait AbstractSpace: Clone {
    type Scalar: Clone + Neg<Output = Self::Scalar> + Num + NumCast;
}

pub trait VectorSpace:
    AbstractSpace
    + Add<Output = Self>
    + Interpolate<Output = Self>
    + Mul<<Self as AbstractSpace>::Scalar, Output = Self>
    + Neg<Output = Self>
    + Zero
{
    fn mean<I>(vectors: I) -> Option<Self>
    where
        I: IntoIterator<Item = Self>,
    {
        let mut vectors = vectors.into_iter();
        if let Some(mut sum) = vectors.next() {
            let mut n = 1usize;
            for vector in vectors {
                n += 1;
                sum = sum + vector;
            }
            NumCast::from(n).map(move |n| sum * (<Self as AbstractSpace>::Scalar::one() / n))
        }
        else {
            None
        }
    }
}

impl<T> VectorSpace for T where
    T: AbstractSpace
        + Add<Output = T>
        + Interpolate<Output = T>
        + Mul<<T as AbstractSpace>::Scalar, Output = T>
        + Neg<Output = T>
        + Zero
{
}

pub trait InnerSpace:
    Dot<Output = <Self as AbstractSpace>::Scalar>
    + Magnitude<Output = <Self as AbstractSpace>::Scalar>
    + Normalize
    + VectorSpace
{
}

impl<T> InnerSpace for T where
    T: Dot<Output = <T as AbstractSpace>::Scalar>
        + Magnitude<Output = <T as AbstractSpace>::Scalar>
        + Normalize
        + VectorSpace
{
}

pub trait Origin {
    fn origin() -> Self;
}

pub trait EuclideanSpace:
    Add<<Self as EuclideanSpace>::Difference, Output = Self>
    + Clone
    + Origin
    + Sub<Output = <Self as EuclideanSpace>::Difference>
{
    type Difference: InnerSpace;

    fn coordinate(&self) -> Self::Difference {
        self.clone() - Self::origin()
    }

    fn centroid<I>(points: I) -> Option<Self>
    where
        I: IntoIterator<Item = Self>,
    {
        VectorSpace::mean(points.into_iter().map(|point| point.coordinate()))
            .map(|mean| Self::origin() + mean)
    }
}
<commit_msg>Require `Project` for `InnerSpace`.<commit_after>use num::{Num, NumCast, One, Zero};
use std::ops::{Add, Mul, Neg, Sub};

use crate::geometry::ops::{Dot, Interpolate, Magnitude, Normalize, Project};

pub trait AbstractSpace: Clone {
    type Scalar: Clone + Neg<Output = Self::Scalar> + Num + NumCast;
}

pub trait VectorSpace:
    AbstractSpace
    + Add<Output = Self>
    + Interpolate<Output = Self>
    + Mul<<Self as AbstractSpace>::Scalar, Output = Self>
    + Neg<Output = Self>
    + Zero
{
    fn mean<I>(vectors: I) -> Option<Self>
    where
        I: IntoIterator<Item = Self>,
    {
        let mut vectors = vectors.into_iter();
        if let Some(mut sum) = vectors.next() {
            let mut n = 1usize;
            for vector in vectors {
                n += 1;
                sum = sum + vector;
            }
            NumCast::from(n).map(move |n| sum * (<Self as AbstractSpace>::Scalar::one() / n))
        }
        else {
            None
        }
    }
}

impl<T> VectorSpace for T where
    T: AbstractSpace
        + Add<Output = T>
        + Interpolate<Output = T>
        + Mul<<T as AbstractSpace>::Scalar, Output = T>
        + Neg<Output = T>
        + Zero
{
}

pub trait InnerSpace:
    Dot<Output = <Self as AbstractSpace>::Scalar>
    + Magnitude<Output = <Self as AbstractSpace>::Scalar>
    + Normalize
    + Project<Output = Self>
    + VectorSpace
{
}

impl<T> InnerSpace for T where
    T: Dot<Output = <T as AbstractSpace>::Scalar>
        + Magnitude<Output = <T as AbstractSpace>::Scalar>
        + Normalize
        + Project<Output = Self>
        + VectorSpace
{
}

pub trait Origin {
    fn origin() -> Self;
}

pub trait EuclideanSpace:
    Add<<Self as EuclideanSpace>::Difference, Output = Self>
    + Clone
    + Origin
    + Sub<Output = <Self as EuclideanSpace>::Difference>
{
    type Difference: InnerSpace;

    fn coordinate(&self) -> Self::Difference {
        self.clone() - Self::origin()
    }

    fn centroid<I>(points: I) -> Option<Self>
    where
        I: IntoIterator<Item = Self>,
    {
        VectorSpace::mean(points.into_iter().map(|point| point.coordinate()))
            .map(|mean| Self::origin() + mean)
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix trait impl completions' `lookup_by` text<commit_after><|endoftext|>


<commit_before>//! Rewrite the request path to "index.html" if the path doesn't start
//! with "/api" and the Accept header contains "html".

use super::prelude::*;

use util::RequestProxy;

// Can't derive debug because of Handler and Static.
#[allow(missing_debug_implementations)]
pub struct EmberIndexRewrite {
    handler: Option<Box<Handler>>,
}

impl Default for EmberIndexRewrite {
    fn default() -> EmberIndexRewrite {
        EmberIndexRewrite {
            handler: None,
        }
    }
}

impl AroundMiddleware for EmberIndexRewrite {
    fn with_handler(&mut self, handler: Box<Handler>) {
        self.handler = Some(handler);
    }
}

impl Handler for EmberIndexRewrite {
    fn call(&self, req: &mut Request) -> Result<Response, Box<Error + Send>> {
        // If the client is requesting html, then we've only got one page so
        // rewrite the request.
        let wants_html = req.headers()
            .find("Accept")
            .map(|accept| accept.iter().any(|s| s.contains("html")))
            .unwrap_or(false);
        // If the route starts with /api, just assume they want the API
        // response and fall through.
        let is_api_path = req.path().starts_with("/api");
        let handler = self.handler.as_ref().unwrap();
        if wants_html && !is_api_path {
            handler.call(&mut RequestProxy {
                other: req,
                path: Some("/index.html"),
                method: None,
            })
        } else {
            handler.call(req)
        }
    }
}
<commit_msg>`cargo fmt`<commit_after>//! Rewrite the request path to "index.html" if the path doesn't start
//! with "/api" and the Accept header contains "html".

use super::prelude::*;

use util::RequestProxy;

// Can't derive debug because of Handler and Static.
#[allow(missing_debug_implementations)]
pub struct EmberIndexRewrite {
    handler: Option<Box<Handler>>,
}

impl Default for EmberIndexRewrite {
    fn default() -> EmberIndexRewrite {
        EmberIndexRewrite { handler: None }
    }
}

impl AroundMiddleware for EmberIndexRewrite {
    fn with_handler(&mut self, handler: Box<Handler>) {
        self.handler = Some(handler);
    }
}

impl Handler for EmberIndexRewrite {
    fn call(&self, req: &mut Request) -> Result<Response, Box<Error + Send>> {
        // If the client is requesting html, then we've only got one page so
        // rewrite the request.
        let wants_html = req.headers()
            .find("Accept")
            .map(|accept| accept.iter().any(|s| s.contains("html")))
            .unwrap_or(false);
        // If the route starts with /api, just assume they want the API
        // response and fall through.
        let is_api_path = req.path().starts_with("/api");
        let handler = self.handler.as_ref().unwrap();
        if wants_html && !is_api_path {
            handler.call(&mut RequestProxy {
                other: req,
                path: Some("/index.html"),
                method: None,
            })
        } else {
            handler.call(req)
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::Bitv;

fn step2(text: &[usize], pos_types: Bitv, lms_pos: &[usize]) -> Vec<usize> {
    let n = text.len();
    let mut pos = Vec::with_capacity(text.len());

    let mut bucket_start = get_bucket_start(text);
    let mut bucket_end = bucket_start.clone()[1..].to_vec();
    bucket_end.push(text.len());
    let mut bucket_end_lms = bucket_end.clone();

    // init all positions as unknown
    for _ in text.iter() {
        pos.push(n);
    }

    // insert LMS positions to the end of their buckets
    for &p in lms_pos.iter().rev() {
        let c = text[p];
        pos[bucket_end_lms[c]] = p;
        bucket_end_lms[c] -= 1;
    }

    // insert L-positions into buckets
    for r in 0..pos.len() {
        let p = pos[r];
        if p == n {
            continue;
        }
        let prev = p - 1;
        if !pos_types.get(prev).unwrap() {
            // L-position, insert into bucket
            let c = text[prev];
            pos[bucket_start[c]] = prev;
            bucket_start[c] += 1;
        }
    }

    for r in (0..pos.len()).rev() {
        let prev = pos[r] - 1;
        if pos_types.get(prev).unwrap() {
            let c = text[prev];
            pos[bucket_end[c]] = prev;
            bucket_end[c] -= 1;
        }
    }

    pos
}

fn get_bucket_start(text: &[usize]) -> Vec<usize> {
    let alphabet_size = *text.iter().max().unwrap();
    let mut bucket_sizes = Vec::with_capacity(alphabet_size);

    for _ in (0..alphabet_size) {
        bucket_sizes.push(0);
    }

    for &c in text.iter() {
        bucket_sizes[c as usize] += 1;
    }

    let mut bucket_start = Vec::with_capacity(alphabet_size as usize);
    let mut sum = 0;
    for &size in bucket_sizes.iter() {
        bucket_start.push(sum);
        sum += size;
    }

    bucket_start
}

/// Calculate the text position type.
/// S-type marks suffixes being lexicographically smaller than their successor,
/// L-type marks those being larger.
/// This function returns a Bitv, with 1-bits denoting S-type
/// and 0-bits denoting L-type.
///
/// # Arguments
///
/// * `text` - the text, ending with a sentinel '$'.
///
/// # Example
///
/// ```rust
/// use std::collections::Bitv;
/// use bio::data_structures::suffix_array::get_pos_type;
/// let text = b"GCCTTAACATTATTACGCCTA$";
/// let pos_type = get_pos_type(text);
/// let mut test = Bitv::from_bytes(&[0b01100110, 0b10010011,  0b01100100]);
/// test.truncate(text.len());
/// assert_eq!(pos_type, test);
/// ```
pub fn get_pos_types(text: &[usize]) -> Bitv {
    let n = text.len();
    let mut pos_types = Bitv::from_elem(n, false);
    pos_types.set(n - 1, true);
    for p in (0..n-1).rev() {
        if text[p] == text[p + 1] {
            // if the characters are equal, the next position determines
            // the lexicographical order
            let v = pos_types.get(p + 1).unwrap();
            pos_types.set(p, v);
        }
        else {
            pos_types.set(p, text[p] < text[p + 1]);
        }
    }

    pos_types
}
<commit_msg>Working on step one.<commit_after>use std::collections::Bitv;

/// Sort LMS suffixes (step 1).
fn get_lms_pos(text: &[usize], pos_types: Bitv) {
    let lms: Vec<bool> = pos_types.iter().enumerate().scan(false, |prev, (i, is_s)| {
        let prev_is_l = !*prev;
        *prev = is_s;
        Some(prev_is_l && is_s)
    }).collect();

    // determine LMS positions
    let lms_init_pos: Vec<usize> = lms.iter().enumerate().filter_map(|(i, &is_lms)| {
        if is_lms { Some(i) } else { None }
    }).collect();

    // sort LMS substrings
    let lms_substring_pos = get_pos(text, pos_types, &lms_init_pos[]);

    let mut i = 0;
    for r in 0..lms_substring_pos.len() {

    }
}

/// Sort other suffixes using sorted LMS suffixes (step 2).
fn get_pos(text: &[usize], pos_types: Bitv, lms_pos: &[usize]) -> Vec<usize> {
    let n = text.len();
    let mut pos = Vec::with_capacity(text.len());

    let mut bucket_start = get_bucket_start(text);
    let mut bucket_end = bucket_start.clone()[1..].to_vec();
    bucket_end.push(text.len());
    let mut bucket_end_lms = bucket_end.clone();

    // init all positions as unknown
    for _ in text.iter() {
        pos.push(n);
    }

    // insert LMS positions to the end of their buckets
    for &p in lms_pos.iter().rev() {
        let c = text[p];
        pos[bucket_end_lms[c]] = p;
        bucket_end_lms[c] -= 1;
    }

    // insert L-positions into buckets
    for r in 0..pos.len() {
        let p = pos[r];
        if p == n {
            continue;
        }
        let prev = p - 1;
        if !pos_types.get(prev).unwrap() {
            // L-position, insert into bucket
            let c = text[prev];
            pos[bucket_start[c]] = prev;
            bucket_start[c] += 1;
        }
    }

    for r in (0..pos.len()).rev() {
        let prev = pos[r] - 1;
        if pos_types.get(prev).unwrap() {
            let c = text[prev];
            pos[bucket_end[c]] = prev;
            bucket_end[c] -= 1;
        }
    }

    pos
}

fn get_bucket_start(text: &[usize]) -> Vec<usize> {
    let alphabet_size = *text.iter().max().unwrap();
    let mut bucket_sizes = Vec::with_capacity(alphabet_size);

    for _ in (0..alphabet_size) {
        bucket_sizes.push(0);
    }

    for &c in text.iter() {
        bucket_sizes[c as usize] += 1;
    }

    let mut bucket_start = Vec::with_capacity(alphabet_size as usize);
    let mut sum = 0;
    for &size in bucket_sizes.iter() {
        bucket_start.push(sum);
        sum += size;
    }

    bucket_start
}

/// Calculate the text position type.
/// S-type marks suffixes being lexicographically smaller than their successor,
/// L-type marks those being larger.
/// This function returns a Bitv, with 1-bits denoting S-type
/// and 0-bits denoting L-type.
///
/// # Arguments
///
/// * `text` - the text, ending with a sentinel '$'.
///
/// # Example
///
/// ```rust
/// use std::collections::Bitv;
/// use bio::data_structures::suffix_array::get_pos_type;
/// let text = b"GCCTTAACATTATTACGCCTA$";
/// let pos_type = get_pos_type(text);
/// let mut test = Bitv::from_bytes(&[0b01100110, 0b10010011,  0b01100100]);
/// test.truncate(text.len());
/// assert_eq!(pos_type, test);
/// ```
pub fn get_pos_types(text: &[usize]) -> Bitv {
    let n = text.len();
    let mut pos_types = Bitv::from_elem(n, false);
    pos_types.set(n - 1, true);
    for p in (0..n-1).rev() {
        if text[p] == text[p + 1] {
            // if the characters are equal, the next position determines
            // the lexicographical order
            let v = pos_types.get(p + 1).unwrap();
            pos_types.set(p, v);
        }
        else {
            pos_types.set(p, text[p] < text[p + 1]);
        }
    }

    pos_types
}
<|endoftext|>


<commit_before>//! Utility methods and constructors for Lua classes

use std::convert::From;
use std::default::Default;
use std::rc::Rc;
use rlua::{self, Lua, ToLua, Table, Value, UserData, AnyUserData, Function,
           UserDataMethods, MetaMethod};
use super::object::{self, Object};
use super::property::Property;

pub type Checker = Rc<Fn(Object) -> bool>;

#[derive(Clone, Debug)]
pub struct Class<'lua> {
    class: AnyUserData<'lua>
}

impl <'lua> From<AnyUserData<'lua>> for Class<'lua> {
    fn from(class: AnyUserData<'lua>) -> Self {
        Class { class }
    }
}

#[derive(Clone)]
pub struct ClassState {
    // NOTE That this is missing fields from the C version.
    // They stored in the meta table instead, to not have unsafety.
    // They are fetchable using getters.
    checker: Option<Checker>,
    instances: u32
}

unsafe impl Send for ClassState {}

pub struct ClassBuilder<'lua>{
    lua: &'lua Lua,
    class: Class<'lua>
}

impl <'lua> ClassBuilder<'lua> {
    pub fn method(self, name: String, meth: rlua::Function)
                  -> rlua::Result<Self> {
        let table = self.class.class.get_user_value::<Table>()?;
        let meta = table.get_metatable()
            .expect("Class had no meta table!");
        meta.set(name, meth)?;
        Ok(self)
    }

    pub fn property(self, prop: Property<'lua>) -> rlua::Result<Self> {
        let table = self.class.class.get_user_value::<Table>()?;
        let properties = table.get::<_, Table>("properties")?;
        let length = properties.len().unwrap_or(0) + 1;
        properties.set(length, prop)?;
        Ok(self)
    }

    // TODO remove, do right
    pub fn dummy_property(self, key: String, val: rlua::Value<'lua>) -> rlua::Result<Self> {
        let table = self.class.class.get_user_value::<Table>()?;
        let meta = table.get_metatable()
            .expect("Class had no meta table!");
        meta.set(key, val)?;
        Ok(self)
    }

    pub fn save_class(self, name: &str)
                      -> rlua::Result<Self> {
        self.lua.globals().set(name, self.class.class.clone())?;
        Ok(self)
    }

    pub fn build(self) -> rlua::Result<Class<'lua>> {
        Ok(self.class)
    }
}

impl <'lua> ToLua<'lua> for Class<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.class.to_lua(lua)
    }
}

impl Default for ClassState {
    fn default() -> Self {
        ClassState {
            checker: Option::default(),
            instances: 0
        }
    }
}

impl UserData for ClassState {
    fn add_methods(methods: &mut UserDataMethods<Self>) {
        methods.add_meta_function(MetaMethod::Index, class_index);
        // TODO Class new index?
        methods.add_meta_function(MetaMethod::NewIndex, object::default_newindex);
        fn call<'lua>(lua: &'lua Lua,
                      (class, args): (AnyUserData<'lua>, rlua::MultiValue<'lua>))
                      -> rlua::Result<Value<'lua>> {
            match class_index(lua, (class, "__call".to_lua(lua)?))? {
                Value::Function(function) => function.call(args),
                v => Ok(v)
            }
        }
        methods.add_meta_function(MetaMethod::Call, call);
        methods.add_meta_function(MetaMethod::ToString, |_, class: AnyUserData| {
            let table = class.get_user_value::<Table>()?;
            table.get::<_, String>("name")
        });
    }
}

impl <'lua> Class<'lua> {
    pub fn builder(lua: &'lua Lua,
                   name: &str,
                   checker: Option<Checker>)
                   -> rlua::Result<ClassBuilder<'lua>> {
        let mut class = ClassState::default();
        class.checker = checker;
        let user_data = lua.create_userdata(class)?;
        let table = lua.create_table()?;
        // Store in not meta table so we can't index it
        table.set("name", name)?;
        table.set("properties", Vec::<Property>::new().to_lua(lua)?)?;
        let meta = lua.create_table()?;
        meta.set("signals", lua.create_table()?)?;
        meta.set("set_index_miss_handler",
                 lua.create_function(set_index_miss_handler)?.bind(user_data.clone())?)?;
        meta.set("set_newindex_miss_handler",
                 lua.create_function(set_newindex_miss_handler)?.bind(user_data.clone())?)?;
        meta.set("__index", meta.clone())?;
        table.set_metatable(Some(meta.clone()));
        user_data.set_user_value(table)?;
        Ok(ClassBuilder{
            lua: lua,
            class: Class { class: user_data }
        })
    }

    pub fn checker(&self) -> rlua::Result<Option<Checker>> {
        self.class.borrow::<ClassState>().map(|class| class.checker.clone())
    }
}

fn set_index_miss_handler<'lua>(_: &'lua Lua, (class, func): (AnyUserData, Function))
                                -> rlua::Result<()> {
    let table = class.get_user_value::<Table>()?;
    let meta = table.get_metatable()
        .expect("Object had no metatable");
    meta.set("__index_miss_handler", func)?;
    Ok(())
}
fn set_newindex_miss_handler<'lua>(_: &'lua Lua, (class, func): (AnyUserData, Function))
                                   -> rlua::Result<()> {
    let table = class.get_user_value::<Table>()?;
    let meta = table.get_metatable()
        .expect("Object had no metatable");
    meta.set("__newindex_miss_handler", func)?;
    Ok(())
}

pub fn class_setup<'lua>(lua: &'lua Lua, name: &str) -> rlua::Result<Class<'lua>> {
    let class = lua.globals().get::<_, AnyUserData>(name)
        .expect("Class was not set! Did you call init?");
    assert!(class.is::<ClassState>()?,
            "This user data was not a class!");
    Ok(Class { class })
}

fn class_index<'lua>(_: &'lua Lua,
                         (class, index): (AnyUserData<'lua>, Value<'lua>))
                         -> rlua::Result<Value<'lua>> {
    let table = class.get_user_value::<Table>()?;
    let meta = table.get_metatable().expect("class had no meta table");
    match meta.raw_get("__index")? {
        Value::Function(function) => function.call((class, index)),
        Value::Table(table) => table.get(index),
        _ => panic!("Unexpected value in index")
    }
}
<commit_msg>Remove wrong 'unsafe impl Send' for ClassState<commit_after>//! Utility methods and constructors for Lua classes

use std::convert::From;
use std::default::Default;
use std::sync::Arc;
use rlua::{self, Lua, ToLua, Table, Value, UserData, AnyUserData, Function,
           UserDataMethods, MetaMethod};
use super::object::{self, Object};
use super::property::Property;

pub type Checker = Arc<Fn(Object) -> bool + Send + Sync>;

#[derive(Clone, Debug)]
pub struct Class<'lua> {
    class: AnyUserData<'lua>
}

impl <'lua> From<AnyUserData<'lua>> for Class<'lua> {
    fn from(class: AnyUserData<'lua>) -> Self {
        Class { class }
    }
}

#[derive(Clone)]
pub struct ClassState {
    // NOTE That this is missing fields from the C version.
    // They stored in the meta table instead, to not have unsafety.
    // They are fetchable using getters.
    checker: Option<Checker>,
    instances: u32
}

pub struct ClassBuilder<'lua>{
    lua: &'lua Lua,
    class: Class<'lua>
}

impl <'lua> ClassBuilder<'lua> {
    pub fn method(self, name: String, meth: rlua::Function)
                  -> rlua::Result<Self> {
        let table = self.class.class.get_user_value::<Table>()?;
        let meta = table.get_metatable()
            .expect("Class had no meta table!");
        meta.set(name, meth)?;
        Ok(self)
    }

    pub fn property(self, prop: Property<'lua>) -> rlua::Result<Self> {
        let table = self.class.class.get_user_value::<Table>()?;
        let properties = table.get::<_, Table>("properties")?;
        let length = properties.len().unwrap_or(0) + 1;
        properties.set(length, prop)?;
        Ok(self)
    }

    // TODO remove, do right
    pub fn dummy_property(self, key: String, val: rlua::Value<'lua>) -> rlua::Result<Self> {
        let table = self.class.class.get_user_value::<Table>()?;
        let meta = table.get_metatable()
            .expect("Class had no meta table!");
        meta.set(key, val)?;
        Ok(self)
    }

    pub fn save_class(self, name: &str)
                      -> rlua::Result<Self> {
        self.lua.globals().set(name, self.class.class.clone())?;
        Ok(self)
    }

    pub fn build(self) -> rlua::Result<Class<'lua>> {
        Ok(self.class)
    }
}

impl <'lua> ToLua<'lua> for Class<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.class.to_lua(lua)
    }
}

impl Default for ClassState {
    fn default() -> Self {
        ClassState {
            checker: Option::default(),
            instances: 0
        }
    }
}

impl UserData for ClassState {
    fn add_methods(methods: &mut UserDataMethods<Self>) {
        methods.add_meta_function(MetaMethod::Index, class_index);
        // TODO Class new index?
        methods.add_meta_function(MetaMethod::NewIndex, object::default_newindex);
        fn call<'lua>(lua: &'lua Lua,
                      (class, args): (AnyUserData<'lua>, rlua::MultiValue<'lua>))
                      -> rlua::Result<Value<'lua>> {
            match class_index(lua, (class, "__call".to_lua(lua)?))? {
                Value::Function(function) => function.call(args),
                v => Ok(v)
            }
        }
        methods.add_meta_function(MetaMethod::Call, call);
        methods.add_meta_function(MetaMethod::ToString, |_, class: AnyUserData| {
            let table = class.get_user_value::<Table>()?;
            table.get::<_, String>("name")
        });
    }
}

impl <'lua> Class<'lua> {
    pub fn builder(lua: &'lua Lua,
                   name: &str,
                   checker: Option<Checker>)
                   -> rlua::Result<ClassBuilder<'lua>> {
        let mut class = ClassState::default();
        class.checker = checker;
        let user_data = lua.create_userdata(class)?;
        let table = lua.create_table()?;
        // Store in not meta table so we can't index it
        table.set("name", name)?;
        table.set("properties", Vec::<Property>::new().to_lua(lua)?)?;
        let meta = lua.create_table()?;
        meta.set("signals", lua.create_table()?)?;
        meta.set("set_index_miss_handler",
                 lua.create_function(set_index_miss_handler)?.bind(user_data.clone())?)?;
        meta.set("set_newindex_miss_handler",
                 lua.create_function(set_newindex_miss_handler)?.bind(user_data.clone())?)?;
        meta.set("__index", meta.clone())?;
        table.set_metatable(Some(meta.clone()));
        user_data.set_user_value(table)?;
        Ok(ClassBuilder{
            lua: lua,
            class: Class { class: user_data }
        })
    }

    pub fn checker(&self) -> rlua::Result<Option<Checker>> {
        self.class.borrow::<ClassState>().map(|class| class.checker.clone())
    }
}

fn set_index_miss_handler<'lua>(_: &'lua Lua, (class, func): (AnyUserData, Function))
                                -> rlua::Result<()> {
    let table = class.get_user_value::<Table>()?;
    let meta = table.get_metatable()
        .expect("Object had no metatable");
    meta.set("__index_miss_handler", func)?;
    Ok(())
}
fn set_newindex_miss_handler<'lua>(_: &'lua Lua, (class, func): (AnyUserData, Function))
                                   -> rlua::Result<()> {
    let table = class.get_user_value::<Table>()?;
    let meta = table.get_metatable()
        .expect("Object had no metatable");
    meta.set("__newindex_miss_handler", func)?;
    Ok(())
}

pub fn class_setup<'lua>(lua: &'lua Lua, name: &str) -> rlua::Result<Class<'lua>> {
    let class = lua.globals().get::<_, AnyUserData>(name)
        .expect("Class was not set! Did you call init?");
    assert!(class.is::<ClassState>()?,
            "This user data was not a class!");
    Ok(Class { class })
}

fn class_index<'lua>(_: &'lua Lua,
                         (class, index): (AnyUserData<'lua>, Value<'lua>))
                         -> rlua::Result<Value<'lua>> {
    let table = class.get_user_value::<Table>()?;
    let meta = table.get_metatable().expect("class had no meta table");
    match meta.raw_get("__index")? {
        Value::Function(function) => function.call((class, index)),
        Value::Table(table) => table.get(index),
        _ => panic!("Unexpected value in index")
    }
}
<|endoftext|>


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

// Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/)

#![cfg(not(test))]
#![deny(warnings)]

extern crate cargo_metadata;
extern crate getopts;
extern crate serde_json as json;

use std::env;
use std::hash::{Hash, Hasher};
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{Command, ExitStatus};
use std::str;
use std::collections::HashSet;
use std::iter::FromIterator;

use getopts::{Matches, Options};
use json::Value;

fn main() {
    let exit_status = execute();
    std::io::stdout().flush().unwrap();
    std::process::exit(exit_status);
}

fn execute() -> i32 {
    let success = 0;
    let failure = 1;

    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optflag("q", "quiet", "no output printed to stdout");
    opts.optflag("v", "verbose", "use verbose output");
    opts.optmulti(
        "p",
        "package",
        "specify package to format (only usable in workspaces)",
        "<package>",
    );
    opts.optflag("", "all", "format all packages (only usable in workspaces)");

    // If there is any invalid argument passed to `cargo fmt`, return without formatting.
    if let Some(arg) = env::args()
        .skip(2)
        .take_while(|a| a != "--")
        .find(|a| !a.starts_with('-'))
    {
        print_usage_to_stderr(&opts, &format!("Invalid argument: `{}`.", arg));
        return failure;
    }

    let matches = match opts.parse(env::args().skip(1).take_while(|a| a != "--")) {
        Ok(m) => m,
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            return failure;
        }
    };

    let verbosity = match (matches.opt_present("v"), matches.opt_present("q")) {
        (false, false) => Verbosity::Normal,
        (false, true) => Verbosity::Quiet,
        (true, false) => Verbosity::Verbose,
        (true, true) => {
            print_usage_to_stderr(&opts, "quiet mode and verbose mode are not compatible");
            return failure;
        }
    };

    if matches.opt_present("h") {
        print_usage_to_stdout(&opts, "");
        return success;
    }

    let workspace_hitlist = WorkspaceHitlist::from_matches(&matches);

    match format_crate(verbosity, &workspace_hitlist) {
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            failure
        }
        Ok(status) => if status.success() {
            success
        } else {
            status.code().unwrap_or(failure)
        },
    }
}

macro_rules! print_usage {
    ($print:ident, $opts:ident, $reason:expr) => ({
        let msg = format!("{}\nusage: cargo fmt [options]", $reason);
        $print!(
            "{}\nThis utility formats all bin and lib files of the current crate using rustfmt. \
             Arguments after `--` are passed to rustfmt.",
            $opts.usage(&msg)
        );
    })
}

fn print_usage_to_stdout(opts: &Options, reason: &str) {
    print_usage!(println, opts, reason);
}

fn print_usage_to_stderr(opts: &Options, reason: &str) {
    print_usage!(eprintln, opts, reason);
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Verbosity {
    Verbose,
    Normal,
    Quiet,
}

fn format_crate(
    verbosity: Verbosity,
    workspace_hitlist: &WorkspaceHitlist,
) -> Result<ExitStatus, io::Error> {
    let targets = get_targets(workspace_hitlist)?;

    // Currently only bin and lib files get formatted
    let files: Vec<_> = targets
        .into_iter()
        .filter(|t| t.kind.should_format())
        .inspect(|t| {
            if verbosity == Verbosity::Verbose {
                println!("[{:?}] {:?}", t.kind, t.path)
            }
        })
        .map(|t| t.path)
        .collect();

    format_files(&files, &get_fmt_args(), verbosity)
}

fn get_fmt_args() -> Vec<String> {
    // All arguments after -- are passed to rustfmt
    env::args().skip_while(|a| a != "--").skip(1).collect()
}

#[derive(Debug)]
enum TargetKind {
    Lib,         // dylib, staticlib, lib
    Bin,         // bin
    Example,     // example file
    Test,        // test file
    Bench,       // bench file
    CustomBuild, // build script
    ProcMacro,   // a proc macro implementation
    Other,       // plugin,...
}

impl TargetKind {
    fn should_format(&self) -> bool {
        match *self {
            TargetKind::Lib
            | TargetKind::Bin
            | TargetKind::Example
            | TargetKind::Test
            | TargetKind::Bench
            | TargetKind::CustomBuild
            | TargetKind::ProcMacro => true,
            _ => false,
        }
    }

    fn from_str(s: &str) -> Self {
        match s {
            "bin" => TargetKind::Bin,
            "lib" | "dylib" | "staticlib" | "cdylib" | "rlib" => TargetKind::Lib,
            "test" => TargetKind::Test,
            "example" => TargetKind::Example,
            "bench" => TargetKind::Bench,
            "custom-build" => TargetKind::CustomBuild,
            "proc-macro" => TargetKind::ProcMacro,
            _ => TargetKind::Other,
        }
    }
}

/// Target uses a `path` field for equality and hashing.
#[derive(Debug)]
pub struct Target {
    /// A path to the main source file of the target.
    path: PathBuf,
    /// A kind of target (e.g. lib, bin, example, ...).
    kind: TargetKind,
}

impl Target {
    pub fn from_target(target: &cargo_metadata::Target) -> Self {
        let path = PathBuf::from(&target.src_path);
        let canonicalized = fs::canonicalize(&path).unwrap_or(path);

        Target {
            path: canonicalized,
            kind: TargetKind::from_str(&target.kind[0]),
        }
    }
}

impl PartialEq for Target {
    fn eq(&self, other: &Target) -> bool {
        self.path == other.path
    }
}

impl Eq for Target {}

impl Hash for Target {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.path.hash(state);
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum WorkspaceHitlist {
    All,
    Some(Vec<String>),
    None,
}

impl WorkspaceHitlist {
    pub fn get_some(&self) -> Option<&[String]> {
        if let WorkspaceHitlist::Some(ref hitlist) = *self {
            Some(hitlist)
        } else {
            None
        }
    }

    pub fn from_matches(matches: &Matches) -> WorkspaceHitlist {
        match (matches.opt_present("all"), matches.opt_present("p")) {
            (false, false) => WorkspaceHitlist::None,
            (true, _) => WorkspaceHitlist::All,
            (false, true) => WorkspaceHitlist::Some(matches.opt_strs("p")),
        }
    }
}

fn get_cargo_metadata_from_utf8(v: &[u8]) -> Option<Value> {
    json::from_str(str::from_utf8(v).ok()?).ok()
}

fn get_json_array_with<'a>(v: &'a Value, key: &str) -> Option<&'a Vec<Value>> {
    v.as_object()?.get(key)?.as_array()
}

// `cargo metadata --no-deps | jq '.["packages"]'`
fn get_packages(v: &[u8]) -> Result<Vec<Value>, io::Error> {
    let e = io::Error::new(
        io::ErrorKind::NotFound,
        String::from("`cargo metadata` returned json without a 'packages' key"),
    );
    match get_cargo_metadata_from_utf8(v) {
        Some(ref json_obj) => get_json_array_with(json_obj, "packages").cloned().ok_or(e),
        None => Err(e),
    }
}

fn extract_target_from_package(package: &Value) -> Option<Vec<Target>> {
    let jtargets = get_json_array_with(package, "targets")?;
    let mut targets: Vec<Target> = vec![];
    for jtarget in jtargets {
        targets.push(Target::from_json(jtarget)?);
    }
    Some(targets)
}

fn filter_packages_with_hitlist(
    packages: Vec<Value>,
    workspace_hitlist: &WorkspaceHitlist,
) -> Result<Vec<Value>, &String> {
    let some_hitlist: Option<HashSet<&String>> =
        workspace_hitlist.get_some().map(HashSet::from_iter);
    if some_hitlist.is_none() {
        return Ok(packages);
    }
    let mut hitlist = some_hitlist.unwrap();
    let members: Vec<Value> = packages
        .into_iter()
        .filter(|member| {
            member
                .as_object()
                .and_then(|member_obj| {
                    member_obj
                        .get("name")
                        .and_then(Value::as_str)
                        .map(|member_name| {
                            hitlist.take(&member_name.to_string()).is_some()
                        })
                })
                .unwrap_or(false)
        })
        .collect();
    if hitlist.is_empty() {
        Ok(members)
    } else {
        Err(hitlist.into_iter().next().unwrap())
    }
}

fn get_dependencies_from_package(package: &Value) -> Option<Vec<PathBuf>> {
    let jdependencies = get_json_array_with(package, "dependencies")?;
    let root_path = env::current_dir().ok()?;
    let mut dependencies: Vec<PathBuf> = vec![];
    for jdep in jdependencies {
        let jdependency = jdep.as_object()?;
        if !jdependency.get("source")?.is_null() {
            continue;
        }
        let name = jdependency.get("name")?.as_str()?;
        let mut path = root_path.clone();
        path.push(&name);
        dependencies.push(path);
    }
    Some(dependencies)
}

// Returns a vector of local dependencies under this crate
fn get_path_to_local_dependencies(packages: &[Value]) -> Vec<PathBuf> {
    let mut local_dependencies: Vec<PathBuf> = vec![];
    for package in packages {
        if let Some(mut d) = get_dependencies_from_package(package) {
            local_dependencies.append(&mut d);
        }
    }
    local_dependencies
}

// Returns a vector of all compile targets of a crate
fn get_targets(workspace_hitlist: &WorkspaceHitlist) -> Result<Vec<Target>, io::Error> {
    let output = Command::new("cargo")
        .args(&["metadata", "--no-deps", "--format-version=1"])
        .output()?;
    if output.status.success() {
        let cur_dir = env::current_dir()?;
        let mut targets: Vec<Target> = vec![];
        let packages = get_packages(&output.stdout)?;

        // If we can find any local dependencies, we will try to get targets from those as well.
        if *workspace_hitlist == WorkspaceHitlist::All {
            for path in get_path_to_local_dependencies(&packages) {
                match env::set_current_dir(path) {
                    Ok(..) => match get_targets(workspace_hitlist) {
                        Ok(ref mut t) => targets.append(t),
                        Err(..) => continue,
                    },
                    Err(..) => continue,
                }
            }
        }

        env::set_current_dir(cur_dir)?;
        match filter_packages_with_hitlist(packages, workspace_hitlist) {
            Ok(packages) => {
                for package in packages {
                    if let Some(mut target) = extract_target_from_package(&package) {
                        targets.append(&mut target);
                    }
                }
                Ok(targets)
            }
            Err(package) => {
                // Mimick cargo of only outputting one <package> spec.
                Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    format!("package `{}` is not a member of the workspace", package),
                ))
            }
        }
    } else {
        Err(io::Error::new(
            io::ErrorKind::NotFound,
            str::from_utf8(&output.stderr).unwrap(),
        ))
    }
}

fn format_files(
    files: &[PathBuf],
    fmt_args: &[String],
    verbosity: Verbosity,
) -> Result<ExitStatus, io::Error> {
    let stdout = if verbosity == Verbosity::Quiet {
        std::process::Stdio::null()
    } else {
        std::process::Stdio::inherit()
    };
    if verbosity == Verbosity::Verbose {
        print!("rustfmt");
        for a in fmt_args {
            print!(" {}", a);
        }
        for f in files {
            print!(" {}", f.display());
        }
        println!();
    }
    let mut command = Command::new("rustfmt")
        .stdout(stdout)
        .args(files)
        .args(fmt_args)
        .spawn()
        .map_err(|e| match e.kind() {
            io::ErrorKind::NotFound => io::Error::new(
                io::ErrorKind::Other,
                "Could not run rustfmt, please make sure it is in your PATH.",
            ),
            _ => e,
        })?;
    command.wait()
}
<commit_msg>Use cargo_metadata crate over json crate<commit_after>// Copyright 2015-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/)

#![cfg(not(test))]
#![deny(warnings)]

extern crate cargo_metadata;
extern crate getopts;
extern crate serde_json as json;

use std::env;
use std::fs;
use std::hash::{Hash, Hasher};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use std::str;
use std::collections::HashSet;
use std::iter::FromIterator;

use getopts::{Matches, Options};

fn main() {
    let exit_status = execute();
    std::io::stdout().flush().unwrap();
    std::process::exit(exit_status);
}

fn execute() -> i32 {
    let success = 0;
    let failure = 1;

    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "show this message");
    opts.optflag("q", "quiet", "no output printed to stdout");
    opts.optflag("v", "verbose", "use verbose output");
    opts.optmulti(
        "p",
        "package",
        "specify package to format (only usable in workspaces)",
        "<package>",
    );
    opts.optflag("", "all", "format all packages (only usable in workspaces)");

    // If there is any invalid argument passed to `cargo fmt`, return without formatting.
    if let Some(arg) = env::args()
        .skip(2)
        .take_while(|a| a != "--")
        .find(|a| !a.starts_with('-'))
    {
        print_usage_to_stderr(&opts, &format!("Invalid argument: `{}`.", arg));
        return failure;
    }

    let matches = match opts.parse(env::args().skip(1).take_while(|a| a != "--")) {
        Ok(m) => m,
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            return failure;
        }
    };

    let verbosity = match (matches.opt_present("v"), matches.opt_present("q")) {
        (false, false) => Verbosity::Normal,
        (false, true) => Verbosity::Quiet,
        (true, false) => Verbosity::Verbose,
        (true, true) => {
            print_usage_to_stderr(&opts, "quiet mode and verbose mode are not compatible");
            return failure;
        }
    };

    if matches.opt_present("h") {
        print_usage_to_stdout(&opts, "");
        return success;
    }

    let workspace_hitlist = WorkspaceHitlist::from_matches(&matches);

    match format_crate(verbosity, &workspace_hitlist) {
        Err(e) => {
            print_usage_to_stderr(&opts, &e.to_string());
            failure
        }
        Ok(status) => if status.success() {
            success
        } else {
            status.code().unwrap_or(failure)
        },
    }
}

macro_rules! print_usage {
    ($print:ident, $opts:ident, $reason:expr) => ({
        let msg = format!("{}\nusage: cargo fmt [options]", $reason);
        $print!(
            "{}\nThis utility formats all bin and lib files of the current crate using rustfmt. \
             Arguments after `--` are passed to rustfmt.",
            $opts.usage(&msg)
        );
    })
}

fn print_usage_to_stdout(opts: &Options, reason: &str) {
    print_usage!(println, opts, reason);
}

fn print_usage_to_stderr(opts: &Options, reason: &str) {
    print_usage!(eprintln, opts, reason);
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Verbosity {
    Verbose,
    Normal,
    Quiet,
}

fn format_crate(
    verbosity: Verbosity,
    workspace_hitlist: &WorkspaceHitlist,
) -> Result<ExitStatus, io::Error> {
    let targets = get_targets(workspace_hitlist)?;

    // Currently only bin and lib files get formatted
    let files: Vec<_> = targets
        .into_iter()
        .filter(|t| t.kind.should_format())
        .inspect(|t| {
            if verbosity == Verbosity::Verbose {
                println!("[{:?}] {:?}", t.kind, t.path)
            }
        })
        .map(|t| t.path)
        .collect();

    format_files(&files, &get_fmt_args(), verbosity)
}

fn get_fmt_args() -> Vec<String> {
    // All arguments after -- are passed to rustfmt
    env::args().skip_while(|a| a != "--").skip(1).collect()
}

#[derive(Debug)]
enum TargetKind {
    Lib,         // dylib, staticlib, lib
    Bin,         // bin
    Example,     // example file
    Test,        // test file
    Bench,       // bench file
    CustomBuild, // build script
    ProcMacro,   // a proc macro implementation
    Other,       // plugin,...
}

impl TargetKind {
    fn should_format(&self) -> bool {
        match *self {
            TargetKind::Lib
            | TargetKind::Bin
            | TargetKind::Example
            | TargetKind::Test
            | TargetKind::Bench
            | TargetKind::CustomBuild
            | TargetKind::ProcMacro => true,
            _ => false,
        }
    }

    fn from_str(s: &str) -> Self {
        match s {
            "bin" => TargetKind::Bin,
            "lib" | "dylib" | "staticlib" | "cdylib" | "rlib" => TargetKind::Lib,
            "test" => TargetKind::Test,
            "example" => TargetKind::Example,
            "bench" => TargetKind::Bench,
            "custom-build" => TargetKind::CustomBuild,
            "proc-macro" => TargetKind::ProcMacro,
            _ => TargetKind::Other,
        }
    }
}

/// Target uses a `path` field for equality and hashing.
#[derive(Debug)]
pub struct Target {
    /// A path to the main source file of the target.
    path: PathBuf,
    /// A kind of target (e.g. lib, bin, example, ...).
    kind: TargetKind,
}

impl Target {
    pub fn from_target(target: &cargo_metadata::Target) -> Self {
        let path = PathBuf::from(&target.src_path);
        let canonicalized = fs::canonicalize(&path).unwrap_or(path);

        Target {
            path: canonicalized,
            kind: TargetKind::from_str(&target.kind[0]),
        }
    }
}

impl PartialEq for Target {
    fn eq(&self, other: &Target) -> bool {
        self.path == other.path
    }
}

impl Eq for Target {}

impl Hash for Target {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.path.hash(state);
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum WorkspaceHitlist {
    All,
    Some(Vec<String>),
    None,
}

impl WorkspaceHitlist {
    pub fn get_some(&self) -> Option<&[String]> {
        if let WorkspaceHitlist::Some(ref hitlist) = *self {
            Some(hitlist)
        } else {
            None
        }
    }

    pub fn from_matches(matches: &Matches) -> WorkspaceHitlist {
        match (matches.opt_present("all"), matches.opt_present("p")) {
            (false, false) => WorkspaceHitlist::None,
            (true, _) => WorkspaceHitlist::All,
            (false, true) => WorkspaceHitlist::Some(matches.opt_strs("p")),
        }
    }
}

fn get_targets(workspace_hitlist: &WorkspaceHitlist) -> Result<HashSet<Target>, io::Error> {
    let mut targets = HashSet::new();

    match *workspace_hitlist {
        WorkspaceHitlist::None => get_targets_root_only(&mut targets)?,
        WorkspaceHitlist::All => get_targets_recursive(None, &mut targets, &mut HashSet::new())?,
        WorkspaceHitlist::Some(ref hitlist) => get_targets_with_hitlist(hitlist, &mut targets)?,
    }

    if targets.is_empty() {
        Err(io::Error::new(
            io::ErrorKind::Other,
            format!("Failed to find targets"),
        ))
    } else {
        Ok(targets)
    }
}

fn get_targets_root_only(targets: &mut HashSet<Target>) -> Result<(), io::Error> {
    let metadata = get_cargo_metadata(None)?;

    for package in metadata.packages {
        for target in package.targets {
            if target.name == package.name {
                targets.insert(Target::from_target(&target));
            }
        }
    }

    Ok(())
}

fn get_targets_recursive(
    manifest_path: Option<&Path>,
    mut targets: &mut HashSet<Target>,
    visited: &mut HashSet<String>,
) -> Result<(), io::Error> {
    let metadata = get_cargo_metadata(manifest_path)?;

    for package in metadata.packages {
        add_targets(&package.targets, &mut targets);

        // Look for local dependencies.
        for dependency in package.dependencies {
            if dependency.source.is_some() || visited.contains(&dependency.name) {
                continue;
            }

            let mut manifest_path = PathBuf::from(&package.manifest_path);

            manifest_path.pop();
            manifest_path.push(&dependency.name);
            manifest_path.push("Cargo.toml");

            if manifest_path.exists() {
                visited.insert(dependency.name);
                get_targets_recursive(Some(&manifest_path), &mut targets, visited)?;
            }
        }
    }

    Ok(())
}

fn get_targets_with_hitlist(
    target_names: &[String],
    targets: &mut HashSet<Target>,
) -> Result<(), io::Error> {
    let metadata = get_cargo_metadata(None)?;

    let mut hitlist: HashSet<&String> = HashSet::from_iter(target_names);

    for package in metadata.packages {
        for target in package.targets {
            if hitlist.remove(&target.name) {
                targets.insert(Target::from_target(&target));
            }
        }
    }

    if hitlist.is_empty() {
        Ok(())
    } else {
        let package = hitlist.iter().next().unwrap();
        Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            format!("package `{}` is not a member of the workspace", package),
        ))
    }
}

fn add_targets(target_paths: &[cargo_metadata::Target], targets: &mut HashSet<Target>) {
    for target in target_paths {
        targets.insert(Target::from_target(&target));
    }
}

fn format_files(
    files: &[PathBuf],
    fmt_args: &[String],
    verbosity: Verbosity,
) -> Result<ExitStatus, io::Error> {
    let stdout = if verbosity == Verbosity::Quiet {
        std::process::Stdio::null()
    } else {
        std::process::Stdio::inherit()
    };
    if verbosity == Verbosity::Verbose {
        print!("rustfmt");
        for a in fmt_args {
            print!(" {}", a);
        }
        for f in files {
            print!(" {}", f.display());
        }
        println!();
    }
    let mut command = Command::new("rustfmt")
        .stdout(stdout)
        .args(files)
        .args(fmt_args)
        .spawn()
        .map_err(|e| match e.kind() {
            io::ErrorKind::NotFound => io::Error::new(
                io::ErrorKind::Other,
                "Could not run rustfmt, please make sure it is in your PATH.",
            ),
            _ => e,
        })?;
    command.wait()
}

fn get_cargo_metadata(manifest_path: Option<&Path>) -> Result<cargo_metadata::Metadata, io::Error> {
    match cargo_metadata::metadata(manifest_path) {
        Ok(metadata) => Ok(metadata),
        Err(..) => Err(io::Error::new(
            io::ErrorKind::Other,
            "`cargo manifest` failed.",
        )),
    }
}
<|endoftext|>