<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::{Arc, RwLock};
use std::sync::mpsc::Sender;
use std::boxed::Box;
use std::net::{SocketAddr, IpAddr};
use std::str::FromStr;

use grpc::{Server as GrpcServer, ServerBuilder, Environment, ChannelBuilder};
use kvproto::tikvpb_grpc::*;
use util::worker::Worker;
use storage::Storage;
use raftstore::store::{SnapshotStatusMsg, SnapManager};

use super::{Result, Config};
use coprocessor::{EndPointHost, EndPointTask};
use super::grpc_service::Service;
use super::transport::{RaftStoreRouter, ServerTransport};
use super::resolve::StoreAddrResolver;
use super::snap::{Task as SnapTask, Runner as SnapHandler};
use super::raft_client::RaftClient;

const DEFAULT_COPROCESSOR_BATCH: usize = 50;
const MAX_GRPC_RECV_MSG_LEN: usize = 10 * 1024 * 1024;
const MAX_GRPC_SEND_MSG_LEN: usize = 128 * 1024 * 1024;

pub struct Server<T: RaftStoreRouter + 'static, S: StoreAddrResolver + 'static> {
    env: Arc<Environment>,
    // Grpc server.
    grpc_server: GrpcServer,
    local_addr: SocketAddr,
    // Transport.
    trans: ServerTransport<T, S>,
    raft_router: T,
    // The kv storage.
    storage: Storage,
    // For handling coprocessor requests.
    end_point_worker: Worker<EndPointTask>,
    // For sending/receiving snapshots.
    snap_mgr: SnapManager,
    snap_worker: Worker<SnapTask>,
}

impl<T: RaftStoreRouter, S: StoreAddrResolver + 'static> Server<T, S> {
    pub fn new(cfg: &Config,
               storage: Storage,
               raft_router: T,
               snapshot_status_sender: Sender<SnapshotStatusMsg>,
               resolver: S,
               snap_mgr: SnapManager)
               -> Result<Server<T, S>> {
        let env = Arc::new(Environment::new(cfg.grpc_concurrency));
        let raft_client = Arc::new(RwLock::new(RaftClient::new(env.clone(), cfg.clone())));
        let end_point_worker = Worker::new("end-point-worker");
        let snap_worker = Worker::new("snap-handler");

        let h = Service::new(storage.clone(),
                             end_point_worker.scheduler(),
                             raft_router.clone(),
                             snap_worker.scheduler());
        let addr = try!(SocketAddr::from_str(&cfg.addr));
        let ip = format!("{}", addr.ip());
        let channel_args = ChannelBuilder::new(env.clone())
            .stream_initial_window_size(cfg.grpc_stream_initial_window_size)
            .max_concurrent_stream(cfg.grpc_concurrent_stream)
            .max_receive_message_len(MAX_GRPC_RECV_MSG_LEN)
            .max_send_message_len(MAX_GRPC_SEND_MSG_LEN)
            .build_args();
        let grpc_server = try!(ServerBuilder::new(env.clone())
            .register_service(create_tikv(h))
            .bind(ip, addr.port())
            .channel_args(channel_args)
            .build());

        let addr = {
            let (ref host, port) = grpc_server.bind_addrs()[0];
            SocketAddr::new(try!(IpAddr::from_str(host)), port as u16)
        };

        let trans = ServerTransport::new(raft_client,
                                         snap_worker.scheduler(),
                                         raft_router.clone(),
                                         snapshot_status_sender,
                                         resolver);

        let svr = Server {
            env: env.clone(),
            grpc_server: grpc_server,
            local_addr: addr,
            trans: trans,
            raft_router: raft_router,
            storage: storage,
            end_point_worker: end_point_worker,
            snap_mgr: snap_mgr,
            snap_worker: snap_worker,
        };

        Ok(svr)
    }

    pub fn transport(&self) -> ServerTransport<T, S> {
        self.trans.clone()
    }

    pub fn start(&mut self, cfg: &Config) -> Result<()> {
        let end_point = EndPointHost::new(self.storage.get_engine(),
                                          self.end_point_worker.scheduler(),
                                          cfg.end_point_concurrency,
                                          cfg.end_point_txn_concurrency_on_busy,
                                          cfg.end_point_small_txn_tasks_limit);
        box_try!(self.end_point_worker.start_batch(end_point, DEFAULT_COPROCESSOR_BATCH));
        let snap_runner = SnapHandler::new(self.env.clone(),
                                           self.snap_mgr.clone(),
                                           self.raft_router.clone());
        box_try!(self.snap_worker.start(snap_runner));
        self.grpc_server.start();
        info!("TiKV is ready to serve");
        Ok(())
    }

    pub fn stop(&mut self) -> Result<()> {
        self.end_point_worker.stop();
        self.snap_worker.stop();
        if let Err(e) = self.storage.stop() {
            error!("failed to stop store: {:?}", e);
        }
        self.grpc_server.shutdown();
        Ok(())
    }

    // Return listening address, this may only be used for outer test
    // to get the real address because we may use "127.0.0.1:0"
    // in test to avoid port conflict.
    pub fn listening_addr(&self) -> SocketAddr {
        self.local_addr
    }
}

#[cfg(test)]
mod tests {
    use std::time::Duration;
    use std::sync::{Arc, Mutex};
    use std::sync::mpsc::{self, Sender};
    use std::net::SocketAddr;
    use std::sync::atomic::{AtomicUsize, Ordering};

    use super::*;
    use super::super::{Result, Config};
    use super::super::transport::RaftStoreRouter;
    use super::super::resolve::{StoreAddrResolver, Callback as ResolveCallback};
    use storage::Storage;
    use kvproto::raft_serverpb::RaftMessage;
    use raftstore::Result as RaftStoreResult;
    use raftstore::store::Msg as StoreMsg;
    use raftstore::store::transport::Transport;

    struct MockResolver {
        addr: Arc<Mutex<Option<SocketAddr>>>,
    }

    impl StoreAddrResolver for MockResolver {
        fn resolve(&self, _: u64, cb: ResolveCallback) -> Result<()> {
            cb.call_box((self.addr.lock().unwrap().ok_or(box_err!("not set")),));
            Ok(())
        }
    }

    #[derive(Clone)]
    struct TestRaftStoreRouter {
        tx: Sender<usize>,
        report_unreachable_count: Arc<AtomicUsize>,
    }

    impl TestRaftStoreRouter {
        fn new(tx: Sender<usize>) -> TestRaftStoreRouter {
            TestRaftStoreRouter {
                tx: tx,
                report_unreachable_count: Arc::new(AtomicUsize::new(0)),
            }
        }
    }

    impl RaftStoreRouter for TestRaftStoreRouter {
        fn send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn try_send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn report_unreachable(&self, _: u64, _: u64, _: u64) -> RaftStoreResult<()> {
            let count = self.report_unreachable_count.clone();
            count.fetch_add(1, Ordering::SeqCst);
            Ok(())
        }
    }

    #[test]
    fn test_peer_resolve() {
        let mut cfg = Config::new();
        cfg.addr = "127.0.0.1:0".to_owned();

        let mut storage = Storage::new(&cfg.storage).unwrap();
        storage.start(&cfg.storage).unwrap();

        let (tx, rx) = mpsc::channel();
        let router = TestRaftStoreRouter::new(tx);
        let report_unreachable_count = router.report_unreachable_count.clone();
        let (snapshot_status_sender, _) = mpsc::channel();

        let addr = Arc::new(Mutex::new(None));
        let mut server =
            Server::new(&cfg,
                        storage,
                        router,
                        snapshot_status_sender,
                        MockResolver { addr: addr.clone() },
                        SnapManager::new("", None, cfg.raft_store.use_sst_file_snapshot))
                .unwrap();
        *addr.lock().unwrap() = Some(server.listening_addr());

        server.start(&cfg).unwrap();

        let trans = server.transport();
        for i in 0..10 {
            if i % 2 == 1 {
                trans.report_unreachable(RaftMessage::new());
            }
            assert_eq!(report_unreachable_count.load(Ordering::SeqCst), (i + 1) / 2);
        }
        let mut msg = RaftMessage::new();
        msg.set_region_id(1);
        trans.send(msg).unwrap();
        assert!(rx.recv_timeout(Duration::from_secs(5)).is_ok());
        server.stop().unwrap();
    }
}
<commit_msg>*: fix test_peer_resove test. (#2010)<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::{Arc, RwLock};
use std::sync::mpsc::Sender;
use std::boxed::Box;
use std::net::{SocketAddr, IpAddr};
use std::str::FromStr;

use grpc::{Server as GrpcServer, ServerBuilder, Environment, ChannelBuilder};
use kvproto::tikvpb_grpc::*;
use util::worker::Worker;
use storage::Storage;
use raftstore::store::{SnapshotStatusMsg, SnapManager};

use super::{Result, Config};
use coprocessor::{EndPointHost, EndPointTask};
use super::grpc_service::Service;
use super::transport::{RaftStoreRouter, ServerTransport};
use super::resolve::StoreAddrResolver;
use super::snap::{Task as SnapTask, Runner as SnapHandler};
use super::raft_client::RaftClient;

const DEFAULT_COPROCESSOR_BATCH: usize = 50;
const MAX_GRPC_RECV_MSG_LEN: usize = 10 * 1024 * 1024;
const MAX_GRPC_SEND_MSG_LEN: usize = 128 * 1024 * 1024;

pub struct Server<T: RaftStoreRouter + 'static, S: StoreAddrResolver + 'static> {
    env: Arc<Environment>,
    // Grpc server.
    grpc_server: GrpcServer,
    local_addr: SocketAddr,
    // Transport.
    trans: ServerTransport<T, S>,
    raft_router: T,
    // The kv storage.
    storage: Storage,
    // For handling coprocessor requests.
    end_point_worker: Worker<EndPointTask>,
    // For sending/receiving snapshots.
    snap_mgr: SnapManager,
    snap_worker: Worker<SnapTask>,
}

impl<T: RaftStoreRouter, S: StoreAddrResolver + 'static> Server<T, S> {
    pub fn new(cfg: &Config,
               storage: Storage,
               raft_router: T,
               snapshot_status_sender: Sender<SnapshotStatusMsg>,
               resolver: S,
               snap_mgr: SnapManager)
               -> Result<Server<T, S>> {
        let env = Arc::new(Environment::new(cfg.grpc_concurrency));
        let raft_client = Arc::new(RwLock::new(RaftClient::new(env.clone(), cfg.clone())));
        let end_point_worker = Worker::new("end-point-worker");
        let snap_worker = Worker::new("snap-handler");

        let h = Service::new(storage.clone(),
                             end_point_worker.scheduler(),
                             raft_router.clone(),
                             snap_worker.scheduler());
        let addr = try!(SocketAddr::from_str(&cfg.addr));
        let ip = format!("{}", addr.ip());
        let channel_args = ChannelBuilder::new(env.clone())
            .stream_initial_window_size(cfg.grpc_stream_initial_window_size)
            .max_concurrent_stream(cfg.grpc_concurrent_stream)
            .max_receive_message_len(MAX_GRPC_RECV_MSG_LEN)
            .max_send_message_len(MAX_GRPC_SEND_MSG_LEN)
            .build_args();
        let grpc_server = try!(ServerBuilder::new(env.clone())
            .register_service(create_tikv(h))
            .bind(ip, addr.port())
            .channel_args(channel_args)
            .build());

        let addr = {
            let (ref host, port) = grpc_server.bind_addrs()[0];
            SocketAddr::new(try!(IpAddr::from_str(host)), port as u16)
        };

        let trans = ServerTransport::new(raft_client,
                                         snap_worker.scheduler(),
                                         raft_router.clone(),
                                         snapshot_status_sender,
                                         resolver);

        let svr = Server {
            env: env.clone(),
            grpc_server: grpc_server,
            local_addr: addr,
            trans: trans,
            raft_router: raft_router,
            storage: storage,
            end_point_worker: end_point_worker,
            snap_mgr: snap_mgr,
            snap_worker: snap_worker,
        };

        Ok(svr)
    }

    pub fn transport(&self) -> ServerTransport<T, S> {
        self.trans.clone()
    }

    pub fn start(&mut self, cfg: &Config) -> Result<()> {
        let end_point = EndPointHost::new(self.storage.get_engine(),
                                          self.end_point_worker.scheduler(),
                                          cfg.end_point_concurrency,
                                          cfg.end_point_txn_concurrency_on_busy,
                                          cfg.end_point_small_txn_tasks_limit);
        box_try!(self.end_point_worker.start_batch(end_point, DEFAULT_COPROCESSOR_BATCH));
        let snap_runner = SnapHandler::new(self.env.clone(),
                                           self.snap_mgr.clone(),
                                           self.raft_router.clone());
        box_try!(self.snap_worker.start(snap_runner));
        self.grpc_server.start();
        info!("TiKV is ready to serve");
        Ok(())
    }

    pub fn stop(&mut self) -> Result<()> {
        self.end_point_worker.stop();
        self.snap_worker.stop();
        if let Err(e) = self.storage.stop() {
            error!("failed to stop store: {:?}", e);
        }
        self.grpc_server.shutdown();
        Ok(())
    }

    // Return listening address, this may only be used for outer test
    // to get the real address because we may use "127.0.0.1:0"
    // in test to avoid port conflict.
    pub fn listening_addr(&self) -> SocketAddr {
        self.local_addr
    }
}

#[cfg(test)]
mod tests {
    use std::time::Duration;
    use std::sync::{Arc, Mutex};
    use std::sync::mpsc::{self, Sender};
    use std::net::SocketAddr;
    use std::sync::atomic::{AtomicUsize, Ordering};

    use super::*;
    use super::super::{Result, Config};
    use super::super::transport::RaftStoreRouter;
    use super::super::resolve::{StoreAddrResolver, Callback as ResolveCallback};
    use storage::Storage;
    use kvproto::raft_serverpb::RaftMessage;
    use raftstore::Result as RaftStoreResult;
    use raftstore::store::Msg as StoreMsg;
    use raftstore::store::transport::Transport;

    struct MockResolver {
        addr: Arc<Mutex<Option<SocketAddr>>>,
    }

    impl StoreAddrResolver for MockResolver {
        fn resolve(&self, _: u64, cb: ResolveCallback) -> Result<()> {
            cb.call_box((self.addr.lock().unwrap().ok_or(box_err!("not set")),));
            Ok(())
        }
    }

    #[derive(Clone)]
    struct TestRaftStoreRouter {
        tx: Sender<usize>,
        report_unreachable_count: Arc<AtomicUsize>,
    }

    impl TestRaftStoreRouter {
        fn new(tx: Sender<usize>) -> TestRaftStoreRouter {
            TestRaftStoreRouter {
                tx: tx,
                report_unreachable_count: Arc::new(AtomicUsize::new(0)),
            }
        }
    }

    impl RaftStoreRouter for TestRaftStoreRouter {
        fn send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn try_send(&self, _: StoreMsg) -> RaftStoreResult<()> {
            self.tx.send(1).unwrap();
            Ok(())
        }

        fn report_unreachable(&self, _: u64, _: u64, _: u64) -> RaftStoreResult<()> {
            let count = self.report_unreachable_count.clone();
            count.fetch_add(1, Ordering::SeqCst);
            Ok(())
        }
    }

    #[test]
    fn test_peer_resolve() {
        let mut cfg = Config::new();
        cfg.addr = "127.0.0.1:0".to_owned();

        let mut storage = Storage::new(&cfg.storage).unwrap();
        storage.start(&cfg.storage).unwrap();

        let (tx, rx) = mpsc::channel();
        let router = TestRaftStoreRouter::new(tx);
        let report_unreachable_count = router.report_unreachable_count.clone();
        let (snapshot_status_sender, _) = mpsc::channel();

        let addr = Arc::new(Mutex::new(None));
        let mut server =
            Server::new(&cfg,
                        storage,
                        router,
                        snapshot_status_sender,
                        MockResolver { addr: addr.clone() },
                        SnapManager::new("", None, cfg.raft_store.use_sst_file_snapshot))
                .unwrap();
        *addr.lock().unwrap() = Some(server.listening_addr());

        server.start(&cfg).unwrap();

        let mut trans = server.transport();
        for i in 0..10 {
            if i % 2 == 1 {
                trans.report_unreachable(RaftMessage::new());
            }
            assert_eq!(report_unreachable_count.load(Ordering::SeqCst), (i + 1) / 2);
        }
        let mut msg = RaftMessage::new();
        msg.set_region_id(1);
        trans.send(msg).unwrap();
        trans.flush();
        assert!(rx.recv_timeout(Duration::from_secs(5)).is_ok());
        server.stop().unwrap();
    }
}
<|endoftext|>


<commit_before>use hyper;
use futures;
use futures::Future;
use hyper::{Client, StatusCode, Body};
use hyper::client::HttpConnector;
use hyper::server::{Service, Request, Response};

pub struct Proxy {
    pub routes: Vec<String>,
    pub client: Client<HttpConnector, Body>,
}

impl Service for Proxy {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item=Response, Error=Self::Error>>;

    fn call(&self, req: Request) -> Self::Future {
        let l = self.routes.len();
        let uri = req.uri();
        let fut = {
            let index = if let Some(addr) = req.remote_addr() {
                addr.port() % (l as u16)
            } else {
                0
            } as usize;
            let backend_addr = self.routes[index].clone();
            let url = format!("http://{}{}", backend_addr, uri.path())
                .parse::<hyper::Uri>().expect("uri error");
            let mut proxied_req = hyper::client::Request::new(req.method().clone(), url);
            *proxied_req.headers_mut() = req.headers().clone();
            let req = self.client.request(proxied_req);
            Box::new(req.then(|res| {
                if let Ok(res) = res {
                    futures::future::ok(
                        Response::new()
                        .with_status(res.status().clone())
                        .with_headers(res.headers().clone())
                        .with_body(res.body()))
                } else {
                    futures::future::ok(
                        Response::new()
                        .with_status(StatusCode::ServiceUnavailable))
                }
            })) as Self::Future
        };
        fut
    }
}
<commit_msg>foward request body and query string<commit_after>use hyper;
use futures;
use futures::Future;
use hyper::{Client, StatusCode, Body};
use hyper::client::HttpConnector;
use hyper::server::{self, Service, Request, Response};

pub struct Proxy {
    pub routes: Vec<String>,
    pub client: Client<HttpConnector, Body>,
}

impl Service for Proxy {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item=Response, Error=Self::Error>>;

    fn call(&self, req: server::Request) -> Self::Future {
        let uri = req.uri().clone();
        let fut = {
            // load blancing, port-hash now
            let index = if let Some(addr) = req.remote_addr() {
                addr.port() % (self.routes.len() as u16)
            } else {
                0
            } as usize;
            let backend_addr = self.routes[index].clone();

            // create request
            let url_str = match uri.query() {
                Some(query) => format!("http://{}{}?{}", backend_addr, uri.path(), query),
                None => format!("http://{}{}", backend_addr, uri.path()),
            };
            let url = url_str.parse::<hyper::Uri>().expect("uri error");
            let mut proxied_req = hyper::client::Request::new(req.method().clone(), url);
            *proxied_req.headers_mut() = req.headers().clone();
            proxied_req.set_body(req.body());

            // request to backend server
            let req = self.client.request(proxied_req);
            Box::new(req.then(|res| {
                if let Ok(res) = res {
                    futures::future::ok(
                        Response::new()
                        .with_status(res.status().clone())
                        .with_headers(res.headers().clone())
                        .with_body(res.body()))
                } else {
                    futures::future::ok(
                        Response::new()
                        .with_status(StatusCode::ServiceUnavailable))
                }
            })) as Self::Future
        };
        fut
    }
}
<|endoftext|>


<commit_before>//!
//! Code to create a scaled read-count track
//!
use htslib::bam;
use htslib::bam::Read;
use htslib::bam::Reader;
use htslib::bam::Records;
use std::path::Path;
use std::error::Error;
use std::fs::File;
use std::ffi::OsString;
use std::ffi::OsStr;
use std::io::Read as ioRead;
use std::io::Write as ioWrite;
use std::io::Seek;
use std::io::Error as ioError;
use std::process::exit;
use std::iter::Peekable;
use seqtable::{SeqTable,SequenceInfo};
use std::collections::BTreeMap;
use std::collections::btree_map::Iter;
use bigwig::write_bigwig;
use bigwig::Strand;
use filter::{RecordCheck, PairedChecker, SingleChecker};

#[derive(Debug)]
pub struct PileUp {
    chroms: Vec<String>,
    chrom_sizes: Vec<u32>,
    counts: Vec<BTreeMap<u32, (f64, f64)>>,
    minus_shift: i32,
    no_scale: bool,
}

impl PileUp {

    fn new(sinfos: &Vec<SequenceInfo>, minus_shift: i32, no_scale: bool) -> PileUp {
        let mut chroms = Vec::new();
        let mut counts = Vec::new();
        let mut chrom_sizes = Vec::new();

        for sinfo in sinfos {
            chroms.push(sinfo.name.clone());
            chrom_sizes.push(sinfo.length);
            counts.push(BTreeMap::new());
        }

        PileUp { chroms: chroms, chrom_sizes: chrom_sizes, counts: counts, minus_shift: minus_shift, no_scale: no_scale}
    }

    fn add_data<R: ioRead+Seek, C: RecordCheck>(&mut self, table: &mut SeqTable<R>, bamrecs: &mut Peekable<Records<Reader>>, tid: &mut i32, map: &Vec<usize>, scale: &Vec<(f64, f64)>, checker: &C) -> bool {
        // skip unmapped sequences (tid = -1)
        if *tid < 0 {
            match bamrecs.next() {
                Some(Ok(ref rec)) => { *tid = rec.tid(); return true; },
                Some(Err(_)) => return false,
                None => return false,
            }
        }

        let sidx = map[*tid as usize];
        let rlen = table.params.read_length as usize;
        let slen = table.len_by_idx(sidx).ok().expect("read sequence length") as i32;
        let mut rdr = table.get_sequence_by_idx(sidx).ok().expect("read sequence");

        loop {
            // check if we changed sequence
            match bamrecs.peek() {
                Some(&Ok(ref rec)) => if rec.tid() != *tid { *tid = rec.tid(); return true; },
                Some(&Err(_)) => return false,
                None => return false,
            }

            // if not count position
            if let Some(Ok(record)) = bamrecs.next() {
                if checker.valid(&record) {
                    let pos = checker.vir_pos(&record);
                    if pos < slen {
                        let (plus_idx, minus_idx) = rdr.vir_get(pos).unwrap();

                        if record.is_reverse() {
                            if minus_idx == 0 {
                                /* no data */
                            } else {
                                let inc = if self.no_scale { 1f64 } else { scale[minus_idx as usize].1 };
                                let minus_pos = (checker.vir_pos(&record) + rlen as i32 - 1i32 + self.minus_shift) as u32;
                                self.counts[sidx as usize].entry(minus_pos).or_insert((0f64, 0f64)).1 += inc;
                            }
                        } else {
                            if plus_idx == 0 {
                                /* no data */
                            } else {
                                let inc = if self.no_scale { 1f64 } else { scale[plus_idx as usize].0 };
                                self.counts[sidx as usize].entry(checker.vir_pos(&record) as u32).or_insert((0f64, 0f64)).0 += inc;
                            }
                        }
                    }
                }
            }
        }
    }

    pub fn write_bed(&self, filename: &str, stranded: bool) -> Result<(),ioError> {
        // open new file
        let mut f = try!(File::create(filename));

        // write data
        for i in 0..self.chroms.len() {
            let chrom : &str = &self.chroms[i];

            for (pos, value) in self.counts[i].iter() {

                if stranded {
                    if value.0 > 0f64 {
                        try!(write!(f, "{}\t{}\t{}\t.\t{}\t+\n", chrom, pos, pos + 1, value.0));
                    }
                    if value.1 > 0f64 {
                        try!(write!(f, "{}\t{}\t{}\t.\t{}\t-\n", chrom, pos, pos + 1, -value.1));
                    }
                } else {
                    try!(write!(f, "{}\t{}\t{}\t.\t{}\n", chrom, pos, pos + 1, value.0 + value.1));
                }
            }
        }
        Ok(())
    }

    fn bw_stranded_filename(filename: &str, strand: Strand) -> OsString {
        let def_ext : &OsStr = OsStr::new("bw");
        let mut basename: OsString = Path::new(filename).file_stem().unwrap_or(OsStr::new(filename)).to_os_string();
        let extension = Path::new(filename).extension().unwrap_or(def_ext).to_os_string();

        match strand {
            Strand::Plus => basename.push("_plus."),
            Strand::Minus => basename.push("_minus."),
            Strand::Both => unreachable!(),
        }
        basename.push(extension);

        return basename;
    }

    pub fn write_bw(&self, filename: &str, stranded: bool) -> Result<(String
    , Option<String>), ioError> {
        if stranded {
            let output_plus = PileUp::bw_stranded_filename(filename, Strand::Plus);
            let output_minus = PileUp::bw_stranded_filename(filename, Strand::Minus);

	        match write_bigwig(&output_plus, &self.chroms, &self.chrom_sizes, &self.counts, Strand::Plus) {
                Ok(_) => {
                    try!(write_bigwig(&output_minus, &self.chroms, &self.chrom_sizes, &self.counts, Strand::Minus));
                    Ok((output_plus.into_string().unwrap(), Some(output_minus.into_string().unwrap())))
                },
                Err(err) => Err(err),
            }
        } else {
            try!(write_bigwig(OsStr::new(filename), &self.chroms, &self.chrom_sizes, &self.counts, Strand::Both));
            Ok((String::from(filename), None))
        }
    }

    pub fn chrom_index(&self, chrom: &str) -> Option<usize> {
        self.chroms.iter().position(|x| x == chrom)
    }

    pub fn chrom_size(&self, index: usize) -> Option<u32> {
        self.chrom_sizes.get(index).map(|&x| x)
    }

    pub fn get(&self, chrom_index: usize, position: u32) -> Option<&(f64, f64)> {
        if chrom_index >= self.counts.len() { return None; }
        self.counts[chrom_index].get(&position)
    }

    pub fn chrom_iter(&self, index: usize) -> Iter<u32, (f64, f64)> {
        self.counts[index].iter()
    }
}

fn scale_factor(exp: u64, etotal: u64, obs: u64, ototal: u64) -> f64 {
    let fexp = if etotal > 0 { exp as f64 / etotal as f64 } else { 0f64 };
    let fobs = if ototal > 0 { obs as f64 / ototal as f64 } else { 0f64 };
    if fobs > 0f64 { fexp / fobs } else { 0f64 }
}

fn compute_scale_factors(counts: &Vec<(u64, u64, u64, u64)>) -> Vec<(f64, f64)> {
    // compute totals
    // skip first row which contains unmappable/unusable position counts
    let totals = counts.iter().skip(1).fold((0u64, 0u64, 0u64, 0u64),
        |acc, &(sp, sm, bp, bm)| ( acc.0 + sp, acc.1 + sm, acc.2 + bp, acc.3 + bm));

    // compute scale
    // x = Obs * ExpFreq / ObsFreq
    // scale = ExpFreq / ObsFreq
    counts.iter().map(|&(sp, sm, bp, bm)| {
        ( scale_factor(sp, totals.0, bp, totals.2),
          scale_factor(sm, totals.1, bm, totals.3)
        )
    }).collect()
}

pub fn scale(seqfile: &str, counts: Vec<(u64, u64, u64, u64)>, bamfiles: &Vec<String>, minqual: u8, shift: bool, no_scale: bool, pair_range: &Option<(i32, i32)>, paired: bool, exact_length: bool, tail_edge: bool) -> PileUp {
    // read
    let file = match File::open(seqfile) {
        Ok(value) => value,
        Err(err) => {
            println!("Error: Failed to open sequence table file '{}': {}", seqfile, err.description());
            exit(1);
        },
    };
    let mut table = match SeqTable::open(file) {
        Ok(value) => value,
        Err(e) => {
            println!("Error:tabulate: {}", e.to_string());
            exit(1);
        },
    };

    let seqinfos = table.sequences();
    let rlen = table.params.read_length as usize;
    let minus_shift = if shift {
        let res = (table.params.plus_offset as i16 - (table.params.kmer_length as i16 - table.params.minus_offset as i16 - 1i16)) as i32;
        println!("# minus strand shift = {} bp", res);
        res
    } else {
        0i32
    };

    let mut pileup = PileUp::new(&seqinfos, minus_shift, no_scale);

    for bamfile in bamfiles {
        println!("# scale {}", &bamfile);
        let bam = match bam::Reader::from_path(&Path::new(bamfile)) {
            Ok(value) => value,
            Err(err) => {
                println!("Error: Failed to open BAM file '{}': {}", bamfile, err.description());
                exit(1);
            },
        };
        let names = bam.header().target_names();
        let mut cur_tid = 0;

        // map BAM tid's to SeqTable idx's
        let map : Vec<usize> = names.iter().map(|&id| {
            let chrom = String::from_utf8_lossy(id);
            for i in 0..seqinfos.len() {
                if seqinfos[i].name.eq(&chrom) {
                    return i;
                }
            }
            println!("Error: Unknown sequence name in BAM: {}", chrom);
            exit(1);
        }
        ).collect();

        // reads
        let mut iter = bam.records().peekable();
        let scale = compute_scale_factors(&counts);

        if pair_range.is_some() || paired {
            let checker = match *pair_range {
                Some((min, max)) => PairedChecker {
                    tail_edge: tail_edge,
                    exact_length: exact_length,
                    read_length: rlen,
                    min_quality: minqual,
                    min_dist: min,
                    max_dist: max,
                    force_paired: paired,
                    max_distance: true,
                },
                None => PairedChecker {
                    tail_edge: tail_edge,
                    exact_length: exact_length,
                    read_length: rlen,
                    min_quality: minqual,
                    min_dist: 0,
                    max_dist: 0,
                    force_paired: paired,
                    max_distance: false,
                },
            };
            while pileup.add_data(&mut table, &mut iter, &mut cur_tid, &map, &scale, &checker) {}
        } else {
            let checker = SingleChecker { tail_edge: tail_edge, exact_length: exact_length, read_length: rlen, min_quality: minqual };
            while pileup.add_data(&mut table, &mut iter, &mut cur_tid, &map, &scale, &checker) {}
        }
    }

    pileup
}
<commit_msg>reverse_complement minus index<commit_after>//!
//! Code to create a scaled read-count track
//!
use htslib::bam;
use htslib::bam::Read;
use htslib::bam::Reader;
use htslib::bam::Records;
use std::path::Path;
use std::error::Error;
use std::fs::File;
use std::ffi::OsString;
use std::ffi::OsStr;
use std::io::Read as ioRead;
use std::io::Write as ioWrite;
use std::io::Seek;
use std::io::Error as ioError;
use std::process::exit;
use std::iter::Peekable;
use seqtable::{SeqTable,SequenceInfo};
use std::collections::BTreeMap;
use std::collections::btree_map::Iter;
use bigwig::write_bigwig;
use bigwig::Strand;
use filter::{RecordCheck, PairedChecker, SingleChecker};

#[derive(Debug)]
pub struct PileUp {
    chroms: Vec<String>,
    chrom_sizes: Vec<u32>,
    counts: Vec<BTreeMap<u32, (f64, f64)>>,
    minus_shift: i32,
    no_scale: bool,
}

pub fn reverse_complement(mer: u64, kmersize: u8) -> u64 {
    let mut res = (!mer).wrapping_add(1);
    res = (res >> 2 & 0x3333333333333333) | (res & 0x3333333333333333) << 2;
    res = res >> 4 & 0xf0f0f0f0f0f0f0f | (res & 0xf0f0f0f0f0f0f0f) << 4;
    res = res >> 8 & 0xff00ff00ff00ff | (res & 0xff00ff00ff00ff) << 8;
    res = res >> 16 & 0xffff0000ffff | (res & 0xffff0000ffff) << 16;
    res = res >> 32 & 0xffffffff | (res & 0xffffffff) << 32;
    res = (res >> 2 * (32 - kmersize)).wrapping_add(1);
    return res;
}

impl PileUp {

    fn new(sinfos: &Vec<SequenceInfo>, minus_shift: i32, no_scale: bool) -> PileUp {
        let mut chroms = Vec::new();
        let mut counts = Vec::new();
        let mut chrom_sizes = Vec::new();

        for sinfo in sinfos {
            chroms.push(sinfo.name.clone());
            chrom_sizes.push(sinfo.length);
            counts.push(BTreeMap::new());
        }

        PileUp { chroms: chroms, chrom_sizes: chrom_sizes, counts: counts, minus_shift: minus_shift, no_scale: no_scale}
    }

    fn add_data<R: ioRead+Seek, C: RecordCheck>(&mut self, table: &mut SeqTable<R>, bamrecs: &mut Peekable<Records<Reader>>, tid: &mut i32, map: &Vec<usize>, scale: &Vec<(f64, f64)>, checker: &C) -> bool {
        // skip unmapped sequences (tid = -1)
        if *tid < 0 {
            match bamrecs.next() {
                Some(Ok(ref rec)) => { *tid = rec.tid(); return true; },
                Some(Err(_)) => return false,
                None => return false,
            }
        }

        let sidx = map[*tid as usize];
        let rlen = table.params.read_length as usize;
	let ksze = table.params.kmer_length as u8;
        let slen = table.len_by_idx(sidx).ok().expect("read sequence length") as i32;
        let mut rdr = table.get_sequence_by_idx(sidx).ok().expect("read sequence");

        loop {
            // check if we changed sequence
            match bamrecs.peek() {
                Some(&Ok(ref rec)) => if rec.tid() != *tid { *tid = rec.tid(); return true; },
                Some(&Err(_)) => return false,
                None => return false,
            }

            // if not count position
            if let Some(Ok(record)) = bamrecs.next() {
                if checker.valid(&record) {
                    let pos = checker.vir_pos(&record);
                    if pos < slen {
                        let (plus_idx, minus_idx) = rdr.vir_get(pos).unwrap();

                        if record.is_reverse() {
                            if minus_idx == 0 {
                                /* no data */
                            } else {
                                let inc = if self.no_scale { 1f64 } else { scale[reverse_complement(minus_idx as u64, ksze) as usize].1 };
                                let minus_pos = (checker.vir_pos(&record) + rlen as i32 - 1i32 + self.minus_shift) as u32;
                                self.counts[sidx as usize].entry(minus_pos).or_insert((0f64, 0f64)).1 += inc;
                            }
                        } else {
                            if plus_idx == 0 {
                                /* no data */
                            } else {
                                let inc = if self.no_scale { 1f64 } else { scale[plus_idx as usize].0 };
                                self.counts[sidx as usize].entry(checker.vir_pos(&record) as u32).or_insert((0f64, 0f64)).0 += inc;
                            }
                        }
                    }
                }
            }
        }
    }

    pub fn write_bed(&self, filename: &str, stranded: bool) -> Result<(),ioError> {
        // open new file
        let mut f = try!(File::create(filename));

        // write data
        for i in 0..self.chroms.len() {
            let chrom : &str = &self.chroms[i];

            for (pos, value) in self.counts[i].iter() {

                if stranded {
                    if value.0 > 0f64 {
                        try!(write!(f, "{}\t{}\t{}\t.\t{}\t+\n", chrom, pos, pos + 1, value.0));
                    }
                    if value.1 > 0f64 {
                        try!(write!(f, "{}\t{}\t{}\t.\t{}\t-\n", chrom, pos, pos + 1, -value.1));
                    }
                } else {
                    try!(write!(f, "{}\t{}\t{}\t.\t{}\n", chrom, pos, pos + 1, value.0 + value.1));
                }
            }
        }
        Ok(())
    }

    fn bw_stranded_filename(filename: &str, strand: Strand) -> OsString {
        let def_ext : &OsStr = OsStr::new("bw");
        let mut basename: OsString = Path::new(filename).file_stem().unwrap_or(OsStr::new(filename)).to_os_string();
        let extension = Path::new(filename).extension().unwrap_or(def_ext).to_os_string();

        match strand {
            Strand::Plus => basename.push("_plus."),
            Strand::Minus => basename.push("_minus."),
            Strand::Both => unreachable!(),
        }
        basename.push(extension);

        return basename;
    }

    pub fn write_bw(&self, filename: &str, stranded: bool) -> Result<(String
    , Option<String>), ioError> {
        if stranded {
            let output_plus = PileUp::bw_stranded_filename(filename, Strand::Plus);
            let output_minus = PileUp::bw_stranded_filename(filename, Strand::Minus);

	        match write_bigwig(&output_plus, &self.chroms, &self.chrom_sizes, &self.counts, Strand::Plus) {
                Ok(_) => {
                    try!(write_bigwig(&output_minus, &self.chroms, &self.chrom_sizes, &self.counts, Strand::Minus));
                    Ok((output_plus.into_string().unwrap(), Some(output_minus.into_string().unwrap())))
                },
                Err(err) => Err(err),
            }
        } else {
            try!(write_bigwig(OsStr::new(filename), &self.chroms, &self.chrom_sizes, &self.counts, Strand::Both));
            Ok((String::from(filename), None))
        }
    }

    pub fn chrom_index(&self, chrom: &str) -> Option<usize> {
        self.chroms.iter().position(|x| x == chrom)
    }

    pub fn chrom_size(&self, index: usize) -> Option<u32> {
        self.chrom_sizes.get(index).map(|&x| x)
    }

    pub fn get(&self, chrom_index: usize, position: u32) -> Option<&(f64, f64)> {
        if chrom_index >= self.counts.len() { return None; }
        self.counts[chrom_index].get(&position)
    }

    pub fn chrom_iter(&self, index: usize) -> Iter<u32, (f64, f64)> {
        self.counts[index].iter()
    }
}

fn scale_factor(exp: u64, etotal: u64, obs: u64, ototal: u64) -> f64 {
    let fexp = if etotal > 0 { exp as f64 / etotal as f64 } else { 0f64 };
    let fobs = if ototal > 0 { obs as f64 / ototal as f64 } else { 0f64 };
    if fobs > 0f64 { fexp / fobs } else { 0f64 }
}

fn compute_scale_factors(counts: &Vec<(u64, u64, u64, u64)>) -> Vec<(f64, f64)> {
    // compute totals
    // skip first row which contains unmappable/unusable position counts
    let totals = counts.iter().skip(1).fold((0u64, 0u64, 0u64, 0u64),
        |acc, &(sp, sm, bp, bm)| ( acc.0 + sp, acc.1 + sm, acc.2 + bp, acc.3 + bm));

    // compute scale
    // x = Obs * ExpFreq / ObsFreq
    // scale = ExpFreq / ObsFreq
    counts.iter().map(|&(sp, sm, bp, bm)| {
        ( scale_factor(sp, totals.0, bp, totals.2),
          scale_factor(sm, totals.1, bm, totals.3)
        )
    }).collect()
}

pub fn scale(seqfile: &str, counts: Vec<(u64, u64, u64, u64)>, bamfiles: &Vec<String>, minqual: u8, shift: bool, no_scale: bool, pair_range: &Option<(i32, i32)>, paired: bool, exact_length: bool, tail_edge: bool) -> PileUp {
    // read
    let file = match File::open(seqfile) {
        Ok(value) => value,
        Err(err) => {
            println!("Error: Failed to open sequence table file '{}': {}", seqfile, err.description());
            exit(1);
        },
    };
    let mut table = match SeqTable::open(file) {
        Ok(value) => value,
        Err(e) => {
            println!("Error:tabulate: {}", e.to_string());
            exit(1);
        },
    };

    let seqinfos = table.sequences();
    let rlen = table.params.read_length as usize;
    let minus_shift = if shift {
        let res = (table.params.plus_offset as i16 - (table.params.kmer_length as i16 - table.params.minus_offset as i16 - 1i16)) as i32;
        println!("# minus strand shift = {} bp", res);
        res
    } else {
        0i32
    };

    let mut pileup = PileUp::new(&seqinfos, minus_shift, no_scale);

    for bamfile in bamfiles {
        println!("# scale {}", &bamfile);
        let bam = match bam::Reader::from_path(&Path::new(bamfile)) {
            Ok(value) => value,
            Err(err) => {
                println!("Error: Failed to open BAM file '{}': {}", bamfile, err.description());
                exit(1);
            },
        };
        let names = bam.header().target_names();
        let mut cur_tid = 0;

        // map BAM tid's to SeqTable idx's
        let map : Vec<usize> = names.iter().map(|&id| {
            let chrom = String::from_utf8_lossy(id);
            for i in 0..seqinfos.len() {
                if seqinfos[i].name.eq(&chrom) {
                    return i;
                }
            }
            println!("Error: Unknown sequence name in BAM: {}", chrom);
            exit(1);
        }
        ).collect();

        // reads
        let mut iter = bam.records().peekable();
        let scale = compute_scale_factors(&counts);

        if pair_range.is_some() || paired {
            let checker = match *pair_range {
                Some((min, max)) => PairedChecker {
                    tail_edge: tail_edge,
                    exact_length: exact_length,
                    read_length: rlen,
                    min_quality: minqual,
                    min_dist: min,
                    max_dist: max,
                    force_paired: paired,
                    max_distance: true,
                },
                None => PairedChecker {
                    tail_edge: tail_edge,
                    exact_length: exact_length,
                    read_length: rlen,
                    min_quality: minqual,
                    min_dist: 0,
                    max_dist: 0,
                    force_paired: paired,
                    max_distance: false,
                },
            };
            while pileup.add_data(&mut table, &mut iter, &mut cur_tid, &map, &scale, &checker) {}
        } else {
            let checker = SingleChecker { tail_edge: tail_edge, exact_length: exact_length, read_length: rlen, min_quality: minqual };
            while pileup.add_data(&mut table, &mut iter, &mut cur_tid, &map, &scale, &checker) {}
        }
    }

    pileup
}
<|endoftext|>


<commit_before>extern crate rusql;
#[cfg(not(feature = "no_readline"))]
extern crate readline;

#[cfg(not(feature = "no_readline"))]
use readline::readline;
use rusql::{rusql_exec, Rusql};

#[cfg(feature = "no_readline")]
use std::io;

#[cfg(feature = "no_readline")]
fn readline(prompt: &str) -> Option<String> {
    print!("{}", prompt);

    io::stdin().read_line().ok()
}

pub fn main() {
    let mut db = Rusql::new();
    loop {
        let input = readline("rusql> ").expect("Error reading line");

        match input.as_slice() {
            ".make_foo" => {
                rusql_exec(&mut db, "CREATE TABLE Foo(Id INTEGER, Name TEXT);
                                     INSERT INTO Foo VALUES
                                            (1, \"Foo1\"), (2, \"Foo2\"), (3, \"Foo3\");",
                           |_, _| ());
            }
            _ => {
                if let Some(results) = rusql_exec(&mut db, input.as_slice(), |_, _| {}) {
                    print!("{}", results);
                }
            }
        }
    }
}
<commit_msg>Implements continuation prompt for shell<commit_after>extern crate rusql;
#[cfg(not(feature = "no_readline"))]
extern crate readline;

#[cfg(not(feature = "no_readline"))]
use readline::readline;
use rusql::{rusql_exec, Rusql};

#[cfg(feature = "no_readline")]
use std::io;

#[cfg(feature = "no_readline")]
fn readline(prompt: &str) -> Option<String> {
    print!("{}", prompt);

    io::stdin().read_line().ok()
}

pub fn main() {
    let mut db = Rusql::new();
    loop {
        let mut input = readline("rusql> ").expect("Error reading line");

        while !input.as_slice().trim_right().ends_with(";")
                && !input.as_slice().trim_left().starts_with(".") {

            let continuation = readline("  ...> ").expect("Error reading line");

            input.push(' ');
            input.push_str(continuation.as_slice());
        }

        match input.as_slice() {
            ".make_foo" => {
                rusql_exec(&mut db, "CREATE TABLE Foo(Id INTEGER, Name TEXT);
                                     INSERT INTO Foo VALUES
                                            (1, \"Foo1\"), (2, \"Foo2\"), (3, \"Foo3\");",
                           |_, _| ());
            }
            _ => {
                if let Some(results) = rusql_exec(&mut db, input.as_slice(), |_, _| {}) {
                    print!("{}", results);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::str;
use std::time::Duration;

use zookeeper::{Acl, CreateMode, Watcher, WatchedEvent, ZkError, ZooKeeper};
use zookeeper::perms;

struct MyWatcher;

impl Watcher for MyWatcher {
    fn handle(&self, _e: &WatchedEvent) {
        // println!("{:?}", e)
    }
}

pub struct Shell {
    hosts: String,
    zk: Option<ZooKeeper>,
    session_timeout: u64,
    default_acl: Vec<Acl>,
}

// are we connected?
macro_rules! fetch_zk {
    ($e:expr) => (
        match $e {
            Some(ref __zk) => __zk,
            _ => {
                println!("Not connected.");
                return;
            }
        })
}

macro_rules! check_args {
    ($args:ident, $count:expr, $params:expr) => (
        if $args.len() != $count {
            println!("Wrong number of arguments, expected parameters: {}", $params);
            return;
        })
}

fn report_error(error: ZkError, path: &str) {
    match error {
        ZkError::NoNode => println!("Path {} does not exist.", path),
        unknown => println!("Unknown error: {:?}", unknown),
    }
}

impl Shell {
    pub fn new(hosts: &str) -> Shell {
        let world_all = Acl {
            perms: perms::ALL,
            scheme: "world".to_string(),
            id: "anyone".to_string()
        };

        Shell {
            hosts: hosts.to_string(),
            zk: None,
            session_timeout: 5,
            default_acl: vec![world_all],
        }
    }

    pub fn run(&mut self) {
        if !self.hosts.is_empty() {
            println!("Connecting...");
            let zk = ZooKeeper::connect(
                &self.hosts,
                Duration::from_secs(self.session_timeout),
                MyWatcher).unwrap();
            self.zk = Some(zk);
        }

        loop {
            let mut line = String::new();

            print!("> ");
            let _ = stdout().flush();

            stdin()
                .read_line(&mut line)
                .ok()
                .expect("Failed to read line");

            let pieces: Vec<&str>  = line.trim().split_whitespace().collect();

            if pieces.len() == 0 {
                continue;
            }

            // dispatch the command
            let args = pieces[1..].to_vec();
            match pieces[0] {
                "get" => self.get(args),
                "set" => self.set(args),
                "ls" => self.ls(args),
                "create" => self.create(args),
                unknown => println!("Unknown command: {}", unknown)
            }
        }

    }

    fn get(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_data(path, false);

        match ret {
            Ok(data_stat) =>  {
                let (bytes, _) = data_stat;
                let datastr = str::from_utf8(&bytes[..]).unwrap().to_string();
                println!("{}", datastr);
            },
            Err(err) => report_error(err, path),
        }
    }

    fn set(&mut self, args: Vec<&str>) {
        check_args!(args, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();
        let ret = zk.set_data(path, data, -1);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn ls(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_children(path, false);

        match ret {
            Ok(children) => println!("{}", children.join(" ")),
            Err(err) => report_error(err, path),
        }
    }

    fn create(&mut self, args: Vec<&str>) {
        check_args!(args, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();

        // FIXME: ACLs are not copyable so we can't use default_acl
        let world_all = Acl {
            perms: perms::ALL,
            scheme: "world".to_string(),
            id: "anyone".to_string()
        };

        let ret = zk.create(path, data, vec![world_all], CreateMode::Persistent);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }
}
<commit_msg>feature(shell): implement `rm`<commit_after>use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::str;
use std::time::Duration;

use zookeeper::{Acl, CreateMode, Watcher, WatchedEvent, ZkError, ZooKeeper};
use zookeeper::perms;

struct MyWatcher;

impl Watcher for MyWatcher {
    fn handle(&self, _e: &WatchedEvent) {
        // println!("{:?}", e)
    }
}

pub struct Shell {
    hosts: String,
    zk: Option<ZooKeeper>,
    session_timeout: u64,
    default_acl: Vec<Acl>,
}

// are we connected?
macro_rules! fetch_zk {
    ($e:expr) => (
        match $e {
            Some(ref __zk) => __zk,
            _ => {
                println!("Not connected.");
                return;
            }
        })
}

macro_rules! check_args {
    ($args:ident, $count:expr, $params:expr) => (
        if $args.len() != $count {
            println!("Wrong number of arguments, expected parameters: {}", $params);
            return;
        })
}

fn report_error(error: ZkError, path: &str) {
    match error {
        ZkError::NoNode => println!("Path {} does not exist.", path),
        ZkError::NotEmpty => println!("Path {} is not empty.", path),
        unknown => println!("Unknown error: {:?}", unknown),
    }
}

impl Shell {
    pub fn new(hosts: &str) -> Shell {
        let world_all = Acl {
            perms: perms::ALL,
            scheme: "world".to_string(),
            id: "anyone".to_string()
        };

        Shell {
            hosts: hosts.to_string(),
            zk: None,
            session_timeout: 5,
            default_acl: vec![world_all],
        }
    }

    pub fn run(&mut self) {
        if !self.hosts.is_empty() {
            println!("Connecting...");
            let zk = ZooKeeper::connect(
                &self.hosts,
                Duration::from_secs(self.session_timeout),
                MyWatcher).unwrap();
            self.zk = Some(zk);
        }

        loop {
            let mut line = String::new();

            print!("> ");
            let _ = stdout().flush();

            stdin()
                .read_line(&mut line)
                .ok()
                .expect("Failed to read line");

            let pieces: Vec<&str>  = line.trim().split_whitespace().collect();

            if pieces.len() == 0 {
                continue;
            }

            // dispatch the command
            let args = pieces[1..].to_vec();
            match pieces[0] {
                "get" => self.get(args),
                "set" => self.set(args),
                "ls" => self.ls(args),
                "create" => self.create(args),
                "rm" => self.rm(args),
                unknown => println!("Unknown command: {}", unknown)
            }
        }

    }

    fn get(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_data(path, false);

        match ret {
            Ok(data_stat) =>  {
                let (bytes, _) = data_stat;
                let datastr = str::from_utf8(&bytes[..]).unwrap().to_string();
                println!("{}", datastr);
            },
            Err(err) => report_error(err, path),
        }
    }

    fn set(&mut self, args: Vec<&str>) {
        check_args!(args, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();
        let ret = zk.set_data(path, data, -1);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn ls(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_children(path, false);

        match ret {
            Ok(children) => println!("{}", children.join(" ")),
            Err(err) => report_error(err, path),
        }
    }

    fn create(&mut self, args: Vec<&str>) {
        check_args!(args, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();

        // FIXME: ACLs are not copyable so we can't use default_acl
        let world_all = Acl {
            perms: perms::ALL,
            scheme: "world".to_string(),
            id: "anyone".to_string()
        };

        let ret = zk.create(path, data, vec![world_all], CreateMode::Persistent);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn rm(&mut self, args: Vec<&str>) {
        check_args!(args, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.delete(path, -1);

        match ret {
            Ok(()) =>  (),
            Err(err) => report_error(err, path),
        }

    }
}
<|endoftext|>


<commit_before>extern crate pink_spider;
use pink_spider::spotify;
use pink_spider::apple_music;
use pink_spider::apple_music::country;
use pink_spider::model::{Model, Album, Provider};
use pink_spider::model::State;

pub fn main() {
    let mut albums = Album::find_all();
    println!("len {}\n", albums.len());
    for mut album in albums.iter_mut().filter(|a| a.state == State::Alive) {
        let album = match album.provider {
            Provider::Spotify => match spotify::fetch_album(&album.identifier) {
                Ok(sp_album) => album.update_with_sp_album(&sp_album),
                Err(_)       => album.disable(),
            },
            Provider::AppleMusic => match apple_music::fetch_album(&country(&album.url),
                                                                   &album.identifier) {
                Ok(am_album) => album.update_with_am_album(&am_album),
                Err(_)       => album.disable(),
            },
            _ => &mut album,
        };
        match album.save() {
            Ok(_) => {
                print!("[{:?}] album id: {} {} {} {} {} is updated\n",
                       album.state,
                       album.id, album.provider, album.identifier,
                       country(&album.url),
                       album.title);
            },
            Err(e) => {
                print!("Failed to update album id: {} {} {} {} {}\n",
                       album.id, album.provider,
                       country(&album.url),
                       album.title, album.identifier);
                print!("{}\n", e);
            },
        }
    }
}
<commit_msg>`update_albums` showes error<commit_after>extern crate pink_spider;
use pink_spider::spotify;
use pink_spider::apple_music;
use pink_spider::apple_music::country;
use pink_spider::model::{Model, Album, Provider};
use pink_spider::model::State;

pub fn main() {
    let mut albums = Album::find_all();
    println!("len {}\n", albums.len());
    for mut album in albums.iter_mut().filter(|a| a.state == State::Alive) {
        let album = match album.provider {
            Provider::Spotify => match spotify::fetch_album(&album.identifier) {
                Ok(sp_album) => album.update_with_sp_album(&sp_album),
                Err(e)       => {
                    print!("{}\n", e);
                    album.disable()
                },
            },
            Provider::AppleMusic => match apple_music::fetch_album(&country(&album.url),
                                                                   &album.identifier) {
                Ok(am_album) => album.update_with_am_album(&am_album),
                Err(e)       => {
                    print!("{}\n", e);
                    album.disable()
                },
            },
            _ => &mut album,
        };
        match album.save() {
            Ok(_) => {
                print!("[{:?}] album id: {} {} {} {} {} is updated\n",
                       album.state,
                       album.id, album.provider, album.identifier,
                       country(&album.url),
                       album.title);
            },
            Err(e) => {
                print!("Failed to update album id: {} {} {} {} {}\n",
                       album.id, album.provider,
                       country(&album.url),
                       album.title, album.identifier);
                print!("{}\n", e);
            },
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name = "tr"]
#![feature(macro_rules)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate collections;
extern crate getopts;

use collections::bitv_set::BitvSet;
use collections::vec_map::VecMap;
use getopts::OptGroup;
use std::char::from_u32;
use std::io::print;
use std::io::stdio::{stdin,stdout};
use std::iter::FromIterator;
use std::vec::Vec;

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

static NAME : &'static str = "tr";
static VERSION : &'static str = "1.0.0";

fn unescape_char(c: char) -> char {
    match c {
        'a' => 0x07u8 as char,
        'b' => 0x08u8 as char,
        'f' => 0x0cu8 as char,
        'v' => 0x0bu8 as char,
        'n' => '\n',
        'r' => '\r',
        't' => '\t',
        _ => c,
    }
}

fn unescape(v: Vec<char>) -> Vec<char> {
    let mut out = Vec::new();
    let mut input = v.as_slice();
    loop {
        input = match input {
            ['\\', e, rest..] => {
                out.push(unescape_char(e));
                rest
            }
            [c, rest..] => {
                out.push(c);
                rest
            }
            [] => break
        }
    }
    out
}

fn expand_range(from: char, to: char) -> Vec<char> {
    range(from as u32, to as u32 + 1).map(|c| from_u32(c).unwrap()).collect()
}

fn expand_set(s: &str) -> Vec<char> {
    let mut set = Vec::<char>::new();
    let unesc = unescape(FromIterator::from_iter(s.chars()));
    let mut input = unesc.as_slice();

    loop {
        input = match input {
            [f, '-', t, rest..] => {
                set.push_all(expand_range(f, t).as_slice());
                rest
            }
            [c, rest..] => {
                set.push(c);
                rest
            }
            [] => break
        };
    }
    set
}

fn delete(set: Vec<char>, complement: bool) {
    let mut bset = BitvSet::new();
    let mut out = stdout();

    for &c in set.iter() {
        bset.insert(c as uint);
    }

    let is_allowed = if complement {
        |c: char| bset.contains(&(c as uint))
    } else {
        |c: char| !bset.contains(&(c as uint))
    };

    for c in stdin().chars() {
        match c {
            Ok(c) if is_allowed(c) => out.write_char(c).unwrap(),
            Ok(_) => (),
            Err(err) => panic!("{}", err),
        };
    }
}

fn tr(set1: &[char], set2: &[char]) {
    let mut map = VecMap::<char>::new();
    let mut out = stdout();

    for i in range(0, set1.len()) {
        if i >= set2.len() {
            map.insert(set1[i] as uint, set2[set2.len()-1]);
        } else {
            map.insert(set1[i] as uint, set2[i]);
        }
    }

    for c in stdin().chars() {
        match c {
            Ok(inc) => {
                let trc = match map.get(&(inc as uint)) {
                    Some(t) => *t,
                    None => inc,
                };
                out.write_char(trc).unwrap();
            }
            Err(err) => {
                panic!("{}", err);
            }
        }
    }
}

fn usage(opts: &[OptGroup]) {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTIONS] SET1 [SET2]", NAME);
        println!("");
        print(getopts::usage("Translate or delete characters.", opts).as_slice());
}

pub fn uumain(args: Vec<String>) -> int {
    let opts = [
        getopts::optflag("c", "complement", "use the complement of SET1"),
        getopts::optflag("C", "", "same as -c"),
        getopts::optflag("d", "delete", "delete characters in SET1"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(err) => {
            show_error!("{}", err);
            return 1;
        }
    };

    if matches.opt_present("help") {
        usage(&opts);
        return 0;
    }

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }

    if matches.free.len() == 0 {
        usage(&opts);
        return 1;
    }

    let dflag = matches.opt_present("d");
    let cflag = matches.opts_present(&["c".to_string(), "C".to_string()]);
    let sets = matches.free;

    if cflag && !dflag {
        show_error!("-c is only supported with -d");
        return 1;
    }

    if dflag {
        let set1 = expand_set(sets[0].as_slice());
        delete(set1, cflag);
    } else {
        let set1 = expand_set(sets[0].as_slice());
        let set2 = expand_set(sets[1].as_slice());
        tr(set1.as_slice(), set2.as_slice());
    }

    0
}
<commit_msg>tr: improve speed slightly<commit_after>#![crate_name = "tr"]
#![feature(macro_rules)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate collections;
extern crate getopts;

use getopts::OptGroup;
use std::char::from_u32;
use std::collections::{BitvSet, VecMap};
use std::io::print;
use std::io::stdio::{stdin,stdout};
use std::iter::FromIterator;
use std::vec::Vec;

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

static NAME : &'static str = "tr";
static VERSION : &'static str = "1.0.0";

#[inline]
fn unescape_char(c: char) -> char {
    match c {
        'a' => 0x07u8 as char,
        'b' => 0x08u8 as char,
        'f' => 0x0cu8 as char,
        'v' => 0x0bu8 as char,
        'n' => '\n',
        'r' => '\r',
        't' => '\t',
        _ => c,
    }
}

#[inline]
fn unescape(v: Vec<char>) -> Vec<char> {
    let mut out = Vec::new();
    let mut input = v.as_slice();
    loop {
        input = match input {
            ['\\', e, rest..] => {
                out.push(unescape_char(e));
                rest
            }
            [c, rest..] => {
                out.push(c);
                rest
            }
            [] => break
        }
    }
    out
}

#[inline]
fn expand_range(from: char, to: char) -> Vec<char> {
    range(from as u32, to as u32 + 1).map(|c| from_u32(c).unwrap()).collect()
}

fn expand_set(s: &str) -> Vec<char> {
    let mut set = Vec::<char>::new();
    let unesc = unescape(FromIterator::from_iter(s.chars()));
    let mut input = unesc.as_slice();

    loop {
        input = match input {
            [f, '-', t, rest..] => {
                set.push_all(expand_range(f, t).as_slice());
                rest
            }
            [c, rest..] => {
                set.push(c);
                rest
            }
            [] => break
        };
    }
    set
}

fn delete(set: Vec<char>, complement: bool) {
    let mut bset = BitvSet::new();
    let mut out = stdout();

    for &c in set.iter() {
        bset.insert(c as uint);
    }

    let is_allowed = if complement {
        |c: char| bset.contains(&(c as uint))
    } else {
        |c: char| !bset.contains(&(c as uint))
    };

    for c in stdin().chars() {
        match c {
            Ok(c) if is_allowed(c) => out.write_char(c).unwrap(),
            Ok(_) => (),
            Err(err) => panic!("{}", err),
        };
    }
}

fn tr(set1: &[char], set2: &[char]) {
    const BUFFER_LEN: uint = 1024;

    let mut map = VecMap::new();
    let mut stdout = stdout();
    let mut outbuffer = String::with_capacity(BUFFER_LEN);

    let set2_len = set2.len();
    for i in range(0, set1.len()) {
        if i >= set2_len {
            map.insert(set1[i] as uint, set2[set2_len - 1]);
        } else {
            map.insert(set1[i] as uint, set2[i]);
        }
    }

    for c in stdin().chars() {
        match c {
            Ok(inc) => {
                let trc = match map.get(&(inc as uint)) {
                    Some(t) => *t,
                    None => inc,
                };
                outbuffer.push(trc);
                if outbuffer.len() >= BUFFER_LEN {
                    stdout.write_str(outbuffer.as_slice()).unwrap();
                    outbuffer.clear();
                }
            }
            Err(err) => {
                panic!("{}", err);
            }
        }
    }
    if outbuffer.len() > 0 {
        stdout.write_str(outbuffer.as_slice()).unwrap();
    }
}

fn usage(opts: &[OptGroup]) {
    println!("{} {}", NAME, VERSION);
    println!("");
    println!("Usage:");
    println!("  {} [OPTIONS] SET1 [SET2]", NAME);
    println!("");
    print(getopts::usage("Translate or delete characters.", opts).as_slice());
}

pub fn uumain(args: Vec<String>) -> int {
    let opts = [
        getopts::optflag("c", "complement", "use the complement of SET1"),
        getopts::optflag("C", "", "same as -c"),
        getopts::optflag("d", "delete", "delete characters in SET1"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(err) => {
            show_error!("{}", err);
            return 1;
        }
    };

    if matches.opt_present("help") {
        usage(&opts);
        return 0;
    }

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }

    if matches.free.len() == 0 {
        usage(&opts);
        return 1;
    }

    let dflag = matches.opt_present("d");
    let cflag = matches.opts_present(&["c".to_string(), "C".to_string()]);
    let sets = matches.free;

    if cflag && !dflag {
        show_error!("-c is only supported with -d");
        return 1;
    }

    if dflag {
        let set1 = expand_set(sets[0].as_slice());
        delete(set1, cflag);
    } else {
        let set1 = expand_set(sets[0].as_slice());
        let set2 = expand_set(sets[1].as_slice());
        tr(set1.as_slice(), set2.as_slice());
    }

    0
}
<|endoftext|>


<commit_before>use std::fmt;
use std::error;
use gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

#[derive(Clone, Copy)]
pub struct Viewport {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32
}

impl Viewport {
    pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
        Viewport {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}

gl_enum! {
    pub gl_enum Capability {
        Blend as BLEND
            = gl::BLEND,
        CullFace as CULL_FACE
            = gl::CULL_FACE,
        DepthTest as DEPTH_TEST
            = gl::DEPTH_TEST,
        Dither as DITHER
            = gl::DITHER,
        PolygonOffsetFill as POLYGON_OFFSET_FILL
            = gl::POLYGON_OFFSET_FILL,
        SampleAlphaToCoverage as SAMPLE_ALPHA_TO_COVERAGE =
            gl::SAMPLE_ALPHA_TO_COVERAGE,
        SampleCoverage as SAMPLE_COVERAGE =
            gl::SAMPLE_COVERAGE,
        ScisscorTest as SCISSCOR_TEST =
            gl::SCISSOR_TEST,
        StencilTest as STENCIL_TEST =
            gl::STENCIL_TEST
    }
}

#[derive(Debug)]
pub enum GLError {
    InvalidEnum,
    InvalidValue,
    InvalidOperation,
    InvalidFramebufferOperation,
    OutOfMemory,
    FramebufferError(GLFramebufferError),
    Message(String)
}

impl fmt::Display for GLError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GLError::InvalidEnum => {
                write!(f, "Invalid enum")
            },
            GLError::InvalidValue => {
                write!(f, "Invalid value")
            },
            GLError::InvalidOperation => {
                write!(f, "Invalid operation")
            },
            GLError::InvalidFramebufferOperation => {
                write!(f, "Invalid framebuffer operation")
            },
            GLError::OutOfMemory => {
                write!(f, "Out of memory")
            },
            GLError::FramebufferError(ref e) => {
                write!(f, "{:?}", e)
            },
            GLError::Message(ref s) => {
                write!(f, "{}", s)
            }
        }
    }
}

impl error::Error for GLError {
    fn description(&self) -> &str {
        match *self {
            GLError::InvalidEnum => "Invalid enum variant in OpenGL call.",
            GLError::InvalidValue => "Out-of-range value in OpenGL call.",
            GLError::InvalidOperation => "The specified OpenGL operation is not allowed in the current state.",
            GLError::InvalidFramebufferOperation => "OpenGL command tried to read or write to an incomplete framebuffer.",
            GLError::OutOfMemory => "There is not enough memory left to execute the specified OpenGL command.",
            GLError::FramebufferError(ref e) => {
                error::Error::description(e)
            },
            GLError::Message(ref s) => &s
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            GLError::FramebufferError(ref e) => { Some(e) },
            _ => { None }
        }
    }
}

#[derive(Debug)]
pub enum GLFramebufferError {
    IncompleteAttachment,
    IncompleteDimensions,
    IncompleteMissingAttachment,
    Unsupported
}

impl fmt::Display for GLFramebufferError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GLFramebufferError::IncompleteAttachment => {
                write!(f, "Incomplete attachment")
            },
            GLFramebufferError::IncompleteDimensions => {
                write!(f, "Incomplete dimensions")
            },
            GLFramebufferError::IncompleteMissingAttachment => {
                write!(f, "Missing attachments")
            },
            GLFramebufferError::Unsupported => {
                write!(f, "Unsupported")
            }
        }
    }
}

impl error::Error for GLFramebufferError {
    fn description(&self) -> &str {
        match *self {
            GLFramebufferError::IncompleteAttachment => "One or more framebuffer attachments are not complete",
            GLFramebufferError::IncompleteDimensions => "Not all images attached to the framebuffer have the same width and height",
            GLFramebufferError::IncompleteMissingAttachment => "The framebuffer has no images attached",
            GLFramebufferError::Unsupported => "The framebuffer contains an unsupported combination of attachments",
        }
    }
}

impl From<GLFramebufferError> for GLError {
    fn from(e: GLFramebufferError) -> GLError {
        GLError::FramebufferError(e)
    }
}

gl_enum! {
    pub gl_enum DrawingMode {
        Points as POINTS = gl::POINTS,
        LineStrip as LINE_STRIP = gl::LINE_STRIP,
        LineLoop as LINE_LOOP = gl::LINE_LOOP,
        Lines as LINES = gl::LINES,
        TriangleStrip as TRIANGLE_STRIP = gl::TRIANGLE_STRIP,
        TriangleFan as TRIANGLE_FAN = gl::TRIANGLE_FAN,
        Triangles as TRIANGLES = gl::TRIANGLES
    }
}

gl_enum! {
    pub gl_enum DataType {
        Byte as BYTE = gl::BYTE,
        UnsignedByte as UNSIGNED_BYTE = gl::UNSIGNED_BYTE,
        Short as SHORT = gl::SHORT,
        UnsignedShort as UNSIGNED_SHORT = gl::UNSIGNED_SHORT,
        Fixed as FIXED = gl::FIXED,
        Float as FLOAT = gl::FLOAT
    }
}
<commit_msg>Add `GLObject` trait<commit_after>use std::mem;
use std::fmt;
use std::error;
use gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

#[derive(Clone, Copy)]
pub struct Viewport {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32
}

impl Viewport {
    pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
        Viewport {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

pub trait GLObject {
    type Id;

    unsafe fn from_raw(id: Self::Id) -> Self;

    fn id(&self) -> Self::Id;

    fn into_raw(self) -> Self::Id
        where Self: Sized
    {
        let id = self.id();
        mem::forget(self);
        id
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}

gl_enum! {
    pub gl_enum Capability {
        Blend as BLEND
            = gl::BLEND,
        CullFace as CULL_FACE
            = gl::CULL_FACE,
        DepthTest as DEPTH_TEST
            = gl::DEPTH_TEST,
        Dither as DITHER
            = gl::DITHER,
        PolygonOffsetFill as POLYGON_OFFSET_FILL
            = gl::POLYGON_OFFSET_FILL,
        SampleAlphaToCoverage as SAMPLE_ALPHA_TO_COVERAGE =
            gl::SAMPLE_ALPHA_TO_COVERAGE,
        SampleCoverage as SAMPLE_COVERAGE =
            gl::SAMPLE_COVERAGE,
        ScisscorTest as SCISSCOR_TEST =
            gl::SCISSOR_TEST,
        StencilTest as STENCIL_TEST =
            gl::STENCIL_TEST
    }
}

#[derive(Debug)]
pub enum GLError {
    InvalidEnum,
    InvalidValue,
    InvalidOperation,
    InvalidFramebufferOperation,
    OutOfMemory,
    FramebufferError(GLFramebufferError),
    Message(String)
}

impl fmt::Display for GLError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GLError::InvalidEnum => {
                write!(f, "Invalid enum")
            },
            GLError::InvalidValue => {
                write!(f, "Invalid value")
            },
            GLError::InvalidOperation => {
                write!(f, "Invalid operation")
            },
            GLError::InvalidFramebufferOperation => {
                write!(f, "Invalid framebuffer operation")
            },
            GLError::OutOfMemory => {
                write!(f, "Out of memory")
            },
            GLError::FramebufferError(ref e) => {
                write!(f, "{:?}", e)
            },
            GLError::Message(ref s) => {
                write!(f, "{}", s)
            }
        }
    }
}

impl error::Error for GLError {
    fn description(&self) -> &str {
        match *self {
            GLError::InvalidEnum => "Invalid enum variant in OpenGL call.",
            GLError::InvalidValue => "Out-of-range value in OpenGL call.",
            GLError::InvalidOperation => "The specified OpenGL operation is not allowed in the current state.",
            GLError::InvalidFramebufferOperation => "OpenGL command tried to read or write to an incomplete framebuffer.",
            GLError::OutOfMemory => "There is not enough memory left to execute the specified OpenGL command.",
            GLError::FramebufferError(ref e) => {
                error::Error::description(e)
            },
            GLError::Message(ref s) => &s
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            GLError::FramebufferError(ref e) => { Some(e) },
            _ => { None }
        }
    }
}

#[derive(Debug)]
pub enum GLFramebufferError {
    IncompleteAttachment,
    IncompleteDimensions,
    IncompleteMissingAttachment,
    Unsupported
}

impl fmt::Display for GLFramebufferError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GLFramebufferError::IncompleteAttachment => {
                write!(f, "Incomplete attachment")
            },
            GLFramebufferError::IncompleteDimensions => {
                write!(f, "Incomplete dimensions")
            },
            GLFramebufferError::IncompleteMissingAttachment => {
                write!(f, "Missing attachments")
            },
            GLFramebufferError::Unsupported => {
                write!(f, "Unsupported")
            }
        }
    }
}

impl error::Error for GLFramebufferError {
    fn description(&self) -> &str {
        match *self {
            GLFramebufferError::IncompleteAttachment => "One or more framebuffer attachments are not complete",
            GLFramebufferError::IncompleteDimensions => "Not all images attached to the framebuffer have the same width and height",
            GLFramebufferError::IncompleteMissingAttachment => "The framebuffer has no images attached",
            GLFramebufferError::Unsupported => "The framebuffer contains an unsupported combination of attachments",
        }
    }
}

impl From<GLFramebufferError> for GLError {
    fn from(e: GLFramebufferError) -> GLError {
        GLError::FramebufferError(e)
    }
}

gl_enum! {
    pub gl_enum DrawingMode {
        Points as POINTS = gl::POINTS,
        LineStrip as LINE_STRIP = gl::LINE_STRIP,
        LineLoop as LINE_LOOP = gl::LINE_LOOP,
        Lines as LINES = gl::LINES,
        TriangleStrip as TRIANGLE_STRIP = gl::TRIANGLE_STRIP,
        TriangleFan as TRIANGLE_FAN = gl::TRIANGLE_FAN,
        Triangles as TRIANGLES = gl::TRIANGLES
    }
}

gl_enum! {
    pub gl_enum DataType {
        Byte as BYTE = gl::BYTE,
        UnsignedByte as UNSIGNED_BYTE = gl::UNSIGNED_BYTE,
        Short as SHORT = gl::SHORT,
        UnsignedShort as UNSIGNED_SHORT = gl::UNSIGNED_SHORT,
        Fixed as FIXED = gl::FIXED,
        Float as FLOAT = gl::FLOAT
    }
}
<|endoftext|>


<commit_before>/*!
 * Reexports of types from encoding-types crate.
 */

pub use encoding_types::{CodecError, DecoderTrap, EncoderTrap, ByteWriter, Encoding, RawDecoder,
                         RawEncoder, StringWriter, EncodingRef, EncoderTrapFunc, DecoderTrapFunc};
pub use super::decode;

#[cfg(test)]
mod tests {
    use super::*;
    use super::EncoderTrap::NcrEscape;
    use util::StrCharIndex;
    use std::convert::Into;

    // a contrived encoding example: same as ASCII, but inserts `prepend` between each character
    // within two "e"s (so that `widespread` becomes `wide*s*p*r*ead` and `eeeeasel` becomes
    // `e*ee*ease*l` where `*` is substituted by `prepend`) and prohibits `prohibit` character.
    struct MyEncoder { flag: bool, prohibit: char, prepend: &'static str, toggle: bool }
    impl RawEncoder for MyEncoder {
        fn from_self(&self) -> Box<RawEncoder> {
            Box::new(MyEncoder { flag: self.flag,
                                 prohibit: self.prohibit,
                                 prepend: self.prepend,
                                 toggle: false })
        }
        fn is_ascii_compatible(&self) -> bool { self.flag }
        fn raw_feed(&mut self, input: &str,
                    output: &mut ByteWriter) -> (usize, Option<CodecError>) {
            for ((i,j), ch) in input.index_iter() {
                if ch <= '\u{7f}' && ch != self.prohibit {
                    if self.toggle && !self.prepend.is_empty() {
                        output.write_bytes(self.prepend.as_bytes());
                    }
                    output.write_byte(ch as u8);
                    if ch == 'e' {
                        self.toggle = !self.toggle;
                    }
                } else {
                    return (i, Some(CodecError { upto: j as isize,
                                                 cause: "!!!".into() }));
                }
            }
            (input.len(), None)
        }
        fn raw_finish(&mut self, _output: &mut ByteWriter) -> Option<CodecError> { None }
    }

    struct MyEncoding { flag: bool, prohibit: char, prepend: &'static str }
    impl Encoding for MyEncoding {
        fn name(&self) -> &'static str { "my encoding" }
        fn raw_encoder(&self) -> Box<RawEncoder> {
            Box::new(MyEncoder { flag: self.flag,
                                 prohibit: self.prohibit,
                                 prepend: self.prepend,
                                 toggle: false })
        }
        fn raw_decoder(&self) -> Box<RawDecoder> { panic!("not supported") }
    }

    #[test]
    fn test_encoding_debug_format() {
        let enc = MyEncoding {
            flag: true,
            prohibit: '\u{80}',
            prepend: "",
        };

        assert_eq!(format!("{:?}", &enc as &Encoding), "Encoding(my encoding)");
    }

    #[test]
    fn test_reencoding_trap_with_ascii_compatible_encoding() {
        static COMPAT: &'static MyEncoding =
            &MyEncoding { flag: true, prohibit: '\u{80}', prepend: "" };
        static INCOMPAT: &'static MyEncoding =
            &MyEncoding { flag: false, prohibit: '\u{80}', prepend: "" };

        assert_eq!(COMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"Hello‽ I'm fine.".to_vec()));
        assert_eq!(INCOMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"Hello‽ I'm fine.".to_vec()));
    }

    #[test]
    fn test_reencoding_trap_with_ascii_incompatible_encoding() {
        static COMPAT: &'static MyEncoding =
            &MyEncoding { flag: true, prohibit: '\u{80}', prepend: "*" };
        static INCOMPAT: &'static MyEncoding =
            &MyEncoding { flag: false, prohibit: '\u{80}', prepend: "*" };

        // this should behave incorrectly as the encoding broke the assumption.
        assert_eq!(COMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"He*l*l*o‽* *I*'*m* *f*i*n*e.".to_vec()));
        assert_eq!(INCOMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"He*l*l*o*&*#*8*2*5*3*;* *I*'*m* *f*i*n*e.".to_vec()));
    }

    #[test]
    #[should_panic]
    fn test_reencoding_trap_can_fail() {
        static FAIL: &'static MyEncoding = &MyEncoding { flag: false, prohibit: '&', prepend: "" };

        // this should fail as this contrived encoding does not support `&` at all
        let _ = FAIL.encode("Hello\u{203d} I'm fine.", NcrEscape);
    }
}
<commit_msg>Add a Send test for RawEncoder<commit_after>/*!
 * Reexports of types from encoding-types crate.
 */

pub use encoding_types::{CodecError, DecoderTrap, EncoderTrap, ByteWriter, Encoding, RawDecoder,
                         RawEncoder, StringWriter, EncodingRef, EncoderTrapFunc, DecoderTrapFunc};
pub use super::decode;

#[cfg(test)]
mod tests {
    use super::*;
    use super::EncoderTrap::NcrEscape;
    use util::StrCharIndex;
    use std::convert::Into;
    use std::sync::mpsc::channel;

    // a contrived encoding example: same as ASCII, but inserts `prepend` between each character
    // within two "e"s (so that `widespread` becomes `wide*s*p*r*ead` and `eeeeasel` becomes
    // `e*ee*ease*l` where `*` is substituted by `prepend`) and prohibits `prohibit` character.
    struct MyEncoder { flag: bool, prohibit: char, prepend: &'static str, toggle: bool }
    impl RawEncoder for MyEncoder {
        fn from_self(&self) -> Box<RawEncoder> {
            Box::new(MyEncoder { flag: self.flag,
                                 prohibit: self.prohibit,
                                 prepend: self.prepend,
                                 toggle: false })
        }
        fn is_ascii_compatible(&self) -> bool { self.flag }
        fn raw_feed(&mut self, input: &str,
                    output: &mut ByteWriter) -> (usize, Option<CodecError>) {
            for ((i,j), ch) in input.index_iter() {
                if ch <= '\u{7f}' && ch != self.prohibit {
                    if self.toggle && !self.prepend.is_empty() {
                        output.write_bytes(self.prepend.as_bytes());
                    }
                    output.write_byte(ch as u8);
                    if ch == 'e' {
                        self.toggle = !self.toggle;
                    }
                } else {
                    return (i, Some(CodecError { upto: j as isize,
                                                 cause: "!!!".into() }));
                }
            }
            (input.len(), None)
        }
        fn raw_finish(&mut self, _output: &mut ByteWriter) -> Option<CodecError> { None }
    }

    struct MyEncoding { flag: bool, prohibit: char, prepend: &'static str }
    impl Encoding for MyEncoding {
        fn name(&self) -> &'static str { "my encoding" }
        fn raw_encoder(&self) -> Box<RawEncoder> {
            Box::new(MyEncoder { flag: self.flag,
                                 prohibit: self.prohibit,
                                 prepend: self.prepend,
                                 toggle: false })
        }
        fn raw_decoder(&self) -> Box<RawDecoder> { panic!("not supported") }
    }

    #[test]
    fn test_encoding_debug_format() {
        let enc = MyEncoding {
            flag: true,
            prohibit: '\u{80}',
            prepend: "",
        };

        assert_eq!(format!("{:?}", &enc as &Encoding), "Encoding(my encoding)");
    }

    #[test]
    fn test_reencoding_trap_with_ascii_compatible_encoding() {
        static COMPAT: &'static MyEncoding =
            &MyEncoding { flag: true, prohibit: '\u{80}', prepend: "" };
        static INCOMPAT: &'static MyEncoding =
            &MyEncoding { flag: false, prohibit: '\u{80}', prepend: "" };

        assert_eq!(COMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"Hello‽ I'm fine.".to_vec()));
        assert_eq!(INCOMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"Hello‽ I'm fine.".to_vec()));
    }

    #[test]
    fn test_reencoding_trap_with_ascii_incompatible_encoding() {
        static COMPAT: &'static MyEncoding =
            &MyEncoding { flag: true, prohibit: '\u{80}', prepend: "*" };
        static INCOMPAT: &'static MyEncoding =
            &MyEncoding { flag: false, prohibit: '\u{80}', prepend: "*" };

        // this should behave incorrectly as the encoding broke the assumption.
        assert_eq!(COMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"He*l*l*o‽* *I*'*m* *f*i*n*e.".to_vec()));
        assert_eq!(INCOMPAT.encode("Hello\u{203d} I'm fine.", NcrEscape),
                   Ok(b"He*l*l*o*&*#*8*2*5*3*;* *I*'*m* *f*i*n*e.".to_vec()));
    }

    #[test]
    fn test_encoding_sendable() {
        static COMPAT: &'static MyEncoding =
            &MyEncoding { flag: true, prohibit: '\u{80}', prepend: "*" };
        let encoder = COMPAT.raw_encoder();
        let (tx, _rx) = channel();
        tx.send(encoder);
    }

    #[test]
    #[should_panic]
    fn test_reencoding_trap_can_fail() {
        static FAIL: &'static MyEncoding = &MyEncoding { flag: false, prohibit: '&', prepend: "" };

        // this should fail as this contrived encoding does not support `&` at all
        let _ = FAIL.encode("Hello\u{203d} I'm fine.", NcrEscape);
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::fmt;
use std::path::{Path, PathBuf};

use prelude::*;

use uuid::Uuid;
use elementtree::Element;
use itertools::Itertools;

pub struct AndroidManifest {
    path: PathBuf,
    root: Element,
}

const ANDROID_NS: &'static str = "http://schemas.android.com/apk/res/android";
const UUIDS_TAG: &'static str = "io.sentry.ProguardUuids";

impl AndroidManifest {

    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<AndroidManifest> {
        let mut f = fs::File::open(path.as_ref())?;
        let root = Element::from_reader(f)?;
        Ok(AndroidManifest {
            path: path.as_ref().to_path_buf(),
            root: root,
        })
    }

    /// Returns the package ID
    pub fn package(&self) -> &str {
        self.root.get_attr("package").unwrap_or("unknown")
    }

    /// Returns a name
    pub fn name(&self) -> String {
        self.root.get_attr("package")
            .unwrap_or("unknown")
            .rsplit(".")
            .next()
            .unwrap()
            .chars()
            .enumerate()
            .map(|(idx, c)| {
                if idx == 0 {
                    c.to_uppercase().to_string()
                } else {
                    c.to_lowercase().to_string()
                }
            })
            .collect()
    }

    /// Returns the internal version code for this manifest
    pub fn version_code(&self) -> &str {
        self.root.get_attr((ANDROID_NS, "versionCode")).unwrap_or("0")
    }

    /// Returns the human readable version number of the manifest
    pub fn version_name(&self) -> &str {
        self.root.get_attr((ANDROID_NS, "versionName")).unwrap_or("0.0")
    }

    /// Returns the proguard uuids mentioned in the manifest
    pub fn proguard_uuids(&self) -> Vec<Uuid> {
        let mut rv = vec![];
        if let Some(app) = self.root.find("application") {
            for md in app.find_all("meta-data") {
                if md.get_attr((ANDROID_NS, "name")) == Some(UUIDS_TAG) {
                    let val = md.get_attr((ANDROID_NS, "value")).unwrap_or("");
                    for key in val.split('|') {
                        if let Ok(uuid) = key.parse() {
                            rv.push(uuid);
                        }
                    }
                }
            }
        }
        rv
    }

    /// Sets new values for the proguard uuids in the manifest
    pub fn set_proguard_uuids(&mut self, uuids: &[Uuid]) {
        let s = uuids.iter()
            .map(|x| x.to_string())
            .join("|");

        if let Some(mut app) = self.root.find_mut("application") {
            for mut md in app.find_all_mut("meta-data") {
                if md.get_attr((ANDROID_NS, "name")) == Some(UUIDS_TAG) {
                    md.set_attr((ANDROID_NS, "value"), s);
                    return;
                }
            }

            app.append_new_child("meta-data")
                .set_attr((ANDROID_NS, "name"), UUIDS_TAG)
                .set_attr((ANDROID_NS, "value"), s);
        }
    }

    /// Write back the file.
    pub fn save(&self) -> Result<()> {
        let mut f = fs::File::create(&self.path)?;
        self.root.to_writer(&mut f)?;
        Ok(())
    }
}

impl fmt::Debug for AndroidManifest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("AndroidManifest")
            .field("package", &self.package())
            .field("version_code", &self.version_code())
            .field("version_name", &self.version_name())
            .field("proguard_uuids", &self.proguard_uuids())
            .finish()
    }
}
<commit_msg>Fixed compiler warning<commit_after>use std::fs;
use std::fmt;
use std::path::{Path, PathBuf};

use prelude::*;

use uuid::Uuid;
use elementtree::Element;
use itertools::Itertools;

pub struct AndroidManifest {
    path: PathBuf,
    root: Element,
}

const ANDROID_NS: &'static str = "http://schemas.android.com/apk/res/android";
const UUIDS_TAG: &'static str = "io.sentry.ProguardUuids";

impl AndroidManifest {

    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<AndroidManifest> {
        let f = fs::File::open(path.as_ref())?;
        let root = Element::from_reader(f)?;
        Ok(AndroidManifest {
            path: path.as_ref().to_path_buf(),
            root: root,
        })
    }

    /// Returns the package ID
    pub fn package(&self) -> &str {
        self.root.get_attr("package").unwrap_or("unknown")
    }

    /// Returns a name
    pub fn name(&self) -> String {
        self.root.get_attr("package")
            .unwrap_or("unknown")
            .rsplit(".")
            .next()
            .unwrap()
            .chars()
            .enumerate()
            .map(|(idx, c)| {
                if idx == 0 {
                    c.to_uppercase().to_string()
                } else {
                    c.to_lowercase().to_string()
                }
            })
            .collect()
    }

    /// Returns the internal version code for this manifest
    pub fn version_code(&self) -> &str {
        self.root.get_attr((ANDROID_NS, "versionCode")).unwrap_or("0")
    }

    /// Returns the human readable version number of the manifest
    pub fn version_name(&self) -> &str {
        self.root.get_attr((ANDROID_NS, "versionName")).unwrap_or("0.0")
    }

    /// Returns the proguard uuids mentioned in the manifest
    pub fn proguard_uuids(&self) -> Vec<Uuid> {
        let mut rv = vec![];
        if let Some(app) = self.root.find("application") {
            for md in app.find_all("meta-data") {
                if md.get_attr((ANDROID_NS, "name")) == Some(UUIDS_TAG) {
                    let val = md.get_attr((ANDROID_NS, "value")).unwrap_or("");
                    for key in val.split('|') {
                        if let Ok(uuid) = key.parse() {
                            rv.push(uuid);
                        }
                    }
                }
            }
        }
        rv
    }

    /// Sets new values for the proguard uuids in the manifest
    pub fn set_proguard_uuids(&mut self, uuids: &[Uuid]) {
        let s = uuids.iter()
            .map(|x| x.to_string())
            .join("|");

        if let Some(mut app) = self.root.find_mut("application") {
            for mut md in app.find_all_mut("meta-data") {
                if md.get_attr((ANDROID_NS, "name")) == Some(UUIDS_TAG) {
                    md.set_attr((ANDROID_NS, "value"), s);
                    return;
                }
            }

            app.append_new_child("meta-data")
                .set_attr((ANDROID_NS, "name"), UUIDS_TAG)
                .set_attr((ANDROID_NS, "value"), s);
        }
    }

    /// Write back the file.
    pub fn save(&self) -> Result<()> {
        let mut f = fs::File::create(&self.path)?;
        self.root.to_writer(&mut f)?;
        Ok(())
    }
}

impl fmt::Debug for AndroidManifest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("AndroidManifest")
            .field("package", &self.package())
            .field("version_code", &self.version_code())
            .field("version_name", &self.version_name())
            .field("proguard_uuids", &self.proguard_uuids())
            .finish()
    }
}
<|endoftext|>


<commit_before>use ruby_sys::types;

use class::any_object::AnyObject;

pub use libc::{c_char, c_int, c_long};
pub use ruby_sys::types::ValueType;

pub type Value = types::Value;
pub type SignedValue = types::SignedValue;
pub type Id = types::Id;

pub type Argc = types::Argc;

pub type Callback<I, O> = extern "C" fn(Argc, *const AnyObject, I) -> O;
pub type CallbackPtr = types::CallbackPtr;
<commit_msg>Add InternalValue to types module<commit_after>use ruby_sys::types;

use class::any_object::AnyObject;

pub use libc::{c_char, c_int, c_long};
pub use ruby_sys::types::ValueType;

pub type Value = types::Value;
pub type InternalValue = types::InternalValue;
pub type SignedValue = types::SignedValue;
pub type Id = types::Id;

pub type Argc = types::Argc;

pub type Callback<I, O> = extern "C" fn(Argc, *const AnyObject, I) -> O;
pub type CallbackPtr = types::CallbackPtr;
<|endoftext|>