<commit_before>//! The context or environment in which the language server functions. In our
//! server implementation this is know as the `WorldState`.
//!
//! Each tick provides an immutable snapshot of the state as `WorldSnapshot`.

use std::{sync::Arc, time::Instant};

use crossbeam_channel::{unbounded, Receiver, Sender};
use flycheck::FlycheckHandle;
use lsp_types::{request::Request as _, Url};
use parking_lot::RwLock;
use ra_db::{CrateId, VfsPath};
use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId};
use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    config::Config,
    diagnostics::{CheckFixes, DiagnosticCollection},
    from_proto,
    line_endings::LineEndings,
    main_loop::Task,
    reload::SourceRootConfig,
    request_metrics::{LatestRequests, RequestMetrics},
    thread_pool::TaskPool,
    to_proto::url_from_abs_path,
    Result,
};

#[derive(Eq, PartialEq)]
pub(crate) enum Status {
    Loading,
    Ready,
}

impl Default for Status {
    fn default() -> Self {
        Status::Loading
    }
}

// Enforces drop order
pub(crate) struct Handle<H, C> {
    pub(crate) handle: H,
    pub(crate) receiver: C,
}

pub(crate) type ReqHandler = fn(&mut GlobalState, lsp_server::Response);
pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>;

/// `GlobalState` is the primary mutable state of the language server
///
/// The most interesting components are `vfs`, which stores a consistent
/// snapshot of the file systems, and `analysis_host`, which stores our
/// incremental salsa database.
///
/// Note that this struct has more than on impl in various modules!
pub(crate) struct GlobalState {
    sender: Sender<lsp_server::Message>,
    req_queue: ReqQueue,
    pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
    pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
    pub(crate) flycheck: Option<Handle<FlycheckHandle, Receiver<flycheck::Message>>>,
    pub(crate) config: Config,
    pub(crate) analysis_host: AnalysisHost,
    pub(crate) diagnostics: DiagnosticCollection,
    pub(crate) mem_docs: FxHashSet<VfsPath>,
    pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
    pub(crate) status: Status,
    pub(crate) source_root_config: SourceRootConfig,
    pub(crate) proc_macro_client: ProcMacroClient,
    pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
    latest_requests: Arc<RwLock<LatestRequests>>,
}

/// An immutable snapshot of the world's state at a point in time.
pub(crate) struct GlobalStateSnapshot {
    pub(crate) config: Config,
    pub(crate) analysis: Analysis,
    pub(crate) check_fixes: CheckFixes,
    pub(crate) latest_requests: Arc<RwLock<LatestRequests>>,
    vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
    pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
}

impl GlobalState {
    pub(crate) fn new(sender: Sender<lsp_server::Message>, config: Config) -> GlobalState {
        let loader = {
            let (sender, receiver) = unbounded::<vfs::loader::Message>();
            let handle: vfs_notify::NotifyHandle =
                vfs::loader::Handle::spawn(Box::new(move |msg| sender.send(msg).unwrap()));
            let handle = Box::new(handle) as Box<dyn vfs::loader::Handle>;
            Handle { handle, receiver }
        };

        let task_pool = {
            let (sender, receiver) = unbounded();
            let handle = TaskPool::new(sender);
            Handle { handle, receiver }
        };

        let analysis_host = AnalysisHost::new(config.lru_capacity);
        GlobalState {
            sender,
            req_queue: ReqQueue::default(),
            task_pool,
            loader,
            flycheck: None,
            config,
            analysis_host,
            diagnostics: Default::default(),
            mem_docs: FxHashSet::default(),
            vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))),
            status: Status::default(),
            source_root_config: SourceRootConfig::default(),
            proc_macro_client: ProcMacroClient::dummy(),
            workspaces: Arc::new(Vec::new()),
            latest_requests: Default::default(),
        }
    }

    pub(crate) fn process_changes(&mut self) -> bool {
        let change = {
            let mut change = AnalysisChange::new();
            let (vfs, line_endings_map) = &mut *self.vfs.write();
            let changed_files = vfs.take_changes();
            if changed_files.is_empty() {
                return false;
            }

            let fs_op = changed_files.iter().any(|it| it.is_created_or_deleted());
            if fs_op {
                let roots = self.source_root_config.partition(&vfs);
                change.set_roots(roots)
            }

            for file in changed_files {
                let text = if file.exists() {
                    let bytes = vfs.file_contents(file.file_id).to_vec();
                    match String::from_utf8(bytes).ok() {
                        Some(text) => {
                            let (text, line_endings) = LineEndings::normalize(text);
                            line_endings_map.insert(file.file_id, line_endings);
                            Some(Arc::new(text))
                        }
                        None => None,
                    }
                } else {
                    None
                };
                change.change_file(file.file_id, text);
            }
            change
        };

        self.analysis_host.apply_change(change);
        true
    }

    pub(crate) fn snapshot(&self) -> GlobalStateSnapshot {
        GlobalStateSnapshot {
            config: self.config.clone(),
            workspaces: Arc::clone(&self.workspaces),
            analysis: self.analysis_host.analysis(),
            vfs: Arc::clone(&self.vfs),
            latest_requests: Arc::clone(&self.latest_requests),
            check_fixes: Arc::clone(&self.diagnostics.check_fixes),
        }
    }

    pub(crate) fn send_request<R: lsp_types::request::Request>(
        &mut self,
        params: R::Params,
        handler: ReqHandler,
    ) {
        let request = self.req_queue.outgoing.register(
            lsp_types::request::WorkDoneProgressCreate::METHOD.to_string(),
            params,
            handler,
        );
        self.send(request.into());
    }
    pub(crate) fn complete_request(&mut self, response: lsp_server::Response) {
        let handler = self.req_queue.outgoing.complete(response.id.clone());
        handler(self, response)
    }

    pub(crate) fn send_notification<N: lsp_types::notification::Notification>(
        &mut self,
        params: N::Params,
    ) {
        let not = lsp_server::Notification::new(N::METHOD.to_string(), params);
        self.send(not.into());
    }

    pub(crate) fn register_request(
        &mut self,
        request: &lsp_server::Request,
        request_received: Instant,
    ) {
        self.req_queue
            .incoming
            .register(request.id.clone(), (request.method.clone(), request_received));
    }
    pub(crate) fn respond(&mut self, response: lsp_server::Response) {
        if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone()) {
            let duration = start.elapsed();
            log::info!("handled req#{} in {:?}", response.id, duration);
            let metrics =
                RequestMetrics { id: response.id.clone(), method: method.to_string(), duration };
            self.latest_requests.write().record(metrics);
            self.send(response.into());
        }
    }
    pub(crate) fn cancel(&mut self, request_id: lsp_server::RequestId) {
        if let Some(response) = self.req_queue.incoming.cancel(request_id) {
            self.send(response.into());
        }
    }

    fn send(&mut self, message: lsp_server::Message) {
        self.sender.send(message).unwrap()
    }
}

impl Drop for GlobalState {
    fn drop(&mut self) {
        self.analysis_host.request_cancellation()
    }
}

impl GlobalStateSnapshot {
    pub(crate) fn url_to_file_id(&self, url: &Url) -> Result<FileId> {
        url_to_file_id(&self.vfs.read().0, url)
    }

    pub(crate) fn file_id_to_url(&self, id: FileId) -> Url {
        file_id_to_url(&self.vfs.read().0, id)
    }

    pub(crate) fn file_line_endings(&self, id: FileId) -> LineEndings {
        self.vfs.read().1[&id]
    }

    pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url {
        let mut base = self.vfs.read().0.file_path(file_id);
        base.pop();
        let path = base.join(path).unwrap();
        let path = path.as_path().unwrap();
        url_from_abs_path(&path)
    }

    pub(crate) fn cargo_target_for_crate_root(
        &self,
        crate_id: CrateId,
    ) -> Option<(&CargoWorkspace, Target)> {
        let file_id = self.analysis.crate_root(crate_id).ok()?;
        let path = self.vfs.read().0.file_path(file_id);
        let path = path.as_path()?;
        self.workspaces.iter().find_map(|ws| match ws {
            ProjectWorkspace::Cargo { cargo, .. } => {
                cargo.target_by_root(&path).map(|it| (cargo, it))
            }
            ProjectWorkspace::Json { .. } => None,
        })
    }
}

pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url {
    let path = vfs.file_path(id);
    let path = path.as_path().unwrap();
    url_from_abs_path(&path)
}

pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> Result<FileId> {
    let path = from_proto::vfs_path(url)?;
    let res = vfs.file_id(&path).ok_or_else(|| format!("file not found: {}", path))?;
    Ok(res)
}
<commit_msg>Set corret request method<commit_after>//! The context or environment in which the language server functions. In our
//! server implementation this is know as the `WorldState`.
//!
//! Each tick provides an immutable snapshot of the state as `WorldSnapshot`.

use std::{sync::Arc, time::Instant};

use crossbeam_channel::{unbounded, Receiver, Sender};
use flycheck::FlycheckHandle;
use lsp_types::Url;
use parking_lot::RwLock;
use ra_db::{CrateId, VfsPath};
use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId};
use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    config::Config,
    diagnostics::{CheckFixes, DiagnosticCollection},
    from_proto,
    line_endings::LineEndings,
    main_loop::Task,
    reload::SourceRootConfig,
    request_metrics::{LatestRequests, RequestMetrics},
    thread_pool::TaskPool,
    to_proto::url_from_abs_path,
    Result,
};

#[derive(Eq, PartialEq)]
pub(crate) enum Status {
    Loading,
    Ready,
}

impl Default for Status {
    fn default() -> Self {
        Status::Loading
    }
}

// Enforces drop order
pub(crate) struct Handle<H, C> {
    pub(crate) handle: H,
    pub(crate) receiver: C,
}

pub(crate) type ReqHandler = fn(&mut GlobalState, lsp_server::Response);
pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>;

/// `GlobalState` is the primary mutable state of the language server
///
/// The most interesting components are `vfs`, which stores a consistent
/// snapshot of the file systems, and `analysis_host`, which stores our
/// incremental salsa database.
///
/// Note that this struct has more than on impl in various modules!
pub(crate) struct GlobalState {
    sender: Sender<lsp_server::Message>,
    req_queue: ReqQueue,
    pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
    pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
    pub(crate) flycheck: Option<Handle<FlycheckHandle, Receiver<flycheck::Message>>>,
    pub(crate) config: Config,
    pub(crate) analysis_host: AnalysisHost,
    pub(crate) diagnostics: DiagnosticCollection,
    pub(crate) mem_docs: FxHashSet<VfsPath>,
    pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
    pub(crate) status: Status,
    pub(crate) source_root_config: SourceRootConfig,
    pub(crate) proc_macro_client: ProcMacroClient,
    pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
    latest_requests: Arc<RwLock<LatestRequests>>,
}

/// An immutable snapshot of the world's state at a point in time.
pub(crate) struct GlobalStateSnapshot {
    pub(crate) config: Config,
    pub(crate) analysis: Analysis,
    pub(crate) check_fixes: CheckFixes,
    pub(crate) latest_requests: Arc<RwLock<LatestRequests>>,
    vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
    pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
}

impl GlobalState {
    pub(crate) fn new(sender: Sender<lsp_server::Message>, config: Config) -> GlobalState {
        let loader = {
            let (sender, receiver) = unbounded::<vfs::loader::Message>();
            let handle: vfs_notify::NotifyHandle =
                vfs::loader::Handle::spawn(Box::new(move |msg| sender.send(msg).unwrap()));
            let handle = Box::new(handle) as Box<dyn vfs::loader::Handle>;
            Handle { handle, receiver }
        };

        let task_pool = {
            let (sender, receiver) = unbounded();
            let handle = TaskPool::new(sender);
            Handle { handle, receiver }
        };

        let analysis_host = AnalysisHost::new(config.lru_capacity);
        GlobalState {
            sender,
            req_queue: ReqQueue::default(),
            task_pool,
            loader,
            flycheck: None,
            config,
            analysis_host,
            diagnostics: Default::default(),
            mem_docs: FxHashSet::default(),
            vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))),
            status: Status::default(),
            source_root_config: SourceRootConfig::default(),
            proc_macro_client: ProcMacroClient::dummy(),
            workspaces: Arc::new(Vec::new()),
            latest_requests: Default::default(),
        }
    }

    pub(crate) fn process_changes(&mut self) -> bool {
        let change = {
            let mut change = AnalysisChange::new();
            let (vfs, line_endings_map) = &mut *self.vfs.write();
            let changed_files = vfs.take_changes();
            if changed_files.is_empty() {
                return false;
            }

            let fs_op = changed_files.iter().any(|it| it.is_created_or_deleted());
            if fs_op {
                let roots = self.source_root_config.partition(&vfs);
                change.set_roots(roots)
            }

            for file in changed_files {
                let text = if file.exists() {
                    let bytes = vfs.file_contents(file.file_id).to_vec();
                    match String::from_utf8(bytes).ok() {
                        Some(text) => {
                            let (text, line_endings) = LineEndings::normalize(text);
                            line_endings_map.insert(file.file_id, line_endings);
                            Some(Arc::new(text))
                        }
                        None => None,
                    }
                } else {
                    None
                };
                change.change_file(file.file_id, text);
            }
            change
        };

        self.analysis_host.apply_change(change);
        true
    }

    pub(crate) fn snapshot(&self) -> GlobalStateSnapshot {
        GlobalStateSnapshot {
            config: self.config.clone(),
            workspaces: Arc::clone(&self.workspaces),
            analysis: self.analysis_host.analysis(),
            vfs: Arc::clone(&self.vfs),
            latest_requests: Arc::clone(&self.latest_requests),
            check_fixes: Arc::clone(&self.diagnostics.check_fixes),
        }
    }

    pub(crate) fn send_request<R: lsp_types::request::Request>(
        &mut self,
        params: R::Params,
        handler: ReqHandler,
    ) {
        let request = self.req_queue.outgoing.register(R::METHOD.to_string(), params, handler);
        self.send(request.into());
    }
    pub(crate) fn complete_request(&mut self, response: lsp_server::Response) {
        let handler = self.req_queue.outgoing.complete(response.id.clone());
        handler(self, response)
    }

    pub(crate) fn send_notification<N: lsp_types::notification::Notification>(
        &mut self,
        params: N::Params,
    ) {
        let not = lsp_server::Notification::new(N::METHOD.to_string(), params);
        self.send(not.into());
    }

    pub(crate) fn register_request(
        &mut self,
        request: &lsp_server::Request,
        request_received: Instant,
    ) {
        self.req_queue
            .incoming
            .register(request.id.clone(), (request.method.clone(), request_received));
    }
    pub(crate) fn respond(&mut self, response: lsp_server::Response) {
        if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone()) {
            let duration = start.elapsed();
            log::info!("handled req#{} in {:?}", response.id, duration);
            let metrics =
                RequestMetrics { id: response.id.clone(), method: method.to_string(), duration };
            self.latest_requests.write().record(metrics);
            self.send(response.into());
        }
    }
    pub(crate) fn cancel(&mut self, request_id: lsp_server::RequestId) {
        if let Some(response) = self.req_queue.incoming.cancel(request_id) {
            self.send(response.into());
        }
    }

    fn send(&mut self, message: lsp_server::Message) {
        self.sender.send(message).unwrap()
    }
}

impl Drop for GlobalState {
    fn drop(&mut self) {
        self.analysis_host.request_cancellation()
    }
}

impl GlobalStateSnapshot {
    pub(crate) fn url_to_file_id(&self, url: &Url) -> Result<FileId> {
        url_to_file_id(&self.vfs.read().0, url)
    }

    pub(crate) fn file_id_to_url(&self, id: FileId) -> Url {
        file_id_to_url(&self.vfs.read().0, id)
    }

    pub(crate) fn file_line_endings(&self, id: FileId) -> LineEndings {
        self.vfs.read().1[&id]
    }

    pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url {
        let mut base = self.vfs.read().0.file_path(file_id);
        base.pop();
        let path = base.join(path).unwrap();
        let path = path.as_path().unwrap();
        url_from_abs_path(&path)
    }

    pub(crate) fn cargo_target_for_crate_root(
        &self,
        crate_id: CrateId,
    ) -> Option<(&CargoWorkspace, Target)> {
        let file_id = self.analysis.crate_root(crate_id).ok()?;
        let path = self.vfs.read().0.file_path(file_id);
        let path = path.as_path()?;
        self.workspaces.iter().find_map(|ws| match ws {
            ProjectWorkspace::Cargo { cargo, .. } => {
                cargo.target_by_root(&path).map(|it| (cargo, it))
            }
            ProjectWorkspace::Json { .. } => None,
        })
    }
}

pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url {
    let path = vfs.file_path(id);
    let path = path.as_path().unwrap();
    url_from_abs_path(&path)
}

pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> Result<FileId> {
    let path = from_proto::vfs_path(url)?;
    let res = vfs.file_id(&path).ok_or_else(|| format!("file not found: {}", path))?;
    Ok(res)
}
<|endoftext|>


<commit_before><commit_msg>nth-prime: Add function template<commit_after>pub fn nth(n: u32) -> Option<u32> {
    unimplemented!("What is the {}th prime number?", n)
}
<|endoftext|>


<commit_before>//! SCCS-style delta weave stores.

use Result;
use SureTree;
use std::cell::RefCell;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::rc::Rc;

use super::{Store, StoreTags, Version};
use weave::{DeltaWriter, SimpleNaming, NamingConvention, NewWeave, Parser, Sink};

pub struct WeaveStore {
    naming: SimpleNaming,
}

impl WeaveStore {
    pub fn new<P: AsRef<Path>>(path: P, base: &str, compressed: bool) -> WeaveStore {
        WeaveStore {
            naming: SimpleNaming::new(path, base, "weave", compressed),
        }
    }
}

impl Store for WeaveStore {
    fn write_new(&self, tree: &SureTree, tags: &StoreTags) -> Result<()> {
        let itags = tags.iter().map(|(k,v)| (k.as_ref(), v.as_ref()));
        match File::open(self.naming.main_file()) {
            Ok(fd) => {
                // TODO: Much better to have a utility to get the delta from the code.
                let lines = BufReader::new(fd).lines();
                let parser = Parser::new(lines, Rc::new(RefCell::new(NullSink)), 1)?;
                let base = parser.get_header().deltas.iter()
                    .map(|x| x.number)
                    .max().expect("At least one delta in weave file");
                drop(parser); // Make sure the file gets closed.

                let mut wv = DeltaWriter::new(&self.naming, itags, base)?;
                tree.save_to(&mut wv)?;
                wv.close()?;
                Ok(())
            }
            Err(_) => {
                // Create a new weave file.
                let mut wv = NewWeave::new(&self.naming, itags)?;

                tree.save_to(&mut wv)?;

                wv.close()?;
                Ok(())
            }
        }
    }

    fn load(&self, version: Version) -> Result<SureTree> {
        panic!("TODO")
    }
}

// The null sink does nothing.
struct NullSink;

impl Sink for NullSink {}
<commit_msg>Move 'get_last_delta' out to a function<commit_after>//! SCCS-style delta weave stores.

use Result;
use SureTree;
use std::cell::RefCell;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::rc::Rc;

use super::{Store, StoreTags, Version};
use weave::{DeltaWriter, SimpleNaming, NamingConvention, NewWeave, Parser, Sink};

pub struct WeaveStore {
    naming: SimpleNaming,
}

impl WeaveStore {
    pub fn new<P: AsRef<Path>>(path: P, base: &str, compressed: bool) -> WeaveStore {
        WeaveStore {
            naming: SimpleNaming::new(path, base, "weave", compressed),
        }
    }
}

impl Store for WeaveStore {
    fn write_new(&self, tree: &SureTree, tags: &StoreTags) -> Result<()> {
        let itags = tags.iter().map(|(k,v)| (k.as_ref(), v.as_ref()));
        match get_last_delta(&self.naming) {
            Ok(base) => {
                let mut wv = DeltaWriter::new(&self.naming, itags, base)?;
                tree.save_to(&mut wv)?;
                wv.close()?;
                Ok(())
            }
            Err(_) => {
                // Create a new weave file.
                let mut wv = NewWeave::new(&self.naming, itags)?;

                tree.save_to(&mut wv)?;

                wv.close()?;
                Ok(())
            }
        }
    }

    fn load(&self, version: Version) -> Result<SureTree> {
        panic!("TODO")
    }
}

/// Get the delta number of the most recent delta.
fn get_last_delta(naming: &NamingConvention) -> Result<usize> {
    let fd = File::open(naming.main_file())?;
    let lines = BufReader::new(fd).lines();
    let parser = Parser::new(lines, Rc::new(RefCell::new(NullSink)), 1)?;
    let base = parser.get_header().deltas.iter()
        .map(|x| x.number)
        .max().expect("At least one delta in weave file");
    Ok(base)
}

// The null sink does nothing.
struct NullSink;

impl Sink for NullSink {}
<|endoftext|>


<commit_before>#![feature(zero_one)]

extern crate rand;
extern crate evo;
extern crate petgraph;
#[macro_use]
extern crate graph_annealing;
extern crate clap;
extern crate crossbeam;
extern crate simple_parallel;
extern crate num_cpus;
extern crate pcg;
extern crate graph_sgf;
extern crate triadic_census;
extern crate time;
extern crate lindenmayer_system;
extern crate graph_edge_evolution;
extern crate asexp;

extern crate rayon;

#[path="genome/genome_edgeop_lsys.rs"]
pub mod genome;

use std::str::FromStr;
use clap::{App, Arg};
use rand::{Rng, SeedableRng};
use rand::distributions::{IndependentSample, Range};
use rand::os::OsRng;
use pcg::PcgRng;
use evo::Probability;
use evo::nsga2::{self, FitnessEval};
use genome::{Genome, Toolbox};
use graph_annealing::helper::{draw_graph, parse_weighted_op_list, to_weighted_vec};
use graph_annealing::goal::Goal;
use graph_annealing::stat::Stat;
use graph_annealing::fitness_function::FitnessFunction;
use simple_parallel::Pool;
use petgraph::{Directed, Graph};
use graph_sgf::{PetgraphReader, Unweighted};
use triadic_census::OptDenseDigraph;
use std::io::BufReader;
use std::fs::File;
use genome::VarOp;
use genome::edgeop::{EdgeOp, edgeops_to_graph};
use genome::expr_op::{ConstExprOp, ExprOp, FlatExprOp};
use std::io::Read;
use asexp::Expr;

#[derive(Debug)]
struct Config {
    ngen: usize,
    mu: usize,
    lambda: usize,
    k: usize,
    seed: Vec<u64>,
    objectives: Vec<FitnessFunction>,
    thresholds: Vec<f32>,
    graph: Graph<Unweighted, Unweighted, Directed>,
    edge_ops: Vec<(EdgeOp, u32)>,
    var_ops: Vec<(VarOp, u32)>,
}

fn read_config() -> Config {
    let matches = App::new("nsga2_edge")
                      .arg(Arg::with_name("NGEN")
                               .long("ngen")
                               .help("Number of generations to run")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("OPS")
                               .long("ops")
                               .help("Edge operation and weight specification, e.g. \
                                      Dup:1,Split:3,Parent:2")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("GRAPH")
                               .long("graph")
                               .help("SGF graph file")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("MU")
                               .long("mu")
                               .help("Population size")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("LAMBDA")
                               .long("lambda")
                               .help("Size of offspring population")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("K")
                               .long("k")
                               .help("Tournament selection (default: 2)")
                               .takes_value(true))
                      .arg(Arg::with_name("SEED")
                               .long("seed")
                               .help("Seed value for Rng")
                               .takes_value(true))
                      .arg(Arg::with_name("VAROPS")
                               .long("varops")
                               .help("Variation operators and weight specification, e.g. \
                                      Mutate:1,LinearCrossover2:1,UniformCrossover:2,Copy:0")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("OBJECTIVES")
                               .long("objectives")
                               .help("Specify 3 objective functions comma separated (null, cc, \
                                      scc, nm, td), e.g. cc,nm,td")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("THRESHOLD")
                               .long("threshold")
                               .help("Abort if for all fitness[i] <= value[i] (default: 0,0,0)")
                               .takes_value(true)
                               .required(false))
                      .get_matches();

    // number of generations
    let ngen: usize = FromStr::from_str(matches.value_of("NGEN").unwrap()).unwrap();

    // size of population
    let mu: usize = FromStr::from_str(matches.value_of("MU").unwrap()).unwrap();

    // size of offspring population
    let lambda: usize = FromStr::from_str(matches.value_of("LAMBDA").unwrap()).unwrap();

    // tournament selection
    let k: usize = FromStr::from_str(matches.value_of("K").unwrap_or("2")).unwrap();
    assert!(k > 0);

    let seed: Vec<u64>;
    if let Some(seed_str) = matches.value_of("SEED") {
        seed = seed_str.split(",").map(|s| FromStr::from_str(s).unwrap()).collect();
    } else {
        println!("Use OsRng to generate seed..");
        let mut rng = OsRng::new().unwrap();
        seed = (0..2).map(|_| rng.next_u64()).collect();
    }

    // read objective functions
    let mut objectives_arr: Vec<FitnessFunction> = matches.value_of("OBJECTIVES")
                                                          .unwrap()
                                                          .split(",")
                                                          .map(|s| {
                                                              FitnessFunction::from_str(s).unwrap()
                                                          })
                                                          .collect();

    while objectives_arr.len() < 3 {
        objectives_arr.push(FitnessFunction::Null);
    }

    if objectives_arr.len() > 3 {
        panic!("Max 3 objectives allowed");
    }

    // read objective functions
    let mut threshold_arr: Vec<f32> = Vec::new();
    for s in matches.value_of("THRESHOLD").unwrap_or("").split(",") {
        let value: f32 = FromStr::from_str(s).unwrap();
        threshold_arr.push(value);
    }

    while threshold_arr.len() < 3 {
        threshold_arr.push(0.0);
    }

    if threshold_arr.len() > 3 {
        panic!("Max 3 threshold values allowed");
    }

    // read graph
    let graph_file = matches.value_of("GRAPH").unwrap();
    println!("Using graph file: {}", graph_file);
    let graph = {
        let mut f = BufReader::new(File::open(graph_file).unwrap());
        let graph: Graph<Unweighted, Unweighted, Directed> = PetgraphReader::from_sgf(&mut f);
        graph
    };

    // Parse weighted operation choice from command line
    let edge_ops = parse_weighted_op_list(matches.value_of("OPS").unwrap()).unwrap();

    // Parse weighted variation operators from command line
    let var_ops = parse_weighted_op_list(matches.value_of("VAROPS").unwrap()).unwrap();

    Config {
        ngen: ngen,
        mu: mu,
        lambda: lambda,
        k: k,
        seed: seed,
        objectives: objectives_arr,
        thresholds: threshold_arr,
        graph: graph,
        edge_ops: edge_ops,
        var_ops: var_ops,
    }
}

fn read_config_from_asexp(expr: Expr) -> Config {
    let map = expr.into_map().unwrap();

    // number of generations
    let ngen: usize = map.get("ngen").and_then(|v| v.get_uint()).unwrap() as usize;

    // size of population
    let mu: usize = map.get("mu").and_then(|v| v.get_uint()).unwrap() as usize;

    // size of offspring population
    let lambda: usize = map.get("lambda").and_then(|v| v.get_uint()).unwrap() as usize;

    // tournament selection
    let k: usize = map.get("k").and_then(|v| v.get_uint()).unwrap_or(2) as usize;
    assert!(k > 0);

    let seed: Vec<u64>;
    if let Some(seed_expr) = map.get("seed") {
        seed = seed_expr.get_uint_vec().unwrap();
    } else {
        println!("Use OsRng to generate seed..");
        let mut rng = OsRng::new().unwrap();
        seed = (0..2).map(|_| rng.next_u64()).collect();
    }

    // read objective functions
    let mut objectives_arr: Vec<FitnessFunction> = map.get("objectives").unwrap().get_vec(|elm| FitnessFunction::from_str(elm.get_str().unwrap()).ok()).unwrap();

    while objectives_arr.len() < 3 {
        objectives_arr.push(FitnessFunction::Null);
    }

    if objectives_arr.len() > 3 {
        panic!("Max 3 objectives allowed");
    }

    // read objective functions
    let mut threshold_arr: Vec<f32> = map.get("thresholds").unwrap().get_vec(|elm| elm.get_float()).unwrap().iter().map(|&i| i as f32).collect();

    while threshold_arr.len() < 3 {
        threshold_arr.push(0.0);
    }

    if threshold_arr.len() > 3 {
        panic!("Max 3 threshold values allowed");
    }

    // read graph
    let graph_file = map.get("graph").unwrap().get_str().unwrap();
    println!("Using graph file: {}", graph_file);
    let graph = {
        let mut f = BufReader::new(File::open(graph_file).unwrap());
        let graph: Graph<Unweighted, Unweighted, Directed> = PetgraphReader::from_sgf(&mut f);
        graph
    };

    // Parse weighted operation choice from command line
    let mut edge_ops: Vec<(EdgeOp, u32)> = Vec::new();
    if let Some(&Expr::Map(ref list)) = map.get("edgeops") {
        for &(ref k, ref v) in list.iter() {
            edge_ops.push((EdgeOp::from_str(k.get_str().unwrap()).unwrap(), v.get_uint().unwrap() as u32));
        }
    } else {
        panic!();
    }

    // Parse weighted variation operators from command line
    let mut var_ops: Vec<(VarOp, u32)> = Vec::new();
    if let Some(&Expr::Map(ref list)) = map.get("varops") {
        for &(ref k, ref v) in list.iter() {
            var_ops.push((VarOp::from_str(k.get_str().unwrap()).unwrap(), v.get_uint().unwrap() as u32));
        }
    } else {
        panic!();
    }

    Config {
        ngen: ngen,
        mu: mu,
        lambda: lambda,
        k: k,
        seed: seed,
        objectives: objectives_arr,
        thresholds: threshold_arr,
        graph: graph,
        edge_ops: edge_ops,
        var_ops: var_ops,
    }
}

fn main() {
    // rayon::initialize();

    let ncpus = num_cpus::get();
    println!("Using {} CPUs", ncpus);

    let mut s = String::new();
    let _ = File::open("runit.config").unwrap().read_to_string(&mut s).unwrap();
    let expr = asexp::Expr::parse_toplevel(&s).unwrap();
    let config = read_config_from_asexp(expr);

    //let config = read_config();
    println!("{:#?}", config);

    let w_ops = to_weighted_vec(&config.edge_ops);
    assert!(w_ops.len() > 0);

    let w_var_ops = to_weighted_vec(&config.var_ops);
    assert!(w_var_ops.len() > 0);

    let mut toolbox = Toolbox::new(Goal::new(OptDenseDigraph::from(config.graph.clone())),
                                   Pool::new(ncpus),
                                   (config.objectives[0], config.objectives[1], config.objectives[2]),

                                   3, // iterations
                                   20, // num_rules
                                   4, // initial rule length
                                   2, // we use 2-ary symbols
                                   Probability::new(0.7), // prob_terminal
                                   2, // max_expr_depth

                                   w_ops,
                                   ExprOp::uniform_distribution(),
                                   FlatExprOp::uniform_distribution(),
                                   ConstExprOp::uniform_distribution(),
                                   w_var_ops);

    assert!(config.seed.len() == 2);
    let mut rng: PcgRng = SeedableRng::from_seed([config.seed[0], config.seed[1]]);

    // create initial random population
    let initial_population: Vec<Genome> = (0..config.mu)
                                              .map(|_| {
                                                  toolbox.random_genome(&mut rng)
                                              })
                                              .collect();

    // output initial population to stdout.
    println!("Population: {:#?}", initial_population);

    // evaluate fitness
    let fitness: Vec<_> = toolbox.fitness(&initial_population[..]);
    assert!(fitness.len() == initial_population.len());

    let mut pop = initial_population;
    let mut fit = fitness;

    for iteration in 0..config.ngen {
        print!("# {:>6}", iteration);
        let before = time::precise_time_ns();
        let (new_pop, new_fit) = nsga2::iterate(&mut rng, pop, fit, config.mu, config.lambda, config.k, &mut toolbox);
        let duration = time::precise_time_ns() - before;
        pop = new_pop;
        fit = new_fit;

        // calculate a min/max/avg value for each objective.
        let stat0: Stat<f32> = Stat::for_objectives(&fit[..], 0);
        let stat1: Stat<f32> = Stat::for_objectives(&fit[..], 1);
        let stat2: Stat<f32> = Stat::for_objectives(&fit[..], 2);

        let duration_ms = (duration as f32) / 1_000_000.0;

        let mut num_optima = 0;
        for f in fit.iter() {
            if f.objectives[0] <= config.thresholds[0] && f.objectives[1] <= config.thresholds[1] &&
               f.objectives[2] <= config.thresholds[2] {
                num_optima += 1;
            }
        }

        print!(" | ");
        print!("{:>8.1}", stat0.min);
        print!("{:>9.1}", stat0.avg);
        print!("{:>10.1}", stat0.max);
        print!(" | ");
        print!("{:>8.1}", stat1.min);
        print!("{:>9.1}", stat1.avg);
        print!("{:>10.1}", stat1.max);
        print!(" | ");
        print!("{:>8.1}", stat2.min);
        print!("{:>9.1}", stat2.avg);
        print!("{:>10.1}", stat2.max);

        print!(" | {:>5} | {:>8.0} ms", num_optima, duration_ms);

        println!("");

        if num_optima > 0 {
            println!("Found premature optimum in Iteration {}", iteration);
            break;
        }
    }
    println!("===========================================================");

    // finally evaluate rank and crowding distance (using select()).
    let rank_dist = nsga2::select(&fit[..], config.mu);
    assert!(rank_dist.len() == config.mu);

    let mut j = 0;

    for rd in rank_dist.iter() {
        if rd.rank == 0 {
            println!("-------------------------------------------");
            println!("rd: {:?}", rd);
            println!("fitness: {:?}", fit[rd.idx]);
            println!("genome: {:?}", pop[rd.idx]);

            // if fit[rd.idx].objectives[0] < 1.0 {
            let ind = &pop[rd.idx];
            let edge_ops = ind.to_edge_ops(&toolbox.axiom_args, toolbox.iterations);
            let g = edgeops_to_graph(&edge_ops);

            draw_graph(g.ref_graph(),
                       // XXX: name
                       &format!("edgeop_lsys_g{}_f{}_i{}.svg",
                                config.ngen,
                                fit[rd.idx].objectives[1] as usize,
                                j));
            j += 1;
            // }
        }
    }
}
<commit_msg>Remove command line parsing. Read config file from command line<commit_after>#![feature(zero_one)]

extern crate rand;
extern crate evo;
extern crate petgraph;
#[macro_use]
extern crate graph_annealing;
extern crate crossbeam;
extern crate simple_parallel;
extern crate num_cpus;
extern crate pcg;
extern crate graph_sgf;
extern crate triadic_census;
extern crate time;
extern crate lindenmayer_system;
extern crate graph_edge_evolution;
extern crate asexp;

extern crate rayon;

#[path="genome/genome_edgeop_lsys.rs"]
pub mod genome;

use std::str::FromStr;
use rand::{Rng, SeedableRng};
use rand::distributions::{IndependentSample, Range};
use rand::os::OsRng;
use pcg::PcgRng;
use evo::Probability;
use evo::nsga2::{self, FitnessEval};
use genome::{Genome, Toolbox};
use graph_annealing::helper::{draw_graph, parse_weighted_op_list, to_weighted_vec};
use graph_annealing::goal::Goal;
use graph_annealing::stat::Stat;
use graph_annealing::fitness_function::FitnessFunction;
use simple_parallel::Pool;
use petgraph::{Directed, Graph};
use graph_sgf::{PetgraphReader, Unweighted};
use triadic_census::OptDenseDigraph;
use std::io::BufReader;
use std::fs::File;
use genome::VarOp;
use genome::edgeop::{EdgeOp, edgeops_to_graph};
use genome::expr_op::{ConstExprOp, ExprOp, FlatExprOp};
use std::io::Read;
use asexp::Expr;
use std::env;

#[derive(Debug)]
struct Config {
    ngen: usize,
    mu: usize,
    lambda: usize,
    k: usize,
    seed: Vec<u64>,
    objectives: Vec<FitnessFunction>,
    thresholds: Vec<f32>,
    graph: Graph<Unweighted, Unweighted, Directed>,
    edge_ops: Vec<(EdgeOp, u32)>,
    var_ops: Vec<(VarOp, u32)>,
}

fn parse_config(expr: Expr) -> Config {
    let map = expr.into_map().unwrap();

    // number of generations
    let ngen: usize = map.get("ngen").and_then(|v| v.get_uint()).unwrap() as usize;

    // size of population
    let mu: usize = map.get("mu").and_then(|v| v.get_uint()).unwrap() as usize;

    // size of offspring population
    let lambda: usize = map.get("lambda").and_then(|v| v.get_uint()).unwrap() as usize;

    // tournament selection
    let k: usize = map.get("k").and_then(|v| v.get_uint()).unwrap_or(2) as usize;
    assert!(k > 0);

    let seed: Vec<u64>;
    if let Some(seed_expr) = map.get("seed") {
        seed = seed_expr.get_uint_vec().unwrap();
    } else {
        println!("Use OsRng to generate seed..");
        let mut rng = OsRng::new().unwrap();
        seed = (0..2).map(|_| rng.next_u64()).collect();
    }

    // read objective functions
    let mut objectives_arr: Vec<FitnessFunction> = map.get("objectives").unwrap().get_vec(|elm| FitnessFunction::from_str(elm.get_str().unwrap()).ok()).unwrap();

    while objectives_arr.len() < 3 {
        objectives_arr.push(FitnessFunction::Null);
    }

    if objectives_arr.len() > 3 {
        panic!("Max 3 objectives allowed");
    }

    // read objective functions
    let mut threshold_arr: Vec<f32> = map.get("thresholds").unwrap().get_vec(|elm| elm.get_float()).unwrap().iter().map(|&i| i as f32).collect();

    while threshold_arr.len() < 3 {
        threshold_arr.push(0.0);
    }

    if threshold_arr.len() > 3 {
        panic!("Max 3 threshold values allowed");
    }

    // read graph
    let graph_file = map.get("graph").unwrap().get_str().unwrap();
    println!("Using graph file: {}", graph_file);
    let graph = {
        let mut f = BufReader::new(File::open(graph_file).unwrap());
        let graph: Graph<Unweighted, Unweighted, Directed> = PetgraphReader::from_sgf(&mut f);
        graph
    };

    // Parse weighted operation choice from command line
    let mut edge_ops: Vec<(EdgeOp, u32)> = Vec::new();
    if let Some(&Expr::Map(ref list)) = map.get("edgeops") {
        for &(ref k, ref v) in list.iter() {
            edge_ops.push((EdgeOp::from_str(k.get_str().unwrap()).unwrap(), v.get_uint().unwrap() as u32));
        }
    } else {
        panic!();
    }

    // Parse weighted variation operators from command line
    let mut var_ops: Vec<(VarOp, u32)> = Vec::new();
    if let Some(&Expr::Map(ref list)) = map.get("varops") {
        for &(ref k, ref v) in list.iter() {
            var_ops.push((VarOp::from_str(k.get_str().unwrap()).unwrap(), v.get_uint().unwrap() as u32));
        }
    } else {
        panic!();
    }

    Config {
        ngen: ngen,
        mu: mu,
        lambda: lambda,
        k: k,
        seed: seed,
        objectives: objectives_arr,
        thresholds: threshold_arr,
        graph: graph,
        edge_ops: edge_ops,
        var_ops: var_ops,
    }
}

fn main() {
    // rayon::initialize();

    let ncpus = num_cpus::get();
    println!("Using {} CPUs", ncpus);

    let mut s = String::new();
    let configfile = env::args().nth(1).unwrap();
    let _ = File::open(configfile).unwrap().read_to_string(&mut s).unwrap();
    let expr = asexp::Expr::parse_toplevel(&s).unwrap();
    let config = parse_config(expr);

    println!("{:#?}", config);

    let w_ops = to_weighted_vec(&config.edge_ops);
    assert!(w_ops.len() > 0);

    let w_var_ops = to_weighted_vec(&config.var_ops);
    assert!(w_var_ops.len() > 0);

    let mut toolbox = Toolbox::new(Goal::new(OptDenseDigraph::from(config.graph.clone())),
                                   Pool::new(ncpus),
                                   (config.objectives[0], config.objectives[1], config.objectives[2]),

                                   3, // iterations
                                   20, // num_rules
                                   4, // initial rule length
                                   2, // we use 2-ary symbols
                                   Probability::new(0.7), // prob_terminal
                                   2, // max_expr_depth

                                   w_ops,
                                   ExprOp::uniform_distribution(),
                                   FlatExprOp::uniform_distribution(),
                                   ConstExprOp::uniform_distribution(),
                                   w_var_ops);

    assert!(config.seed.len() == 2);
    let mut rng: PcgRng = SeedableRng::from_seed([config.seed[0], config.seed[1]]);

    // create initial random population
    let initial_population: Vec<Genome> = (0..config.mu)
                                              .map(|_| {
                                                  toolbox.random_genome(&mut rng)
                                              })
                                              .collect();

    // output initial population to stdout.
    println!("Population: {:#?}", initial_population);

    // evaluate fitness
    let fitness: Vec<_> = toolbox.fitness(&initial_population[..]);
    assert!(fitness.len() == initial_population.len());

    let mut pop = initial_population;
    let mut fit = fitness;

    for iteration in 0..config.ngen {
        print!("# {:>6}", iteration);
        let before = time::precise_time_ns();
        let (new_pop, new_fit) = nsga2::iterate(&mut rng, pop, fit, config.mu, config.lambda, config.k, &mut toolbox);
        let duration = time::precise_time_ns() - before;
        pop = new_pop;
        fit = new_fit;

        // calculate a min/max/avg value for each objective.
        let stat0: Stat<f32> = Stat::for_objectives(&fit[..], 0);
        let stat1: Stat<f32> = Stat::for_objectives(&fit[..], 1);
        let stat2: Stat<f32> = Stat::for_objectives(&fit[..], 2);

        let duration_ms = (duration as f32) / 1_000_000.0;

        let mut num_optima = 0;
        for f in fit.iter() {
            if f.objectives[0] <= config.thresholds[0] && f.objectives[1] <= config.thresholds[1] &&
               f.objectives[2] <= config.thresholds[2] {
                num_optima += 1;
            }
        }

        print!(" | ");
        print!("{:>8.1}", stat0.min);
        print!("{:>9.1}", stat0.avg);
        print!("{:>10.1}", stat0.max);
        print!(" | ");
        print!("{:>8.1}", stat1.min);
        print!("{:>9.1}", stat1.avg);
        print!("{:>10.1}", stat1.max);
        print!(" | ");
        print!("{:>8.1}", stat2.min);
        print!("{:>9.1}", stat2.avg);
        print!("{:>10.1}", stat2.max);

        print!(" | {:>5} | {:>8.0} ms", num_optima, duration_ms);

        println!("");

        if num_optima > 0 {
            println!("Found premature optimum in Iteration {}", iteration);
            break;
        }
    }
    println!("===========================================================");

    // finally evaluate rank and crowding distance (using select()).
    let rank_dist = nsga2::select(&fit[..], config.mu);
    assert!(rank_dist.len() == config.mu);

    let mut j = 0;

    for rd in rank_dist.iter() {
        if rd.rank == 0 {
            println!("-------------------------------------------");
            println!("rd: {:?}", rd);
            println!("fitness: {:?}", fit[rd.idx]);
            println!("genome: {:?}", pop[rd.idx]);

            // if fit[rd.idx].objectives[0] < 1.0 {
            let ind = &pop[rd.idx];
            let edge_ops = ind.to_edge_ops(&toolbox.axiom_args, toolbox.iterations);
            let g = edgeops_to_graph(&edge_ops);

            draw_graph(g.ref_graph(),
                       // XXX: name
                       &format!("edgeop_lsys_g{}_f{}_i{}.svg",
                                config.ngen,
                                fit[rd.idx].objectives[1] as usize,
                                j));
            j += 1;
            // }
        }
    }
}
<|endoftext|>


<commit_before>// src/controllers/money_maps_controller.rs

/// Money Maps Controller

// Import
// External
use ::chrono::{DateTime, Duration, Local};
use ::nickel::{JsonBody, Request};
use ::bson::{Bson, Document};
use ::bson::oid::ObjectId;
use ::std::default::Default;
use ::crypto::sha2::Sha256;
use ::jwt::{Header, Registered, Token};
use ::rustc_serialize::hex::ToHex;
// Utilities
use ::common::api_result::ApiResult;
use ::common::config::Config;
use ::common::data_access::ServerData;
use ::common::mm_result::{MMResult, MMError, MMErrorKind};
use ::common::session as Session;
// DAO
use ::dao::dao_manager::DAOManager;
// Models
use ::models::user_model::{OutUserModel};
use ::models::money_map_model::{MoneyMapModel, MoneyMapUserModel};

#[derive(Clone)]
pub struct MoneyMapsController{
    dao_manager: DAOManager,
    config: Config
}

impl MoneyMapsController{

    pub fn new(dao_manager: DAOManager, config: Config) -> MoneyMapsController{
        MoneyMapsController{
            dao_manager: dao_manager,
            config: config
        }
    }

    /// Find All Money Maps belonging to the requesting user
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<Vec<MoneyMapModel>>` - ApiResult including a vector of money maps
    pub fn find(&self, req: &mut Request<ServerData>) -> ApiResult<Vec<MoneyMapModel>>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                //Get list of money maps for this user
                let mut money_maps = dao.find(Some(doc!{
                    "users.user_id" => user_id,
                    "deleted" => {
                        "$ne" => true
                    }
                }));

                // Get list of user details for each money map
                for i in 0..money_maps.len(){
                    match self.get_users_for_mm(&money_maps[i]){
                        Ok(users_list) => {
                            // Add the new list of user details to the money map
                            money_maps[i].set_users(Some(users_list));
                        },
                        Err(e) => {
                            return ApiResult::Failure{msg:e.get_message()};
                        }
                    }
                }

                // Return the list of money maps
                ApiResult::Success{result:money_maps}
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end find_all

    /// Create Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the create money map
    pub fn create(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        match req.json_as::<MoneyMapModel>(){
                            Ok(mut money_map) => {
                                // Validate
                                let validation_result = money_map.validate();
                                if validation_result.is_valid(){
                                    // Save User
                                    match dao.create(&money_map, user_id.clone()){
                                        Ok(result) => {
                                            // Set user ID
                                            match result.inserted_id{
                                                Some(id_wrapper) => {
                                                    match id_wrapper{
                                                        Bson::ObjectId(id) => money_map.set_id(id),
                                                        _ => {}
                                                    }
                                                },
                                                None => {}
                                            }
                                            // Add user details
                                            if let Ok(id) = ObjectId::with_string(user_id.as_str()){
                                                if let Some(user) = user_dao.find_one(Some(doc!{"_id" => id}), None){
                                                    money_map.set_users(Some(
                                                        vec![
                                                            MoneyMapUserModel::new(OutUserModel::new(user), true)
                                                        ]
                                                    ));
                                                }
                                            }

                                            ApiResult::Success{result:money_map}
                                        },
                                        Err(e) => {
                                            error!("{}",e);
                                            ApiResult::Failure{msg:"Unable to create money map"}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:money_map}
                                }
                            },
                            Err(e) => {
                                error!("{}",e);
                                ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                            }
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        ApiResult::Failure{msg:"Unable to interact with database"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end create

    /// Modify Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the modified user
    pub fn modify(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {

                match req.json_as::<MoneyMapModel>(){
                    Ok(edit_money_map) => {
                        // Get Money Map
                        if let Some(mm_id) = edit_money_map.get_id(){
                            let filter = doc!{
                                "_id" => mm_id,
                                "users.user_id" => user_id
                            };

                            if let Some(money_map) = dao.find_one(Some(filter), None){

                            // Verify User has access

                            // Validate
                                let validation_result = edit_money_map.validate();
                                if validation_result.is_valid(){
                                    // Save
                                    match dao.update(&edit_money_map){
                                        Ok(mut updated_mm) => {
                                            match self.get_users_for_mm(&updated_mm){
                                                Ok(users_list) => {
                                                    // Add the new list of user details to the money map
                                                    updated_mm.set_users(Some(users_list));
                                                    ApiResult::Success{result:updated_mm}
                                                },
                                                Err(e) => {
                                                    ApiResult::Success{result:updated_mm}
                                                }
                                            }
                                        },
                                        Err(e) => {
                                            ApiResult::Failure{msg:e.get_message()}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:edit_money_map}
                                }

                            }else{
                                ApiResult::Failure{msg:"Unable to find Money Map"}
                            }
                        }else{
                            ApiResult::Failure{msg:"Invalid Money Map ID"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end modify

    /// Delete a Money Map
    ///
    /// # Arguments
    /// &self
    /// id - String
    ///
    /// # Returns
    /// `ApiResult<String>` - ApiResult
    pub fn delete(&self, id: &str) -> ApiResult<String>{
        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match dao.delete(id){
                    Ok(result) => {
                        if result.acknowledged && result.modified_count > 0 {
                            ApiResult::Success{result:"Successfully deleted money map".to_string()}
                        }else{
                            ApiResult::Failure{msg:"Unable to delete money map"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Malformed ID"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end delete

    fn get_users_for_mm(&self, money_map: &MoneyMapModel) -> MMResult<Vec<MoneyMapUserModel>>{
        // Initialze a list of user details for this money map
        let mut users_list = Vec::new();
        if let Some(mm_users) = money_map.get_users(){

            // For each user associated with this money map
            for mm_user in mm_users{
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        // Fetch the user's details
                        let user_id = Bson::ObjectId(mm_user.user.unwrap().id.unwrap());
                        let found_user = user_dao.find_one(Some(doc!{
                            "_id" => user_id
                        }), None);
                        if let Some(user) = found_user{
                            // Add the user details to the list
                            users_list.push(
                                MoneyMapUserModel::new(OutUserModel::new(user), mm_user.owner)
                            );
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        return Err(MMError::new("Unable to interact with database", MMErrorKind::Controller));
                    }
                }
            }
        }
        Ok(users_list)
    }
}
<commit_msg>Fix modify money map user verification documentation<commit_after>// src/controllers/money_maps_controller.rs

/// Money Maps Controller

// Import
// External
use ::chrono::{DateTime, Duration, Local};
use ::nickel::{JsonBody, Request};
use ::bson::{Bson, Document};
use ::bson::oid::ObjectId;
use ::std::default::Default;
use ::crypto::sha2::Sha256;
use ::jwt::{Header, Registered, Token};
use ::rustc_serialize::hex::ToHex;
// Utilities
use ::common::api_result::ApiResult;
use ::common::config::Config;
use ::common::data_access::ServerData;
use ::common::mm_result::{MMResult, MMError, MMErrorKind};
use ::common::session as Session;
// DAO
use ::dao::dao_manager::DAOManager;
// Models
use ::models::user_model::{OutUserModel};
use ::models::money_map_model::{MoneyMapModel, MoneyMapUserModel};

#[derive(Clone)]
pub struct MoneyMapsController{
    dao_manager: DAOManager,
    config: Config
}

impl MoneyMapsController{

    pub fn new(dao_manager: DAOManager, config: Config) -> MoneyMapsController{
        MoneyMapsController{
            dao_manager: dao_manager,
            config: config
        }
    }

    /// Find All Money Maps belonging to the requesting user
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<Vec<MoneyMapModel>>` - ApiResult including a vector of money maps
    pub fn find(&self, req: &mut Request<ServerData>) -> ApiResult<Vec<MoneyMapModel>>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                //Get list of money maps for this user
                let mut money_maps = dao.find(Some(doc!{
                    "users.user_id" => user_id,
                    "deleted" => {
                        "$ne" => true
                    }
                }));

                // Get list of user details for each money map
                for i in 0..money_maps.len(){
                    match self.get_users_for_mm(&money_maps[i]){
                        Ok(users_list) => {
                            // Add the new list of user details to the money map
                            money_maps[i].set_users(Some(users_list));
                        },
                        Err(e) => {
                            return ApiResult::Failure{msg:e.get_message()};
                        }
                    }
                }

                // Return the list of money maps
                ApiResult::Success{result:money_maps}
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end find_all

    /// Create Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the create money map
    pub fn create(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        match req.json_as::<MoneyMapModel>(){
                            Ok(mut money_map) => {
                                // Validate
                                let validation_result = money_map.validate();
                                if validation_result.is_valid(){
                                    // Save User
                                    match dao.create(&money_map, user_id.clone()){
                                        Ok(result) => {
                                            // Set user ID
                                            match result.inserted_id{
                                                Some(id_wrapper) => {
                                                    match id_wrapper{
                                                        Bson::ObjectId(id) => money_map.set_id(id),
                                                        _ => {}
                                                    }
                                                },
                                                None => {}
                                            }
                                            // Add user details
                                            if let Ok(id) = ObjectId::with_string(user_id.as_str()){
                                                if let Some(user) = user_dao.find_one(Some(doc!{"_id" => id}), None){
                                                    money_map.set_users(Some(
                                                        vec![
                                                            MoneyMapUserModel::new(OutUserModel::new(user), true)
                                                        ]
                                                    ));
                                                }
                                            }

                                            ApiResult::Success{result:money_map}
                                        },
                                        Err(e) => {
                                            error!("{}",e);
                                            ApiResult::Failure{msg:"Unable to create money map"}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:money_map}
                                }
                            },
                            Err(e) => {
                                error!("{}",e);
                                ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                            }
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        ApiResult::Failure{msg:"Unable to interact with database"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end create

    /// Modify Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the modified user
    pub fn modify(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {

                match req.json_as::<MoneyMapModel>(){
                    Ok(edit_money_map) => {
                        // Get Money Map
                        if let Some(mm_id) = edit_money_map.get_id(){
                            let filter = doc!{
                                "_id" => mm_id,
                                "users.user_id" => user_id
                            };

                            if let Some(money_map) = dao.find_one(Some(filter), None){

                                // Validate
                                let validation_result = edit_money_map.validate();
                                if validation_result.is_valid(){
                                    // Save
                                    match dao.update(&edit_money_map){
                                        Ok(mut updated_mm) => {
                                            match self.get_users_for_mm(&updated_mm){
                                                Ok(users_list) => {
                                                    // Add the new list of user details to the money map
                                                    updated_mm.set_users(Some(users_list));
                                                    ApiResult::Success{result:updated_mm}
                                                },
                                                Err(e) => {
                                                    ApiResult::Success{result:updated_mm}
                                                }
                                            }
                                        },
                                        Err(e) => {
                                            ApiResult::Failure{msg:e.get_message()}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:edit_money_map}
                                }

                            }else{
                                ApiResult::Failure{msg:"Unable to find Money Map"}
                            }
                        }else{
                            ApiResult::Failure{msg:"Invalid Money Map ID"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end modify

    /// Delete a Money Map
    ///
    /// # Arguments
    /// &self
    /// id - String
    ///
    /// # Returns
    /// `ApiResult<String>` - ApiResult
    pub fn delete(&self, id: &str) -> ApiResult<String>{
        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match dao.delete(id){
                    Ok(result) => {
                        if result.acknowledged && result.modified_count > 0 {
                            ApiResult::Success{result:"Successfully deleted money map".to_string()}
                        }else{
                            ApiResult::Failure{msg:"Unable to delete money map"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Malformed ID"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end delete

    fn get_users_for_mm(&self, money_map: &MoneyMapModel) -> MMResult<Vec<MoneyMapUserModel>>{
        // Initialze a list of user details for this money map
        let mut users_list = Vec::new();
        if let Some(mm_users) = money_map.get_users(){

            // For each user associated with this money map
            for mm_user in mm_users{
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        // Fetch the user's details
                        let user_id = Bson::ObjectId(mm_user.user.unwrap().id.unwrap());
                        let found_user = user_dao.find_one(Some(doc!{
                            "_id" => user_id
                        }), None);
                        if let Some(user) = found_user{
                            // Add the user details to the list
                            users_list.push(
                                MoneyMapUserModel::new(OutUserModel::new(user), mm_user.owner)
                            );
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        return Err(MMError::new("Unable to interact with database", MMErrorKind::Controller));
                    }
                }
            }
        }
        Ok(users_list)
    }
}
<|endoftext|>


<commit_before>#![allow(unused_variables, dead_code)]
#[macro_use]
extern crate r2pipe;
extern crate docopt;
extern crate rustc_serialize;
extern crate radeco_lib;

mod radeco;
mod structs;
mod errors;

use rustc_serialize::json;
use docopt::Docopt;
use std::process::exit;
use std::fs::{File};
use std::io::{Write, Read};

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
	flag_output: String,
	flag_version: bool,
	flag_verbose: bool,
	flag_shell: bool,
	flag_help: bool,
	arg_file: Option<String>,
	flag_from_json: bool,
	flag_build_json: bool,
	cmd_run: bool,
}

static USAGE: &'static str = "
radeco. The radare2 decompiler.

Usage:
  radeco <file>
  radeco [options] [<file>]
  radeco run [options] [<file>]
  radeco --shell <file>
  radeco --output=<output> <file>
  radeco --version
  radeco --verbose

Options:
  --help                 Show this screen.
  --version              Show version.
  --verbose              Display verbose output.
  --shell                Run interactive prompt.
  --output=<mode>        Select output mode.
  --from-json            Run radeco based on config and information
                         from input json file. Needs an input file.
  --build-json           Interactive wizard to build the JSON config
                         file needed for radeco. When used with run, the
                         config generated is automatically used to
                         run radeco rather than dumping it to a file.
";

fn spawn_shell(bname: String) -> i32 {
	radeco::spawn_shell(bname)
}

//fn radeco_pipe(args:&Args) -> i32 {
	//let mut r = Radeco::pipe().unwrap();
	//if args.flag_shell {
		//r.shell();
	//} else {
		//println!("Running radeco via pipe");
		//// TODO get offset, function, bin info, ..
	//}
	//r.close();
	//0
//}

fn write_file(fname: String, res: String) {
	let mut file = File::create(fname).unwrap();
	file.write_all(res.as_bytes()).unwrap();
}

fn build_json(run: bool) {
	let inp = structs::input_builder();
	let mut runner = inp.validate().unwrap();
	if !run {
		let mut name = inp.name.clone().unwrap();
		let json = json::as_pretty_json(&inp);
		let raw_json = format!("{}", json);
		name.push_str(".json");
		write_file(name, raw_json);
	} else {
		runner.run();
		runner.dump();
	}
}

fn read_json(fname: String) -> Result<structs::Input, errors::ReadErr> {
    let mut fh = try!(File::open(fname));
    let mut raw_json = String::new();
    try!(fh.read_to_string(&mut raw_json));
    json::decode(&*raw_json).map_err(|x| errors::ReadErr::DecodeErr(x))
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

	if args.flag_version {
		println!("Version: {:?}", VERSION);
		exit(0);
	}

	if args.flag_help {
		println!("{}", USAGE);
		exit(0);
	}

	//if args.arg_file != "" {
		//if args.arg_file == "-" {
			//exit(radeco_pipe(&args));
		//} else {
			//exit(radeco_file(&args));
		//}
	//}

	if args.flag_build_json {
		build_json(args.cmd_run);
	}

	if args.flag_from_json {
		if args.arg_file.is_none() {
			println!("{}", USAGE);
		}
		let r = read_json(args.arg_file.clone().unwrap());
		if let Ok(inp) =  r {
			let mut runner = inp.validate().unwrap();
			runner.run();
			runner.dump();
		} else {
			println!("[x] {}", r.err().unwrap())
		}
	}

	if args.flag_shell {
		if args.arg_file.is_none() {
			println!("{}", USAGE);
			exit(0);
		}
		let status = spawn_shell(args.arg_file.clone().unwrap());
		exit(status);
	}
}
<commit_msg>Better commandline parsing<commit_after>#![allow(unused_variables, dead_code)]
#[macro_use]
extern crate r2pipe;
extern crate docopt;
extern crate rustc_serialize;
extern crate radeco_lib;

mod radeco;
mod structs;
mod errors;

//use self::radeco::Radeco;
use self::r2pipe::R2Pipe;
use rustc_serialize::json;
use docopt::Docopt;
use std::process::exit;
use std::fs::{File};
use std::io::{Write, Read};

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_output: Option<String>,
    flag_version: bool,
    flag_address: String,
    flag_verbose: bool,
    flag_shell: bool,
    flag_help: bool,
    arg_file: Option<String>,
    flag_config: bool,
    flag_make_config: bool,
    cmd_run: bool,
}

static USAGE: &'static str = "
radeco. The radare2 decompiler.

Usage:
  radeco <file>
  radeco [options] [<file>]
  radeco run [options] [<file>]
  radeco --shell <file>
  radeco --output=<output> <file>
  radeco --version
  radeco --verbose

Options:
  --config <file>        Run decompilation using json rules file.
  --make-config <file>   Wizard to make the JSON config.
  -a --address=<addr>    Address of function to decompile.
  -e --esil=<expr>       Evaluate given esil expression.
  -o --output=<mode>     Output mode (c, ssa, json, r2, r2g, dot).
  --verbose              Display verbose output.
  --shell                Run interactive prompt.
  --version              Show version.
  --help                 Show this screen.
";

fn spawn_shell(bname: String) -> i32 {
    radeco::spawn_shell(bname)
}

//fn radeco_pipe(args:&Args) -> i32 {
//let mut r = Radeco::pipe().unwrap();
//if args.flag_shell {
//r.shell();
//} else {
//println!("Running radeco via pipe");
//// TODO get offset, function, bin info, ..
//}
//r.close();
//0
//}

fn write_file(fname: String, res: String) {
    let mut file = File::create(fname).unwrap();
    file.write_all(res.as_bytes()).unwrap();
}

fn make_config(run: bool) {
    let inp = structs::input_builder();
    let mut runner = inp.validate().unwrap();
    if !run {
        let mut name = inp.name.clone().unwrap();
        let json = json::as_pretty_json(&inp);
        let raw_json = format!("{}", json);
        name.push_str(".json");
        write_file(name, raw_json);
    } else {
        runner.run();
        runner.dump();
    }
}

fn json_slurp(fname: String) -> Result<structs::Input, errors::ReadErr> {
    let mut fh = try!(File::open(fname));
    let mut raw_json = String::new();
    try!(fh.read_to_string(&mut raw_json));
    json::decode(&*raw_json).map_err(|x| errors::ReadErr::DecodeErr(x))
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("Version: {:?}", VERSION);
        exit(0);
    }

    if args.flag_help {
        println!("{}", USAGE);
        exit(0);
    }

    let mut outmode: String = "c".to_string();
    let mut address: String = "entry0".to_string();

    if args.flag_output.is_some() {
        let flag_output = args.flag_output.clone().unwrap();
        if match &*flag_output {
            "c"|"C"|"r2"|"dot"|"r2g"|"json"|"ssa" => true,
            _ => false,
        } {
            println!("--> output mode is ok");
            outmode = flag_output;
        } else {
            println!("Invalid mode for --output=<mode>");
            exit(1);
        }
    }

    if args.flag_address != "" {
        address = args.flag_address;
    }

    if args.flag_make_config {
        make_config(args.cmd_run);
        exit(0);
    }

    if args.flag_config {
        if args.arg_file.is_none() {
            println!("{}", USAGE);
        }
        let filename = args.arg_file.clone().unwrap();
        let r = json_slurp(filename);
        if let Ok(inp) =  r {
            let mut runner = inp.validate().unwrap();
            runner.run();
            runner.dump();
        } else {
            println!("[x] {}", r.err().unwrap())
        }
        exit(0);
    }

    if args.flag_shell {
        if args.arg_file.is_none() {
            println!("{}", USAGE);
            exit(0);
        }
        let file = args.arg_file.clone().unwrap();
        exit(spawn_shell(file));
    }

    /* perform batch decompilation */
    if let Some (file) = args.arg_file.clone() {
        if let Ok(r2p) = R2Pipe::spawn(&*file) {
            println!("OK");
        } else {
            // XXX: r2pipe doesnt returns fail if the target file doesnt exist or r2 fails to run
            println!("Cannot find file");
        }
    } else {
        if let Ok(mut r2p) = R2Pipe::open() {
            println!("Running from r2");
            println!("--> address {}", address);
            println!("--> output {}", outmode);
            r2p.cmd (&*format!("s {}", address));
            //r2p.cmd ("af");
            let res = r2p.cmd("pd");
            println!("--> {}", res);

            //let mut r = Radeco::pipe().unwrap();
            //r.close();
            /* perform decompilation of function at current offset */
            //if args.arg_file != "" {
            //  if args.arg_file == "-" {
            //      exit(
            //  } else {
            //      exit(radeco_file(&args));
            //  }
            //}
            // XXX it hangs here, r2pipe looks buggy
            r2p.close();
        } else {
            if args.flag_output.is_some() {
                println!("Missing file");
            } else {
                println!("{}", USAGE);
            }
            exit(1);
        }
    }
}
<|endoftext|>


<commit_before>#![deny(
    absolute_paths_not_starting_with_crate,
    ambiguous_associated_items,
    anonymous_parameters,
    arithmetic_overflow,
    array_into_iter,
    asm_sub_register,
    bindings_with_variant_name,
    broken_intra_doc_links,
    cenum_impl_drop_cast,
    clashing_extern_declarations,
    coherence_leak_check,
    conflicting_repr_hints,
    confusable_idents,
    const_err,
    const_evaluatable_unchecked,
    const_item_mutation,
    dead_code,
    deprecated,
    deprecated_in_future,
    drop_bounds,
    ellipsis_inclusive_range_patterns,
    explicit_outlives_requirements,
    exported_private_dependencies,
    function_item_references,
    ill_formed_attribute_input,
    illegal_floating_point_literal_pattern,
    improper_ctypes,
    improper_ctypes_definitions,
    incomplete_features,
    incomplete_include,
    indirect_structural_match,
    inline_no_sanitize,
    invalid_codeblock_attributes,
    invalid_type_param_default,
    invalid_value,
    irrefutable_let_patterns,
    keyword_idents,
    late_bound_lifetime_arguments,
    macro_expanded_macro_exports_accessed_by_absolute_paths,
    meta_variable_misuse,
    missing_copy_implementations,
    missing_crate_level_docs,
    missing_docs,
    mixed_script_confusables,
    mutable_borrow_reservation_conflict,
    mutable_transmutes,
    no_mangle_const_items,
    no_mangle_generic_items,
    non_ascii_idents,
    non_camel_case_types,
    non_shorthand_field_patterns,
    non_snake_case,
    non_upper_case_globals,
    nontrivial_structural_match,
    order_dependent_trait_objects,
    overflowing_literals,
    overlapping_patterns,
    path_statements,
    patterns_in_fns_without_body,
    pointer_structural_match,
    private_doc_tests,
    private_in_public,
    proc_macro_derive_resolution_fallback,
    pub_use_of_private_extern_crate,
    redundant_semicolons,
    safe_packed_borrows,
    soft_unstable,
    stable_features,
    temporary_cstring_as_ptr,
    trivial_bounds,
    trivial_casts,
    trivial_numeric_casts,
    type_alias_bounds,
    tyvar_behind_raw_pointer,
    unaligned_references,
    uncommon_codepoints,
    unconditional_panic,
    unconditional_recursion,
    uninhabited_static,
    unknown_crate_types,
    unnameable_test_items,
    unreachable_code,
    unreachable_patterns,
    unreachable_pub,
    unsafe_code,
    unstable_features,
    unstable_name_collisions,
    unused_allocation,
    unused_assignments,
    unused_attributes,
    unused_braces,
    unused_comparisons,
    unused_crate_dependencies,
    unused_doc_comments,
    unused_extern_crates,
    unused_features,
    unused_import_braces,
    unused_imports,
    unused_labels,
    unused_lifetimes,
    unused_macros,
    unused_must_use,
    unused_mut,
    unused_parens,
    unused_qualifications,
    unused_unsafe,
    unused_variables,
    where_clauses_object_safety,
    while_true
)]
#![warn(macro_use_extern_crate, unknown_lints)]
#![allow(
    bare_trait_objects,
    box_pointers,
    elided_lifetimes_in_paths,
    invalid_html_tags,
    missing_doc_code_examples,
    missing_debug_implementations,
    single_use_lifetimes,
    unused_results,
    variant_size_differences,
    warnings,
    renamed_and_removed_lints
)]

//! # cargo-make
//!
//! Rust task runner and build tool.

//! The cargo-make task runner enables to define and configure sets of tasks and run them as a flow.

//! A task is a command or a script to execute.

//! Tasks can have dependencies which are also tasks that will be executed before the task itself.

//! With a simple toml based configuration file, you can define a multi platform build script that can run build, test,
//! documentation generation, bench tests execution, security validations and more by running a single command.
//!
//! ## Installation
//! In order to install, just run the following command
//!
//! ```sh
//! cargo install cargo-make
//! ```
//!
//! This will install cargo-make in your ~/.cargo/bin.

//! Make sure to add ~/.cargo/bin directory to your PATH variable.
//!
//! # Contributing
//! See [contributing guide](https://github.com/sagiegurari/cargo-make/blob/master/.github/CONTRIBUTING.md)
//!
//! # License
//! Developed by Sagie Gur-Ari and licensed under the
//! [Apache 2](https://github.com/sagiegurari/cargo-make/blob/master/LICENSE) open source license.
//!

#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;

#[cfg(test)]
mod test;

// make types public for docs
pub mod types;

mod cache;
mod cli;
mod cli_commands;
mod command;
mod condition;
mod config;
mod descriptor;
mod environment;
mod execution_plan;
mod functions;
mod installer;
mod io;
mod legacy;
mod logger;
mod profile;
mod proxy_task;
mod recursion_level;
mod runner;
mod scriptengine;
mod storage;
mod time_summary;
mod toolchain;
mod version;

/// Handles the command line arguments and executes the runner.
pub fn run_cli(command_name: String, sub_command: bool) {
    cli::run_cli(command_name, sub_command)
}
<commit_msg>Update lint rules<commit_after>#![deny(
    absolute_paths_not_starting_with_crate,
    ambiguous_associated_items,
    anonymous_parameters,
    arithmetic_overflow,
    array_into_iter,
    asm_sub_register,
    bindings_with_variant_name,
    broken_intra_doc_links,
    cenum_impl_drop_cast,
    clashing_extern_declarations,
    coherence_leak_check,
    conflicting_repr_hints,
    confusable_idents,
    const_err,
    const_evaluatable_unchecked,
    const_item_mutation,
    dead_code,
    deprecated,
    deprecated_in_future,
    drop_bounds,
    ellipsis_inclusive_range_patterns,
    explicit_outlives_requirements,
    exported_private_dependencies,
    function_item_references,
    ill_formed_attribute_input,
    illegal_floating_point_literal_pattern,
    improper_ctypes,
    improper_ctypes_definitions,
    incomplete_features,
    incomplete_include,
    indirect_structural_match,
    inline_no_sanitize,
    invalid_codeblock_attributes,
    invalid_type_param_default,
    invalid_value,
    irrefutable_let_patterns,
    keyword_idents,
    late_bound_lifetime_arguments,
    macro_expanded_macro_exports_accessed_by_absolute_paths,
    meta_variable_misuse,
    missing_abi,
    missing_copy_implementations,
    missing_crate_level_docs,
    missing_docs,
    missing_fragment_specifier,
    mixed_script_confusables,
    mutable_borrow_reservation_conflict,
    mutable_transmutes,
    no_mangle_const_items,
    no_mangle_generic_items,
    non_ascii_idents,
    non_autolinks,
    non_camel_case_types,
    non_shorthand_field_patterns,
    non_snake_case,
    non_upper_case_globals,
    nontrivial_structural_match,
    order_dependent_trait_objects,
    overflowing_literals,
    overlapping_range_endpoints,
    panic_fmt,
    path_statements,
    patterns_in_fns_without_body,
    pointer_structural_match,
    private_doc_tests,
    private_in_public,
    private_intra_doc_links,
    proc_macro_derive_resolution_fallback,
    pub_use_of_private_extern_crate,
    redundant_semicolons,
    safe_packed_borrows,
    soft_unstable,
    stable_features,
    temporary_cstring_as_ptr,
    trivial_bounds,
    trivial_casts,
    trivial_numeric_casts,
    type_alias_bounds,
    tyvar_behind_raw_pointer,
    unaligned_references,
    uncommon_codepoints,
    unconditional_panic,
    unconditional_recursion,
    uninhabited_static,
    unknown_crate_types,
    unnameable_test_items,
    unreachable_code,
    unreachable_patterns,
    unreachable_pub,
    unsafe_code,
    unstable_features,
    unstable_name_collisions,
    unsupported_naked_functions,
    unused_allocation,
    unused_assignments,
    unused_attributes,
    unused_braces,
    unused_comparisons,
    unused_crate_dependencies,
    unused_doc_comments,
    unused_extern_crates,
    unused_features,
    unused_import_braces,
    unused_imports,
    unused_labels,
    unused_lifetimes,
    unused_macros,
    unused_must_use,
    unused_mut,
    unused_parens,
    unused_qualifications,
    unused_unsafe,
    unused_variables,
    useless_deprecated,
    where_clauses_object_safety,
    while_true
)]
#![warn(macro_use_extern_crate, unknown_lints)]
#![allow(
    bare_trait_objects,
    box_pointers,
    elided_lifetimes_in_paths,
    invalid_html_tags,
    missing_doc_code_examples,
    missing_debug_implementations,
    single_use_lifetimes,
    unused_results,
    variant_size_differences,
    warnings,
    renamed_and_removed_lints
)]

//! # cargo-make
//!
//! Rust task runner and build tool.

//! The cargo-make task runner enables to define and configure sets of tasks and run them as a flow.

//! A task is a command or a script to execute.

//! Tasks can have dependencies which are also tasks that will be executed before the task itself.

//! With a simple toml based configuration file, you can define a multi platform build script that can run build, test,
//! documentation generation, bench tests execution, security validations and more by running a single command.
//!
//! ## Installation
//! In order to install, just run the following command
//!
//! ```sh
//! cargo install cargo-make
//! ```
//!
//! This will install cargo-make in your ~/.cargo/bin.

//! Make sure to add ~/.cargo/bin directory to your PATH variable.
//!
//! # Contributing
//! See [contributing guide](https://github.com/sagiegurari/cargo-make/blob/master/.github/CONTRIBUTING.md)
//!
//! # License
//! Developed by Sagie Gur-Ari and licensed under the
//! [Apache 2](https://github.com/sagiegurari/cargo-make/blob/master/LICENSE) open source license.
//!

#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;

#[cfg(test)]
mod test;

// make types public for docs
pub mod types;

mod cache;
mod cli;
mod cli_commands;
mod command;
mod condition;
mod config;
mod descriptor;
mod environment;
mod execution_plan;
mod functions;
mod installer;
mod io;
mod legacy;
mod logger;
mod profile;
mod proxy_task;
mod recursion_level;
mod runner;
mod scriptengine;
mod storage;
mod time_summary;
mod toolchain;
mod version;

/// Handles the command line arguments and executes the runner.
pub fn run_cli(command_name: String, sub_command: bool) {
    cli::run_cli(command_name, sub_command)
}
<|endoftext|>