<commit_before>use super::{Key, Symbols, XkbFile, XkbKeySym};
use crate::{
    bundle::keys::KeyValue,
    models::{DesktopModes, Layout},
    utils::UnwrapOrUnknownExt,
};
use std::collections::BTreeMap;

impl XkbFile {
    pub fn from_layout(name: &str, layout: Layout) -> Result<Self, Error> {
        let mut modes = vec![
            layout.modes.x11.clone().map(|x| ("x11", x)),
            layout.modes.win.clone().map(|x| ("win", x)),
            layout.modes.mac.clone().map(|x| ("mac", x)),
            layout.modes.chrome.clone().map(|x| ("chrome", x)),
        ]
        .into_iter()
        .flatten();

        let default = modes
            .next()
            .map(|(target, mode)| {
                Ok(Symbols {
                    id: "basic".to_string(),
                    name: format!("{} ({})", layout.name().unwrap_or_unknown(), target),
                    leading_includes: vec!["latin".to_string()],
                    keys: collect_keys(&mode, None)?,
                    trailing_includes: vec!["level3(ralt_switch)".to_string()],
                })
            })
            .ok_or_else(|| Error::NoXkbCompatibleModes {
                available_modes: layout.modes.available_modes(),
            })??;

        let mut others = modes
            .map(|(target, mode)| {
                Ok(Symbols {
                    id: target.to_string(),
                    name: format!("{} ({})", layout.name().unwrap_or_unknown(), target),
                    leading_includes: vec![format!("{}(basic)", name)],
                    keys: collect_keys(&mode, Some(&default))?,
                    trailing_includes: vec!["level3(ralt_switch)".to_string()],
                })
            })
            .collect::<Result<Vec<Symbols>, Error>>()?;

        if let Some(dead_keys) = layout.dead_keys.as_ref() {
            for (target, mode_keys) in dead_keys {
                let parent =
                    match target.as_str() {
                        "x11" => layout.modes.x11.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        "win" => layout.modes.win.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        "mac" => layout.modes.mac.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        "chrome" => layout.modes.chrome.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        _ => continue,
                    };

                others.push(Symbols {
                    id: format!("{}_deadkeys", target.to_string()),
                    name: format!(
                        "{} ({}) (dead keys)",
                        layout.name().unwrap_or_unknown(),
                        target
                    ),
                    leading_includes: vec![format!("{}({})", name, target)],
                    keys: collect_dead_keys(&mode_keys, parent)?,
                    trailing_includes: vec![],
                });
            }
        }

        Ok(XkbFile { default, others })
    }
}

fn collect_keys(key_map: &DesktopModes, _default: Option<&Symbols>) -> Result<Vec<Key>, Error> {
    let default = key_map
        .get("default")
        .cloned()
        .ok_or(Error::NoDefaultKeyMap)?;
    let shift = key_map.get("shift").cloned().unwrap_or_default();
    let alt = key_map.get("alt").cloned().unwrap_or_default();
    let alt_shift = key_map.get("alt_shift").cloned().unwrap_or_default();

    let mut res = Vec::new();

    for (iso_code, default) in &*default {
        res.push(Key {
            iso_code: iso_code.to_string(),
            default: if let KeyValue::Symbol(s) = default {
                Some(XkbKeySym(s.to_owned()))
            } else {
                None
            },
            shift: shift.get_string(*iso_code).map(XkbKeySym),
            alt: alt.get_string(*iso_code).map(XkbKeySym),
            alt_shift: alt_shift.get_string(*iso_code).map(XkbKeySym),
        });
    }

    Ok(res)
}

fn collect_dead_keys(
    key_map: &BTreeMap<String, Vec<String>>,
    parent: &DesktopModes,
) -> Result<Vec<Key>, Error> {
    fn char_to_dead(c: &str) -> Option<char> {
        let c = c.chars().next().expect("keysym can't be empty");
        let original = x11_keysymdef::lookup_by_codepoint(c)?;
        let name = original.names.get(0)?;
        let dead = format!("dead_{}", name);
        if let Some(record) = x11_keysymdef::lookup_by_name(&dead) {
            Some(record.unicode)
        } else {
            None
        }
    }

    let default = parent
        .get("default")
        .cloned()
        .ok_or(Error::NoDefaultKeyMap)?;
    let shift = parent.get("shift").cloned().unwrap_or_default();
    let alt = parent.get("alt").cloned().unwrap_or_default();
    let alt_shift = parent.get("alt_shift").cloned().unwrap_or_default();

    let mut overwritten_keys = BTreeMap::new();

    for (mode, map) in key_map {
        let parent_key = parent
            .get(mode)
            .expect("dead keys only defined for know modes");
        for key in map {
            let (iso_code, value) = parent_key
                .iter()
                .find(|(_iso, value)| match value {
                    KeyValue::Symbol(value) => key == value,
                    _ => false,
                })
                .expect("dead key not in parent mode");
            let value = value.to_string();

            let mut key = overwritten_keys.entry(iso_code).or_insert_with(|| Key {
                iso_code: iso_code.to_string(),
                default: default.get_string(*iso_code).map(XkbKeySym),
                shift: shift.get_string(*iso_code).map(XkbKeySym),
                alt: alt.get_string(*iso_code).map(XkbKeySym),
                alt_shift: alt_shift.get_string(*iso_code).map(XkbKeySym),
            });
            let dead = char_to_dead(&value).map(|x| XkbKeySym(x.to_string()));
            let dead = if let Some(x) = dead {
                x
            } else {
                log::warn!(
                    "while generating XKB dead key block: `{}` cannot be turned into a dead key",
                    value
                );
                continue;
            };

            match mode.as_str() {
                "default" => key.default = Some(dead),
                "shift" => key.shift = Some(dead),
                "alt" => key.alt = Some(dead),
                "alt+shift" => key.alt_shift = Some(dead),
                _ => {}
            }
        }
    }

    Ok(overwritten_keys
        .into_iter()
        .map(|(_iso, val)| val)
        .collect())
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("No `default` keymap")]
    NoDefaultKeyMap,
    #[error("No XKB compatible modes, found: {}", available_modes.join(", "))]
    NoXkbCompatibleModes { available_modes: Vec<String> },
    #[error("Cannot set dead keys for unconfigured target `{}`", target)]
    DeadKeysForUnconfiguredTarget { target: String },
}
<commit_msg>Bugfixed missing alt+shift layer in XKB files<commit_after>use super::{Key, Symbols, XkbFile, XkbKeySym};
use crate::{
    bundle::keys::KeyValue,
    models::{DesktopModes, Layout},
    utils::UnwrapOrUnknownExt,
};
use std::collections::BTreeMap;

impl XkbFile {
    pub fn from_layout(name: &str, layout: Layout) -> Result<Self, Error> {
        let mut modes = vec![
            layout.modes.x11.clone().map(|x| ("x11", x)),
            layout.modes.win.clone().map(|x| ("win", x)),
            layout.modes.mac.clone().map(|x| ("mac", x)),
            layout.modes.chrome.clone().map(|x| ("chrome", x)),
        ]
        .into_iter()
        .flatten();

        let default = modes
            .next()
            .map(|(target, mode)| {
                Ok(Symbols {
                    id: "basic".to_string(),
                    name: format!("{} ({})", layout.name().unwrap_or_unknown(), target),
                    leading_includes: vec!["latin".to_string()],
                    keys: collect_keys(&mode, None)?,
                    trailing_includes: vec!["level3(ralt_switch)".to_string()],
                })
            })
            .ok_or_else(|| Error::NoXkbCompatibleModes {
                available_modes: layout.modes.available_modes(),
            })??;

        let mut others = modes
            .map(|(target, mode)| {
                Ok(Symbols {
                    id: target.to_string(),
                    name: format!("{} ({})", layout.name().unwrap_or_unknown(), target),
                    leading_includes: vec![format!("{}(basic)", name)],
                    keys: collect_keys(&mode, Some(&default))?,
                    trailing_includes: vec!["level3(ralt_switch)".to_string()],
                })
            })
            .collect::<Result<Vec<Symbols>, Error>>()?;

        if let Some(dead_keys) = layout.dead_keys.as_ref() {
            for (target, mode_keys) in dead_keys {
                let parent =
                    match target.as_str() {
                        "x11" => layout.modes.x11.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        "win" => layout.modes.win.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        "mac" => layout.modes.mac.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        "chrome" => layout.modes.chrome.as_ref().ok_or(
                            Error::DeadKeysForUnconfiguredTarget {
                                target: target.clone(),
                            },
                        )?,
                        _ => continue,
                    };

                others.push(Symbols {
                    id: format!("{}_deadkeys", target.to_string()),
                    name: format!(
                        "{} ({}) (dead keys)",
                        layout.name().unwrap_or_unknown(),
                        target
                    ),
                    leading_includes: vec![format!("{}({})", name, target)],
                    keys: collect_dead_keys(&mode_keys, parent)?,
                    trailing_includes: vec![],
                });
            }
        }

        Ok(XkbFile { default, others })
    }
}

fn collect_keys(key_map: &DesktopModes, _default: Option<&Symbols>) -> Result<Vec<Key>, Error> {
    let default = key_map
        .get("default")
        .cloned()
        .ok_or(Error::NoDefaultKeyMap)?;
    let shift = key_map.get("shift").cloned().unwrap_or_default();
    let alt = key_map.get("alt").cloned().unwrap_or_default();
    let alt_shift = key_map.get("alt+shift").cloned().unwrap_or_default();

    let mut res = Vec::new();

    for (iso_code, default) in &*default {
        res.push(Key {
            iso_code: iso_code.to_string(),
            default: if let KeyValue::Symbol(s) = default {
                Some(XkbKeySym(s.to_owned()))
            } else {
                None
            },
            shift: shift.get_string(*iso_code).map(XkbKeySym),
            alt: alt.get_string(*iso_code).map(XkbKeySym),
            alt_shift: alt_shift.get_string(*iso_code).map(XkbKeySym),
        });
    }

    Ok(res)
}

fn collect_dead_keys(
    key_map: &BTreeMap<String, Vec<String>>,
    parent: &DesktopModes,
) -> Result<Vec<Key>, Error> {
    fn char_to_dead(c: &str) -> Option<char> {
        let c = c.chars().next().expect("keysym can't be empty");
        let original = x11_keysymdef::lookup_by_codepoint(c)?;
        let name = original.names.get(0)?;
        let dead = format!("dead_{}", name);
        if let Some(record) = x11_keysymdef::lookup_by_name(&dead) {
            Some(record.unicode)
        } else {
            None
        }
    }

    let default = parent
        .get("default")
        .cloned()
        .ok_or(Error::NoDefaultKeyMap)?;
    let shift = parent.get("shift").cloned().unwrap_or_default();
    let alt = parent.get("alt").cloned().unwrap_or_default();
    let alt_shift = parent.get("alt_shift").cloned().unwrap_or_default();

    let mut overwritten_keys = BTreeMap::new();

    for (mode, map) in key_map {
        let parent_key = parent
            .get(mode)
            .expect("dead keys only defined for know modes");
        for key in map {
            let (iso_code, value) = parent_key
                .iter()
                .find(|(_iso, value)| match value {
                    KeyValue::Symbol(value) => key == value,
                    _ => false,
                })
                .expect("dead key not in parent mode");
            let value = value.to_string();

            let mut key = overwritten_keys.entry(iso_code).or_insert_with(|| Key {
                iso_code: iso_code.to_string(),
                default: default.get_string(*iso_code).map(XkbKeySym),
                shift: shift.get_string(*iso_code).map(XkbKeySym),
                alt: alt.get_string(*iso_code).map(XkbKeySym),
                alt_shift: alt_shift.get_string(*iso_code).map(XkbKeySym),
            });
            let dead = char_to_dead(&value).map(|x| XkbKeySym(x.to_string()));
            let dead = if let Some(x) = dead {
                x
            } else {
                log::warn!(
                    "while generating XKB dead key block: `{}` cannot be turned into a dead key",
                    value
                );
                continue;
            };

            match mode.as_str() {
                "default" => key.default = Some(dead),
                "shift" => key.shift = Some(dead),
                "alt" => key.alt = Some(dead),
                "alt+shift" => key.alt_shift = Some(dead),
                _ => {}
            }
        }
    }

    Ok(overwritten_keys
        .into_iter()
        .map(|(_iso, val)| val)
        .collect())
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("No `default` keymap")]
    NoDefaultKeyMap,
    #[error("No XKB compatible modes, found: {}", available_modes.join(", "))]
    NoXkbCompatibleModes { available_modes: Vec<String> },
    #[error("Cannot set dead keys for unconfigured target `{}`", target)]
    DeadKeysForUnconfiguredTarget { target: String },
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::net::SocketAddr;
use std::collections::HashMap;
use rand::random;
use mio::net::TcpStream;

use network::{AppId,Backend,ConnectionError};

pub struct BackendMap {
  pub instances: HashMap<AppId, Vec<Rc<RefCell<Backend>>>>,
}

impl BackendMap {
  pub fn new() -> BackendMap {
    BackendMap {
      instances: HashMap::new(),
    }
  }

  pub fn add_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    if let Some(addrs) = self.instances.get_mut(app_id) {
      let id = addrs.last().map(|b| (*b.borrow_mut()).id ).unwrap_or(0) + 1;
      let backend = Rc::new(RefCell::new(Backend::new(*instance_address, id)));
      if !addrs.contains(&backend) {
        addrs.push(backend);
      }
    }

    if self.instances.get(app_id).is_none() {
      let backend = Backend::new(*instance_address, 0);
      self.instances.insert(String::from(app_id), vec![Rc::new(RefCell::new(backend))]);
    }
  }

  pub fn remove_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    if let Some(instances) = self.instances.get_mut(app_id) {
      instances.retain(|backend| &(*backend.borrow()).address != instance_address);
    } else {
      error!("Instance was already removed");
    }
  }

  pub fn close_backend_connection(&mut self, app_id: &str, addr: &SocketAddr) {
    if let Some(app_instances) = self.instances.get_mut(app_id) {
      if let Some(ref mut backend) = app_instances.iter_mut().find(|backend| &(*backend.borrow()).address == addr) {
        (*backend.borrow_mut()).dec_connections();
      }
    }
  }

  pub fn backend_from_app_id(&mut self, app_id: &str) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    if let Some(ref mut app_instances) = self.instances.get_mut(app_id) {
      if app_instances.len() == 0 {
        return Err(ConnectionError::NoBackendAvailable);
      }

      //FIXME: hardcoded for now, these should come from configuration
      let max_failures_per_backend:usize = 10;
      let max_failures:usize             = 3;

      for _ in 0..max_failures {
        //FIXME: it's probably pretty wasteful to refilter every time here
        let mut instances:Vec<&mut Rc<RefCell<Backend>>> = app_instances.iter_mut().filter(|backend| (*backend.borrow()).can_open(max_failures_per_backend)).collect();
        if instances.is_empty() {
          error!("no more available backends for app {}", app_id);
          return Err(ConnectionError::NoBackendAvailable);
        }
        let rnd = random::<usize>();
        let idx = rnd % instances.len();

        let conn = instances.get_mut(idx).ok_or(ConnectionError::NoBackendAvailable).and_then(|ref mut b| {
          let ref mut backend = *b.borrow_mut();
          //info!("{}\tConnecting {} -> {:?}", client.http().map(|h| h.log_ctx.clone()).unwrap_or("".to_string()), app_id, (backend.address, backend.active_connections, backend.failures));
          let conn = backend.try_connect(max_failures_per_backend);
          if backend.failures >= max_failures_per_backend {
            //error!("{}\tbackend {:?} connections failed {} times, disabling it", client.http().map(|h| h.log_ctx.clone()).unwrap_or("".to_string()), (backend.address, backend.active_connections), backend.failures);
          }

          conn.map(|c| (b.clone(), c))
        });

        if conn.is_ok() {
          return conn;
        }
      }
      Err(ConnectionError::NoBackendAvailable)
    } else {
      Err(ConnectionError::NoBackendAvailable)
    }
  }

  pub fn backend_from_sticky_session(&mut self, app_id: &str, sticky_session: u32) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    let max_failures_per_backend = 10;
    if let Some(ref mut app_instances) = self.instances.get_mut(app_id) {
      let sticky_backend: Option<&mut Rc<RefCell<Backend>>> = app_instances.iter_mut().find(|b| {
        let backend = &*b.borrow();
        backend.id == sticky_session && backend.can_open(max_failures_per_backend)
      });

      if let Some(b) = sticky_backend {
        //FIXME: hardcoded for now, these should come from configuration
        let ref mut backend = *b.borrow_mut();
        let conn = backend.try_connect(max_failures_per_backend);
        //info!("{}\tConnecting {} -> {:?} using session {}", client.http().map(|h| h.log_ctx.clone()).unwrap_or("".to_string()), app_id, (backend.address, backend.active_connections, backend.failures), sticky_session);
        if backend.failures >= max_failures_per_backend {
          //error!("{}\tbackend {:?} connections failed {} times, disabling it", client.http().map(|h| h.log_ctx.clone()).unwrap_or("".to_string()), (backend.address, backend.active_connections), backend.failures);
        }

        return conn.map(|c| (b.clone(), c));
      }
    }

    debug!("Couldn't find a backend corresponding to sticky_session {} for app {}", sticky_session, app_id);
    Err(ConnectionError::NoBackendAvailable)
  }
}
<commit_msg>reactivate some logs<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::net::SocketAddr;
use std::collections::HashMap;
use rand::random;
use mio::net::TcpStream;

use network::{AppId,Backend,ConnectionError};

pub struct BackendMap {
  pub instances: HashMap<AppId, Vec<Rc<RefCell<Backend>>>>,
}

impl BackendMap {
  pub fn new() -> BackendMap {
    BackendMap {
      instances: HashMap::new(),
    }
  }

  pub fn add_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    if let Some(addrs) = self.instances.get_mut(app_id) {
      let id = addrs.last().map(|b| (*b.borrow_mut()).id ).unwrap_or(0) + 1;
      let backend = Rc::new(RefCell::new(Backend::new(*instance_address, id)));
      if !addrs.contains(&backend) {
        addrs.push(backend);
      }
    }

    if self.instances.get(app_id).is_none() {
      let backend = Backend::new(*instance_address, 0);
      self.instances.insert(String::from(app_id), vec![Rc::new(RefCell::new(backend))]);
    }
  }

  pub fn remove_instance(&mut self, app_id: &str, instance_address: &SocketAddr) {
    if let Some(instances) = self.instances.get_mut(app_id) {
      instances.retain(|backend| &(*backend.borrow()).address != instance_address);
    } else {
      error!("Instance was already removed");
    }
  }

  pub fn close_backend_connection(&mut self, app_id: &str, addr: &SocketAddr) {
    if let Some(app_instances) = self.instances.get_mut(app_id) {
      if let Some(ref mut backend) = app_instances.iter_mut().find(|backend| &(*backend.borrow()).address == addr) {
        (*backend.borrow_mut()).dec_connections();
      }
    }
  }

  pub fn backend_from_app_id(&mut self, app_id: &str) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    if let Some(ref mut app_instances) = self.instances.get_mut(app_id) {
      if app_instances.len() == 0 {
        return Err(ConnectionError::NoBackendAvailable);
      }

      //FIXME: hardcoded for now, these should come from configuration
      let max_failures_per_backend:usize = 10;
      let max_failures:usize             = 3;

      for _ in 0..max_failures {
        //FIXME: it's probably pretty wasteful to refilter every time here
        let mut instances:Vec<&mut Rc<RefCell<Backend>>> = app_instances.iter_mut().filter(|backend| (*backend.borrow()).can_open(max_failures_per_backend)).collect();
        if instances.is_empty() {
          error!("no more available backends for app {}", app_id);
          return Err(ConnectionError::NoBackendAvailable);
        }
        let rnd = random::<usize>();
        let idx = rnd % instances.len();

        let conn = instances.get_mut(idx).ok_or(ConnectionError::NoBackendAvailable).and_then(|ref mut b| {
          let ref mut backend = *b.borrow_mut();
          info!("Connecting {} -> {:?}", app_id, (backend.address, backend.active_connections, backend.failures));
          let conn = backend.try_connect(max_failures_per_backend);
          if backend.failures >= max_failures_per_backend {
            error!("backend {:?} connections failed {} times, disabling it", (backend.address, backend.active_connections), backend.failures);
          }

          conn.map(|c| (b.clone(), c))
        });

        if conn.is_ok() {
          return conn;
        }
      }
      Err(ConnectionError::NoBackendAvailable)
    } else {
      Err(ConnectionError::NoBackendAvailable)
    }
  }

  pub fn backend_from_sticky_session(&mut self, app_id: &str, sticky_session: u32) -> Result<(Rc<RefCell<Backend>>,TcpStream),ConnectionError> {
    let max_failures_per_backend = 10;
    if let Some(ref mut app_instances) = self.instances.get_mut(app_id) {
      let sticky_backend: Option<&mut Rc<RefCell<Backend>>> = app_instances.iter_mut().find(|b| {
        let backend = &*b.borrow();
        backend.id == sticky_session && backend.can_open(max_failures_per_backend)
      });

      if let Some(b) = sticky_backend {
        //FIXME: hardcoded for now, these should come from configuration
        let ref mut backend = *b.borrow_mut();
        let conn = backend.try_connect(max_failures_per_backend);
        info!("Connecting {} -> {:?} using session {}", app_id, (backend.address, backend.active_connections, backend.failures), sticky_session);
        if backend.failures >= max_failures_per_backend {
          error!("backend {:?} connections failed {} times, disabling it", (backend.address, backend.active_connections), backend.failures);
        }

        return conn.map(|c| (b.clone(), c));
      }
    }

    debug!("Couldn't find a backend corresponding to sticky_session {} for app {}", sticky_session, app_id);
    Err(ConnectionError::NoBackendAvailable)
  }
}
<|endoftext|>


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

use clap::{Arg, ArgGroup, App, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
    app
        .subcommand(SubCommand::with_name("internal")
                    .about("Add, remove and list internal links")
                    .version("0.1")
                    .subcommand(SubCommand::with_name("add")
                                .about("Add link from one entry to another (and vice-versa)")
                                .version("0.1")
                                .arg(Arg::with_name("from")
                                     .long("from")
                                     .short("f")
                                     .takes_value(true)
                                     .required(true)
                                     .help("Link from this entry")
                                     .value_name("ENTRY"))
                                .arg(Arg::with_name("to")
                                     .long("to")
                                     .short("t")
                                     .takes_value(true)
                                     .required(true)
                                     .multiple(true)
                                     .help("Link to this entries")
                                     .value_name("ENTRIES"))
                                )

                    .subcommand(SubCommand::with_name("remove")
                            .about("Remove a link between two or more entries")
                            .version("0.1")
                            .arg(Arg::with_name("from")
                                 .long("from")
                                 .short("f")
                                 .takes_value(true)
                                 .required(true)
                                 .help("Remove Link from this entry")
                                 .value_name("ENTRY"))
                            .arg(Arg::with_name("to")
                                 .long("to")
                                 .short("t")
                                 .takes_value(true)
                                 .required(true)
                                 .multiple(true)
                                 .help("Remove links to these entries")
                                 .value_name("ENTRIES"))
                            )

                    .arg(Arg::with_name("list")
                         .long("list")
                         .short("l")
                         .takes_value(true)
                         .required(false)
                         .help("List links to this entry")
                         .value_name("ENTRY"))
                    )
        .subcommand(SubCommand::with_name("external")
                    .about("Add and remove external links")
                    .version("0.1")

                    .arg(Arg::with_name("id")
                         .long("id")
                         .short("i")
                         .takes_value(true)
                         .required(true)
                         .help("Modify external link of this entry")
                         .value_name("ENTRY"))

                    .arg(Arg::with_name("add")
                         .long("add")
                         .short("a")
                         .takes_value(true)
                         .required(false)
                         .help("Add this URI as external link")
                         .value_name("URI"))

                    .arg(Arg::with_name("remove")
                         .long("remove")
                         .short("r")
                         .takes_value(false)
                         .required(false)
                         .help("Remove one external link"))

                    .arg(Arg::with_name("set")
                         .long("set")
                         .short("s")
                         .takes_value(true)
                         .required(false)
                         .help("Set these URIs as external link (seperate by comma)")
                         .value_name("URIs"))

                    .arg(Arg::with_name("list")
                         .long("list")
                         .short("l")
                         .takes_value(false)
                         .required(false)
                         .help("List external links"))

                    .group(ArgGroup::with_name("external-link-group")
                           .args(&["add", "remove", "set", "list"])
                           .required(true))

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

use clap::{Arg, ArgGroup, App, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
    app
        .subcommand(SubCommand::with_name("internal")
                    .about("Add, remove and list internal links")
                    .version("0.1")
                    .subcommand(SubCommand::with_name("add")
                                .about("Add link from one entry to another (and vice-versa)")
                                .version("0.1")
                                .arg(Arg::with_name("from")
                                     .long("from")
                                     .short("f")
                                     .takes_value(true)
                                     .required(true)
                                     .help("Link from this entry")
                                     .value_name("ENTRY"))
                                .arg(Arg::with_name("to")
                                     .long("to")
                                     .short("t")
                                     .takes_value(true)
                                     .required(true)
                                     .multiple(true)
                                     .help("Link to this entries")
                                     .value_name("ENTRIES"))
                                )

                    .subcommand(SubCommand::with_name("remove")
                            .about("Remove a link between two or more entries")
                            .version("0.1")
                            .arg(Arg::with_name("from")
                                 .long("from")
                                 .short("f")
                                 .takes_value(true)
                                 .required(true)
                                 .help("Remove Link from this entry")
                                 .value_name("ENTRY"))
                            .arg(Arg::with_name("to")
                                 .long("to")
                                 .short("t")
                                 .takes_value(true)
                                 .required(true)
                                 .multiple(true)
                                 .help("Remove links to these entries")
                                 .value_name("ENTRIES"))
                            )

                    .arg(Arg::with_name("list")
                         .long("list")
                         .short("l")
                         .takes_value(true)
                         .required(false)
                         .help("List links to this entry")
                         .value_name("ENTRY"))
                    )
        .subcommand(SubCommand::with_name("external")
                    .about("Add and remove external links")
                    .version("0.1")

                    .arg(Arg::with_name("id")
                         .long("id")
                         .short("i")
                         .takes_value(true)
                         .required(true)
                         .help("Modify external link of this entry")
                         .value_name("ENTRY"))

                    .arg(Arg::with_name("add")
                         .long("add")
                         .short("a")
                         .takes_value(true)
                         .required(false)
                         .help("Add this URI as external link")
                         .value_name("URI"))

                    .arg(Arg::with_name("remove")
                         .long("remove")
                         .short("r")
                         .takes_value(true)
                         .required(true)
                         .help("Remove one external link"))

                    .arg(Arg::with_name("set")
                         .long("set")
                         .short("s")
                         .takes_value(true)
                         .required(false)
                         .help("Set these URIs as external link (seperate by comma)")
                         .value_name("URIs"))

                    .arg(Arg::with_name("list")
                         .long("list")
                         .short("l")
                         .takes_value(false)
                         .required(false)
                         .help("List external links"))

                    .group(ArgGroup::with_name("external-link-group")
                           .args(&["add", "remove", "set", "list"])
                           .required(true))

                    )
}
<|endoftext|>


<commit_before>use nom::{crlf, Slice};
use std::str;

pub use self::fetch::fetch;

mod fetch;
mod sequence;

const DIGITS: &'static str = "0123456789";
const NZ_DIGITS: &'static str = "123456789";

fn is_astring_char(chr: u8) -> bool {
    is_atom_char(chr) || is_resp_specials(chr)
}

// any CHAR except atom-specials
fn is_atom_char(chr: u8) -> bool {
    !is_atom_specials(chr)
}

fn is_atom_specials(chr: u8) -> bool {
    chr == b'(' || chr == b')' || chr == b'{' || is_sp(chr) || is_ctl(chr) ||
        is_list_wildcards(chr) || is_quoted_specials(chr) ||
        is_resp_specials(chr)
}

fn is_sp(chr: u8) -> bool {
    chr == b' '
}

fn is_ctl(chr: u8) -> bool {
    (chr >= b'\x00' && chr <= b'\x1F') || chr == b'\x7F'
}

fn is_list_wildcards(chr: u8) -> bool {
    chr == b'%' || chr == b'*'
}

fn is_quoted_specials(chr: u8) -> bool {
    is_dquote(chr) || chr == b'\\'
}

fn is_dquote(chr: u8) -> bool {
    chr == b'"'
}

fn is_resp_specials(chr: u8) -> bool {
    chr == b']'
}

// an ASCII digit (%x30-%x39)
fn is_digit(chr: u8) -> bool {
    chr >= b'0' && chr <= b'9'
}

// any TEXT_CHAR except quoted_specials
fn is_quoted_char(chr: u8) -> bool {
    !is_quoted_specials(chr) && is_text_char(chr)
}

// any CHAR except CR and LF
fn is_text_char(chr: u8) -> bool {
    !is_eol_char(chr)
}

// a CR or LF CHAR
fn is_eol_char(chr: u8) -> bool {
    chr == b'\r' || chr == b'\n'
}

/* String parsing */

named!(astring<&[u8], &[u8]>, alt!(take_while1!(is_astring_char) | string));

named!(string<&[u8], &[u8]>, alt!(quoted | literal));

named!(quoted<&[u8], &[u8]>,
    delimited!(
        tag!("\""),
        recognize!(
            many0!(
                alt!(
                    take_while1!(is_quoted_char) |
                    preceded!(tag!("\\"), alt!(tag!("\"") | tag!("\\")))
                )
            )
        ),
        tag!("\"")
    )
);

named!(literal<&[u8], &[u8]>,
    do_parse!(
        // The "number" is used to indicate the number of octets.
        number: terminated!(delimited!(tag!("{"), number, tag!("}")), crlf) >>
        v: recognize!(
            count!(
                do_parse!(
                    // any OCTET except NUL ('%x00')
                    not!(char!('\x00')) >>
                    chr: take!(1) >>

                    (chr)
                ),
                number
            )
        ) >>

        (v)
    )
);

/* RFC 3501 Boilerplate */

/// Recognizes an non-zero unsigned 32-bit integer.
// (0 < n < 4,294,967,296)
named!(number<usize>, flat_map!(take_while1!(is_digit), parse_to!(usize)));

/// Recognizes a non-zero unsigned 32-bit integer.
// (0 < n < 4,294,967,296)
named!(nz_number<usize>,
    flat_map!(
        recognize!(
            tuple!(
                digit_nz,
                many0!(one_of!(DIGITS))
            )
        ),
        parse_to!(usize)
    )
);

/// Recognizes exactly one non-zero numerical character: 1-9.
// digit-nz = %x31-39
//    ; 1-9
named!(digit_nz<char>, one_of!(NZ_DIGITS));

/// Recognizes exactly one ASCII whitespace.
named!(whitespace<char>, char!(' '));

#[cfg(test)]
mod tests {
    use nom::ErrorKind::{Alt, Char, Count, OneOf, TakeWhile1, MapOpt, Tag};
    use nom::Needed::Size;
    use nom::IResult::{Done, Error, Incomplete};
    use super::{
        astring,
        digit_nz,
        literal,
        number,
        nz_number,
        quoted,
        string,
        whitespace
    };

    #[test]
    fn test_astring() {
        assert_eq!(astring(b""), Incomplete(Size(1)));
        assert_eq!(astring(b"("), Error(Alt));
        assert_eq!(astring(b"]"), Done(&b""[..], &b"]"[..]));
        assert_eq!(astring(b"a"), Done(&b""[..], &b"a"[..]));
        assert_eq!(astring(b"\"test\"abc"), Done(&b"abc"[..], &b"test"[..]));
        assert_eq!(astring(b"\"test\""), Done(&b""[..], &b"test"[..]));
        assert_eq!(astring(b"{3}\r\nabc\x00"), Done(&b"\x00"[..], &b"abc"[..]));
    }

    #[test]
    fn test_string() {
        assert_eq!(string(b"\"test\""), Done(&b""[..], &b"test"[..]));
        assert_eq!(string(b"{2}\r\nab\x00"), Done(&b"\x00"[..], &b"ab"[..]));
    }

    #[test]
    fn test_quoted() {
        assert_eq!(quoted(b""), Incomplete(Size(1)));
        assert_eq!(quoted(b"\"\""), Done(&b""[..], &b""[..]));
        assert_eq!(quoted(b"\"a\""), Done(&b""[..], &b"a"[..]));
        assert_eq!(quoted(b"\"\\\""), Incomplete(Size(4)));
        assert_eq!(quoted(b"\"\\\"\""), Done(&b""[..], &b"\\\""[..]));
        assert_eq!(quoted(b"\"\\\\\""), Done(&b""[..], &b"\\\\"[..]));
        assert_eq!(quoted(b"\"\r\""), Error(Tag));
        assert_eq!(quoted(b"\"\t\""), Done(&b""[..], &b"\t"[..]));
    }

    #[test]
    fn test_literal() {
        assert_eq!(literal(b""), Incomplete(Size(1)));
        assert_eq!(literal(b"{1}\r\nabc"), Done(&b"bc"[..], &b"a"[..]));
        assert_eq!(literal(b"{0}\r\n"), Done(&b""[..], &b""[..]));
        assert_eq!(literal(b"{1}\r\na"), Done(&b""[..], &b"a"[..]));
        assert_eq!(literal(b"{2}\r\na"), Incomplete(Size(7)));
        assert_eq!(literal(b"{2}\r\na\x00a"), Error(Count));
    }

    #[test]
    fn test_number() {
        assert_eq!(number(b""), Incomplete(Size(1)));
        assert_eq!(number(b"a"), Error(TakeWhile1));
        assert_eq!(number(b"0"), Done(&b""[..], 0));
        assert_eq!(number(b"1"), Done(&b""[..], 1));
        assert_eq!(number(b"10"), Done(&b""[..], 10));
        assert_eq!(number(b"10a"), Done(&b"a"[..], 10));
        assert_eq!(number(b"4294967296"), Done(&b""[..], 4294967296));
        assert_eq!(number(b"100000000000000000000"), Error(MapOpt));
    }

    #[test]
    fn test_nz_number() {
        assert_eq!(nz_number(b""), Incomplete(Size(1)));
        assert_eq!(nz_number(b"a"), Error(OneOf));
        assert_eq!(nz_number(b"0"), Error(OneOf));
        assert_eq!(nz_number(b"1"), Done(&b""[..], 1));
        assert_eq!(nz_number(b"10"), Done(&b""[..], 10));
        assert_eq!(nz_number(b"10a"), Done(&b"a"[..], 10));
        assert_eq!(nz_number(b"4294967296"), Done(&b""[..], 4294967296));
        assert_eq!(nz_number(b"100000000000000000000"), Error(MapOpt));
    }

    #[test]
    fn test_digit_nz() {
        assert_eq!(digit_nz(b""), Incomplete(Size(1)));
        assert_eq!(digit_nz(b"a"), Error(OneOf));
        assert_eq!(digit_nz(b"1"), Done(&b""[..], '1'));
        assert_eq!(digit_nz(b"62"), Done(&b"2"[..], '6'));
    }

    #[test]
    fn test_whitespace() {
        assert_eq!(whitespace(b""), Incomplete(Size(1)));
        assert_eq!(whitespace(b"a"), Error(Char));
        assert_eq!(whitespace(b" "), Done(&b""[..], ' '));
        assert_eq!(whitespace(b"\t"), Error(Char));
    }
}
<commit_msg>impr: simplify comparison in is_ctl function<commit_after>use nom::{crlf, Slice};
use std::str;

pub use self::fetch::fetch;

mod fetch;
mod sequence;

const DIGITS: &'static str = "0123456789";
const NZ_DIGITS: &'static str = "123456789";

fn is_astring_char(chr: u8) -> bool {
    is_atom_char(chr) || is_resp_specials(chr)
}

// any CHAR except atom-specials
fn is_atom_char(chr: u8) -> bool {
    !is_atom_specials(chr)
}

fn is_atom_specials(chr: u8) -> bool {
    chr == b'(' || chr == b')' || chr == b'{' || is_sp(chr) || is_ctl(chr) ||
        is_list_wildcards(chr) || is_quoted_specials(chr) ||
        is_resp_specials(chr)
}

fn is_sp(chr: u8) -> bool {
    chr == b' '
}

fn is_ctl(chr: u8) -> bool {
    chr <= b'\x1F' || chr == b'\x7F'
}

fn is_list_wildcards(chr: u8) -> bool {
    chr == b'%' || chr == b'*'
}

fn is_quoted_specials(chr: u8) -> bool {
    is_dquote(chr) || chr == b'\\'
}

fn is_dquote(chr: u8) -> bool {
    chr == b'"'
}

fn is_resp_specials(chr: u8) -> bool {
    chr == b']'
}

// an ASCII digit (%x30-%x39)
fn is_digit(chr: u8) -> bool {
    chr >= b'0' && chr <= b'9'
}

// any TEXT_CHAR except quoted_specials
fn is_quoted_char(chr: u8) -> bool {
    !is_quoted_specials(chr) && is_text_char(chr)
}

// any CHAR except CR and LF
fn is_text_char(chr: u8) -> bool {
    !is_eol_char(chr)
}

// a CR or LF CHAR
fn is_eol_char(chr: u8) -> bool {
    chr == b'\r' || chr == b'\n'
}

/* String parsing */

named!(astring<&[u8], &[u8]>, alt!(take_while1!(is_astring_char) | string));

named!(string<&[u8], &[u8]>, alt!(quoted | literal));

named!(quoted<&[u8], &[u8]>,
    delimited!(
        tag!("\""),
        recognize!(
            many0!(
                alt!(
                    take_while1!(is_quoted_char) |
                    preceded!(tag!("\\"), alt!(tag!("\"") | tag!("\\")))
                )
            )
        ),
        tag!("\"")
    )
);

named!(literal<&[u8], &[u8]>,
    do_parse!(
        // The "number" is used to indicate the number of octets.
        number: terminated!(delimited!(tag!("{"), number, tag!("}")), crlf) >>
        v: recognize!(
            count!(
                do_parse!(
                    // any OCTET except NUL ('%x00')
                    not!(char!('\x00')) >>
                    chr: take!(1) >>

                    (chr)
                ),
                number
            )
        ) >>

        (v)
    )
);

/* RFC 3501 Boilerplate */

/// Recognizes an non-zero unsigned 32-bit integer.
// (0 < n < 4,294,967,296)
named!(number<usize>, flat_map!(take_while1!(is_digit), parse_to!(usize)));

/// Recognizes a non-zero unsigned 32-bit integer.
// (0 < n < 4,294,967,296)
named!(nz_number<usize>,
    flat_map!(
        recognize!(
            tuple!(
                digit_nz,
                many0!(one_of!(DIGITS))
            )
        ),
        parse_to!(usize)
    )
);

/// Recognizes exactly one non-zero numerical character: 1-9.
// digit-nz = %x31-39
//    ; 1-9
named!(digit_nz<char>, one_of!(NZ_DIGITS));

/// Recognizes exactly one ASCII whitespace.
named!(whitespace<char>, char!(' '));

#[cfg(test)]
mod tests {
    use nom::ErrorKind::{Alt, Char, Count, OneOf, TakeWhile1, MapOpt, Tag};
    use nom::Needed::Size;
    use nom::IResult::{Done, Error, Incomplete};
    use super::{
        astring,
        digit_nz,
        literal,
        number,
        nz_number,
        quoted,
        string,
        whitespace
    };

    #[test]
    fn test_astring() {
        assert_eq!(astring(b""), Incomplete(Size(1)));
        assert_eq!(astring(b"("), Error(Alt));
        assert_eq!(astring(b"]"), Done(&b""[..], &b"]"[..]));
        assert_eq!(astring(b"a"), Done(&b""[..], &b"a"[..]));
        assert_eq!(astring(b"\"test\"abc"), Done(&b"abc"[..], &b"test"[..]));
        assert_eq!(astring(b"\"test\""), Done(&b""[..], &b"test"[..]));
        assert_eq!(astring(b"{3}\r\nabc\x00"), Done(&b"\x00"[..], &b"abc"[..]));
    }

    #[test]
    fn test_string() {
        assert_eq!(string(b"\"test\""), Done(&b""[..], &b"test"[..]));
        assert_eq!(string(b"{2}\r\nab\x00"), Done(&b"\x00"[..], &b"ab"[..]));
    }

    #[test]
    fn test_quoted() {
        assert_eq!(quoted(b""), Incomplete(Size(1)));
        assert_eq!(quoted(b"\"\""), Done(&b""[..], &b""[..]));
        assert_eq!(quoted(b"\"a\""), Done(&b""[..], &b"a"[..]));
        assert_eq!(quoted(b"\"\\\""), Incomplete(Size(4)));
        assert_eq!(quoted(b"\"\\\"\""), Done(&b""[..], &b"\\\""[..]));
        assert_eq!(quoted(b"\"\\\\\""), Done(&b""[..], &b"\\\\"[..]));
        assert_eq!(quoted(b"\"\r\""), Error(Tag));
        assert_eq!(quoted(b"\"\t\""), Done(&b""[..], &b"\t"[..]));
    }

    #[test]
    fn test_literal() {
        assert_eq!(literal(b""), Incomplete(Size(1)));
        assert_eq!(literal(b"{1}\r\nabc"), Done(&b"bc"[..], &b"a"[..]));
        assert_eq!(literal(b"{0}\r\n"), Done(&b""[..], &b""[..]));
        assert_eq!(literal(b"{1}\r\na"), Done(&b""[..], &b"a"[..]));
        assert_eq!(literal(b"{2}\r\na"), Incomplete(Size(7)));
        assert_eq!(literal(b"{2}\r\na\x00a"), Error(Count));
    }

    #[test]
    fn test_number() {
        assert_eq!(number(b""), Incomplete(Size(1)));
        assert_eq!(number(b"a"), Error(TakeWhile1));
        assert_eq!(number(b"0"), Done(&b""[..], 0));
        assert_eq!(number(b"1"), Done(&b""[..], 1));
        assert_eq!(number(b"10"), Done(&b""[..], 10));
        assert_eq!(number(b"10a"), Done(&b"a"[..], 10));
        assert_eq!(number(b"4294967296"), Done(&b""[..], 4294967296));
        assert_eq!(number(b"100000000000000000000"), Error(MapOpt));
    }

    #[test]
    fn test_nz_number() {
        assert_eq!(nz_number(b""), Incomplete(Size(1)));
        assert_eq!(nz_number(b"a"), Error(OneOf));
        assert_eq!(nz_number(b"0"), Error(OneOf));
        assert_eq!(nz_number(b"1"), Done(&b""[..], 1));
        assert_eq!(nz_number(b"10"), Done(&b""[..], 10));
        assert_eq!(nz_number(b"10a"), Done(&b"a"[..], 10));
        assert_eq!(nz_number(b"4294967296"), Done(&b""[..], 4294967296));
        assert_eq!(nz_number(b"100000000000000000000"), Error(MapOpt));
    }

    #[test]
    fn test_digit_nz() {
        assert_eq!(digit_nz(b""), Incomplete(Size(1)));
        assert_eq!(digit_nz(b"a"), Error(OneOf));
        assert_eq!(digit_nz(b"1"), Done(&b""[..], '1'));
        assert_eq!(digit_nz(b"62"), Done(&b"2"[..], '6'));
    }

    #[test]
    fn test_whitespace() {
        assert_eq!(whitespace(b""), Incomplete(Size(1)));
        assert_eq!(whitespace(b"a"), Error(Char));
        assert_eq!(whitespace(b" "), Done(&b""[..], ' '));
        assert_eq!(whitespace(b"\t"), Error(Char));
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This module defines the structs transported during the network messaging protocol v1.
//! These should serialize as per [link](TODO: Add ref).

use crate::protocols::wire::handshake::v1::{MessagingProtocolVersion, ProtocolId};
use serde::{Deserialize, Serialize};

#[cfg(test)]
mod test;

/// Message variants that are sent on the wire.
/// New variants cannot be added without bumping up the MessagingProtocolVersion.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum NetworkMessage {
    Error(ErrorCode),
    Ping(Nonce),
    Pong(Nonce),
    RpcRequest(RpcRequest),
    RpcResponse(RpcResponse),
    DirectSendMsg(DirectSendMsg),
}

/// Enum representing various error codes that can be embedded in NetworkMessage.
/// New variants cannot be added without bumping up the MessagingProtocolVersion.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum ErrorCode {
    /// Failed to parse NetworkMessage when interpreting according to provided protocol version.
    ParsingError(MessagingProtocolVersion, Box<NetworkMessage>),
    /// Ping timed out.
    TimedOut,
}

/// Nonces used by Ping and Pong message types.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct Nonce(pub u32);

/// Create alias RequestId for u32.
pub type RequestId = u32;

/// Create alias Priority for u8.
pub type Priority = u8;

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct RpcRequest {
    /// RequestId for the RPC Request.
    pub request_id: RequestId,
    /// `protocol_id` is a variant of the ProtocolId enum.
    pub protocol_id: ProtocolId,
    /// Request priority in the range 0..=255.
    pub priority: Priority,
    /// Request payload. This will be parsed by the application-level handler.
    #[serde(with = "serde_bytes")]
    pub raw_request: Vec<u8>,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct RpcResponse {
    /// RequestId for corresponding request. This is copied as is from the RpcRequest.
    pub request_id: RequestId,
    /// Response priority in the range 0..=255. This will likely be same as the priority of
    /// corresponding request.
    pub priority: Priority,
    /// Response payload.
    #[serde(with = "serde_bytes")]
    pub raw_response: Vec<u8>,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct DirectSendMsg {
    /// `protocol_id` is a variant of the ProtocolId enum.
    pub protocol_id: ProtocolId,
    /// Message priority in the range 0..=255.
    pub priority: Priority,
    /// Message payload.
    #[serde(with = "serde_bytes")]
    pub raw_msg: Vec<u8>,
}
<commit_msg>[network] Add ErrorCode::NotSupported to wire protocol<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This module defines the structs transported during the network messaging protocol v1.
//! These should serialize as per [link](TODO: Add ref).

use crate::protocols::wire::handshake::v1::{MessagingProtocolVersion, ProtocolId};
use serde::{Deserialize, Serialize};

#[cfg(test)]
mod test;

/// Message variants that are sent on the wire.
/// New variants cannot be added without bumping up the MessagingProtocolVersion.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum NetworkMessage {
    Error(ErrorCode),
    Ping(Nonce),
    Pong(Nonce),
    RpcRequest(RpcRequest),
    RpcResponse(RpcResponse),
    DirectSendMsg(DirectSendMsg),
}

/// Enum representing various error codes that can be embedded in NetworkMessage.
/// New variants cannot be added without bumping up the MessagingProtocolVersion.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum ErrorCode {
    /// Failed to parse NetworkMessage when interpreting according to provided protocol version.
    ParsingError(MessagingProtocolVersion, Box<NetworkMessage>),
    /// Ping timed out.
    TimedOut,
    /// A message was received for a protocol that is not supported over this connection.
    NotSupported(ProtocolId),
}

/// Nonces used by Ping and Pong message types.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct Nonce(pub u32);

/// Create alias RequestId for u32.
pub type RequestId = u32;

/// Create alias Priority for u8.
pub type Priority = u8;

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct RpcRequest {
    /// RequestId for the RPC Request.
    pub request_id: RequestId,
    /// `protocol_id` is a variant of the ProtocolId enum.
    pub protocol_id: ProtocolId,
    /// Request priority in the range 0..=255.
    pub priority: Priority,
    /// Request payload. This will be parsed by the application-level handler.
    #[serde(with = "serde_bytes")]
    pub raw_request: Vec<u8>,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct RpcResponse {
    /// RequestId for corresponding request. This is copied as is from the RpcRequest.
    pub request_id: RequestId,
    /// Response priority in the range 0..=255. This will likely be same as the priority of
    /// corresponding request.
    pub priority: Priority,
    /// Response payload.
    #[serde(with = "serde_bytes")]
    pub raw_response: Vec<u8>,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct DirectSendMsg {
    /// `protocol_id` is a variant of the ProtocolId enum.
    pub protocol_id: ProtocolId,
    /// Message priority in the range 0..=255.
    pub priority: Priority,
    /// Message payload.
    #[serde(with = "serde_bytes")]
    pub raw_msg: Vec<u8>,
}
<|endoftext|>


<commit_before>#![feature(no_core, lang_items, intrinsics, unboxed_closures)]
#![no_core]
#![allow(dead_code)]

#[lang="sized"]
pub trait Sized {}

#[lang="copy"]
pub unsafe trait Copy {}

unsafe impl Copy for bool {}
unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for isize {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}

#[lang="freeze"]
trait Freeze {}

#[lang="mul"]
pub trait Mul<RHS = Self> {
    type Output;

    #[must_use]
    fn mul(self, rhs: RHS) -> Self::Output;
}

impl Mul for u8 {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        self * rhs
    }
}

#[lang="bitor"]
pub trait BitOr<RHS = Self> {
    type Output;

    #[must_use]
    fn bitor(self, rhs: RHS) -> Self::Output;
}

impl BitOr for bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        self | rhs
    }
}

impl<'a> BitOr<bool> for &'a bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        *self | rhs
    }
}

#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
    fn eq(&self, other: &Rhs) -> bool;
    fn ne(&self, other: &Rhs) -> bool;
}

impl PartialEq for u8 {
    fn eq(&self, other: &u8) -> bool { (*self) == (*other) }
    fn ne(&self, other: &u8) -> bool { (*self) != (*other) }
}

impl PartialEq for char {
    fn eq(&self, other: &char) -> bool { (*self) == (*other) }
    fn ne(&self, other: &char) -> bool { (*self) != (*other) }
}

impl<T: ?Sized> PartialEq for *const T {
    fn eq(&self, other: &*const T) -> bool { *self == *other }
    fn ne(&self, other: &*const T) -> bool { *self != *other }
}

#[lang = "fn_once"]
#[rustc_paren_sugar]
pub trait FnOnce<Args> {
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

#[lang = "fn_mut"]
#[rustc_paren_sugar]
pub trait FnMut<Args> : FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

#[lang="panic"]
pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
    loop {}
}

#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
    // Code here does not matter - this is replaced by the
    // real drop glue by the compiler.
    drop_in_place(to_drop);
}

pub mod intrinsics {
    extern "rust-intrinsic" {
        pub fn size_of<T>() -> usize;
        pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
        pub fn transmute<T, U>(e: T) -> U;
        pub fn uninit<T>() -> T;
    }
}
<commit_msg>Add Coerce and CoerceUnsized to mini_core<commit_after>#![feature(no_core, lang_items, intrinsics, unboxed_closures)]
#![no_core]
#![allow(dead_code)]

#[lang="sized"]
pub trait Sized {}

#[lang = "unsize"]
pub trait Unsize<T: ?Sized> {}

#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}

impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}

#[lang="copy"]
pub unsafe trait Copy {}

unsafe impl Copy for bool {}
unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for isize {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}

#[lang="freeze"]
trait Freeze {}

#[lang="mul"]
pub trait Mul<RHS = Self> {
    type Output;

    #[must_use]
    fn mul(self, rhs: RHS) -> Self::Output;
}

impl Mul for u8 {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        self * rhs
    }
}

#[lang="bitor"]
pub trait BitOr<RHS = Self> {
    type Output;

    #[must_use]
    fn bitor(self, rhs: RHS) -> Self::Output;
}

impl BitOr for bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        self | rhs
    }
}

impl<'a> BitOr<bool> for &'a bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        *self | rhs
    }
}

#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
    fn eq(&self, other: &Rhs) -> bool;
    fn ne(&self, other: &Rhs) -> bool;
}

impl PartialEq for u8 {
    fn eq(&self, other: &u8) -> bool { (*self) == (*other) }
    fn ne(&self, other: &u8) -> bool { (*self) != (*other) }
}

impl PartialEq for char {
    fn eq(&self, other: &char) -> bool { (*self) == (*other) }
    fn ne(&self, other: &char) -> bool { (*self) != (*other) }
}

impl<T: ?Sized> PartialEq for *const T {
    fn eq(&self, other: &*const T) -> bool { *self == *other }
    fn ne(&self, other: &*const T) -> bool { *self != *other }
}

#[lang = "fn_once"]
#[rustc_paren_sugar]
pub trait FnOnce<Args> {
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

#[lang = "fn_mut"]
#[rustc_paren_sugar]
pub trait FnMut<Args> : FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

#[lang="panic"]
pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
    loop {}
}

#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
    // Code here does not matter - this is replaced by the
    // real drop glue by the compiler.
    drop_in_place(to_drop);
}

pub mod intrinsics {
    extern "rust-intrinsic" {
        pub fn size_of<T>() -> usize;
        pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
        pub fn transmute<T, U>(e: T) -> U;
        pub fn uninit<T>() -> T;
    }
}
<|endoftext|>


<commit_before>use std::collections::btree_map::{BTreeMap, Keys};

/// A lazy iterator producing elements in the set intersection (in-order).
#[derive(Clone)]
pub struct Intersection<K, Iter: Iterator<Item=K>> {
    iters: Vec<Iter>
}

impl<K: Ord, V: Iterator<Item=K>> Iterator for Intersection<K, V> {
    type Item = K;

    fn next(&mut self) -> Option<K> {
        let mut maximum = match self.iters.first_mut().map(Iterator::next) {
            Some(Some(k)) => k,
            _ => return None
        };

        // Where the maximum came from
        let mut skip_nth = 0;

        // Keep trying to...
        loop {
            let mut retry_with = None;

            // ...match all iters front element
            // with the chosen maximum
            for (i, iter) in self.iters.iter_mut().enumerate() {
                if i == skip_nth { continue; }

                match iter.find(|x| x >= &maximum) {
                    Some(val) => if val > maximum {
                        retry_with = Some(val);
                        skip_nth = i;
                        break;
                    },

                    // Intersection is empty
                    None => return None,
                }
            }

            match retry_with {
                Some(new_maximum) => maximum = new_maximum,
                None => return Some(maximum)
            }
        }
    }
}

/// An extension trait for slices of BTreeMaps that enables
/// computing intersections
pub trait BTreeMapExt {
    /// The type of the map's keys.
    type Key;

    /// The type of the map's keys iterator.
    type Iter: Iterator<Item=Self::Key>;

    /// Visits the values representing the intersection, in ascending order.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::collections::BTreeMap;
    ///
    /// let mut a = BTreeMap::new();
    /// a.insert(1, ());
    /// a.insert(2, ());
    ///
    /// let mut b = BTreeMap::new();
    /// b.insert(2, ());
    /// b.insert(3, ());
    ///
    /// let maps = &[a, b];
    /// let intersection: Vec<_> = maps.intersection().cloned().collect();
    /// assert_eq!(intersection, [2]);
    /// ```
    fn intersection(self) -> Intersection<Self::Key, Self::Iter>;
}

impl<'a, K: Ord, V> BTreeMapExt for &'a [BTreeMap<K, V>] {
    type Key = &'a K;
    type Iter = Keys<'a, K, V>;
    fn intersection(self) -> Intersection<&'a K, Keys<'a, K, V>> {
        Intersection{iters: self.iter().map(|map| map.keys()).collect() }
    }
}

#[test]
fn test_intersection_first_min() {
    let mut map1 = BTreeMap::new();
    map1.insert(1, ());
    map1.insert(2, ());
    map1.insert(3, ());
    map1.insert(4, ());
    let mut map2 = BTreeMap::new();
    map2.insert(2, ());
    map2.insert(3, ());
    map2.insert(4, ());
    let mut map3 = BTreeMap::new();
    map3.insert(1, ());
    map3.insert(2, ());
    map3.insert(3, ());
    let maps = vec![map1, map2, map3];
    let maps = &*maps;
    let intersection: Vec<_> = maps.intersection().collect();
    assert_eq!(intersection, vec![&2, &3]);
}

#[test]
fn test_intersection_last_min() {
    let mut map1 = BTreeMap::new();
    map1.insert(2, ());
    map1.insert(3, ());
    map1.insert(4, ());
    map1.insert(5, ());
    let mut map2 = BTreeMap::new();
    map2.insert(2, ());
    map2.insert(3, ());
    map2.insert(4, ());
    let mut map3 = BTreeMap::new();
    map3.insert(1, ());
    map3.insert(2, ());
    map3.insert(3, ());
    let maps = vec![map1, map2, map3];
    let maps = &*maps;
    let intersection: Vec<_> = maps.intersection().collect();
    assert_eq!(intersection, vec![&2, &3]);
}
<commit_msg>Fix doc test<commit_after>use std::collections::btree_map::{BTreeMap, Keys};

/// A lazy iterator producing elements in the set intersection (in-order).
#[derive(Clone)]
pub struct Intersection<K, Iter: Iterator<Item=K>> {
    iters: Vec<Iter>
}

impl<K: Ord, V: Iterator<Item=K>> Iterator for Intersection<K, V> {
    type Item = K;

    fn next(&mut self) -> Option<K> {
        let mut maximum = match self.iters.first_mut().map(Iterator::next) {
            Some(Some(k)) => k,
            _ => return None
        };

        // Where the maximum came from
        let mut skip_nth = 0;

        // Keep trying to...
        loop {
            let mut retry_with = None;

            // ...match all iters front element
            // with the chosen maximum
            for (i, iter) in self.iters.iter_mut().enumerate() {
                if i == skip_nth { continue; }

                match iter.find(|x| x >= &maximum) {
                    Some(val) => if val > maximum {
                        retry_with = Some(val);
                        skip_nth = i;
                        break;
                    },

                    // Intersection is empty
                    None => return None,
                }
            }

            match retry_with {
                Some(new_maximum) => maximum = new_maximum,
                None => return Some(maximum)
            }
        }
    }
}

/// An extension trait for slices of BTreeMaps that enables
/// computing intersections
pub trait BTreeMapExt {
    /// The type of the map's keys.
    type Key;

    /// The type of the map's keys iterator.
    type Iter: Iterator<Item=Self::Key>;

    /// Visits the values representing the intersection, in ascending order.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::collections::BTreeMap;
    /// use inverted_index::util::BTreeMapExt;
    ///
    /// let mut a = BTreeMap::new();
    /// a.insert(1, ());
    /// a.insert(2, ());
    ///
    /// let mut b = BTreeMap::new();
    /// b.insert(2, ());
    /// b.insert(3, ());
    ///
    /// let maps = &[a, b];
    /// let intersection: Vec<_> = maps.intersection().cloned().collect();
    /// assert_eq!(intersection, [2]);
    /// ```
    fn intersection(self) -> Intersection<Self::Key, Self::Iter>;
}

impl<'a, K: Ord, V> BTreeMapExt for &'a [BTreeMap<K, V>] {
    type Key = &'a K;
    type Iter = Keys<'a, K, V>;
    fn intersection(self) -> Intersection<&'a K, Keys<'a, K, V>> {
        Intersection{iters: self.iter().map(|map| map.keys()).collect() }
    }
}

#[test]
fn test_intersection_first_min() {
    let mut map1 = BTreeMap::new();
    map1.insert(1, ());
    map1.insert(2, ());
    map1.insert(3, ());
    map1.insert(4, ());
    let mut map2 = BTreeMap::new();
    map2.insert(2, ());
    map2.insert(3, ());
    map2.insert(4, ());
    let mut map3 = BTreeMap::new();
    map3.insert(1, ());
    map3.insert(2, ());
    map3.insert(3, ());
    let maps = vec![map1, map2, map3];
    let maps = &*maps;
    let intersection: Vec<_> = maps.intersection().collect();
    assert_eq!(intersection, vec![&2, &3]);
}

#[test]
fn test_intersection_last_min() {
    let mut map1 = BTreeMap::new();
    map1.insert(2, ());
    map1.insert(3, ());
    map1.insert(4, ());
    map1.insert(5, ());
    let mut map2 = BTreeMap::new();
    map2.insert(2, ());
    map2.insert(3, ());
    map2.insert(4, ());
    let mut map3 = BTreeMap::new();
    map3.insert(1, ());
    map3.insert(2, ());
    map3.insert(3, ());
    let maps = vec![map1, map2, map3];
    let maps = &*maps;
    let intersection: Vec<_> = maps.intersection().collect();
    assert_eq!(intersection, vec![&2, &3]);
}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Joao Oliveira <joaoxsouls@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// last synced with: uname (GNU coreutils) 8.21

// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use platform_info::*;

const ABOUT: &str = "Print certain system information.  With no OPTION, same as -s.";

pub mod options {
    pub static ALL: &str = "all";
    pub static KERNELNAME: &str = "kernel-name";
    pub static NODENAME: &str = "nodename";
    pub static KERNELVERSION: &str = "kernel-version";
    pub static KERNELRELEASE: &str = "kernel-release";
    pub static MACHINE: &str = "machine";
    pub static PROCESSOR: &str = "processor";
    pub static HWPLATFORM: &str = "hardware-platform";
    pub static OS: &str = "operating-system";
}

#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "")))]
const HOST_OS: &str = "GNU/Linux";
#[cfg(all(target_os = "linux", not(any(target_env = "gnu", target_env = ""))))]
const HOST_OS: &str = "Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "netbsd")]
const HOST_OS: &str = "NetBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = format!("{} [OPTION]...", uucore::execution_phrase());
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let uname = crash_if_err!(1, PlatformInfo::new());
    let mut output = String::new();

    let all = matches.is_present(options::ALL);
    let kernelname = matches.is_present(options::KERNELNAME);
    let nodename = matches.is_present(options::NODENAME);
    let kernelrelease = matches.is_present(options::KERNELRELEASE);
    let kernelversion = matches.is_present(options::KERNELVERSION);
    let machine = matches.is_present(options::MACHINE);
    let processor = matches.is_present(options::PROCESSOR);
    let hwplatform = matches.is_present(options::HWPLATFORM);
    let os = matches.is_present(options::OS);

    let none = !(all
        || kernelname
        || nodename
        || kernelrelease
        || kernelversion
        || machine
        || os
        || processor
        || hwplatform);

    if kernelname || all || none {
        output.push_str(&uname.sysname());
        output.push(' ');
    }

    if nodename || all {
        output.push_str(&uname.nodename());
        output.push(' ');
    }
    if kernelrelease || all {
        output.push_str(&uname.release());
        output.push(' ');
    }
    if kernelversion || all {
        output.push_str(&uname.version());
        output.push(' ');
    }
    if machine || all {
        output.push_str(&uname.machine());
        output.push(' ');
    }
    if processor || all {
        // According to https://stackoverflow.com/posts/394271/revisions
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if hwplatform || all {
        // According to https://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if os || all {
        output.push_str(HOST_OS);
        output.push(' ');
    }
    println!("{}", output.trim_end());

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .arg(Arg::with_name(options::ALL)
            .short("a")
            .long(options::ALL)
            .help("Behave as though all of the options -mnrsv were specified."))
        .arg(Arg::with_name(options::KERNELNAME)
            .short("s")
            .long(options::KERNELNAME)
            .alias("sysname") // Obsolescent option in GNU uname
            .help("print the kernel name."))
        .arg(Arg::with_name(options::NODENAME)
            .short("n")
            .long(options::NODENAME)
            .help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
        .arg(Arg::with_name(options::KERNELRELEASE)
            .short("r")
            .long(options::KERNELRELEASE)
            .alias("release") // Obsolescent option in GNU uname
            .help("print the operating system release."))
        .arg(Arg::with_name(options::KERNELVERSION)
            .short("v")
            .long(options::KERNELVERSION)
            .help("print the operating system version."))
        .arg(Arg::with_name(options::HWPLATFORM)
            .short("i")
            .long(options::HWPLATFORM)
            .help("print the hardware platform (non-portable)"))
        .arg(Arg::with_name(options::MACHINE)
            .short("m")
            .long(options::MACHINE)
            .help("print the machine hardware name."))
        .arg(Arg::with_name(options::PROCESSOR)
            .short("p")
            .long(options::PROCESSOR)
            .help("print the processor type (non-portable)"))
        .arg(Arg::with_name(options::OS)
            .short("o")
            .long(options::OS)
            .help("print the operating system name."))
}
<commit_msg>uname: use UResult<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Joao Oliveira <joaoxsouls@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// last synced with: uname (GNU coreutils) 8.21

// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv

use clap::{crate_version, App, Arg};
use platform_info::*;
use uucore::error::{FromIo, UResult};

const ABOUT: &str = "Print certain system information.  With no OPTION, same as -s.";

pub mod options {
    pub static ALL: &str = "all";
    pub static KERNELNAME: &str = "kernel-name";
    pub static NODENAME: &str = "nodename";
    pub static KERNELVERSION: &str = "kernel-version";
    pub static KERNELRELEASE: &str = "kernel-release";
    pub static MACHINE: &str = "machine";
    pub static PROCESSOR: &str = "processor";
    pub static HWPLATFORM: &str = "hardware-platform";
    pub static OS: &str = "operating-system";
}

#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "")))]
const HOST_OS: &str = "GNU/Linux";
#[cfg(all(target_os = "linux", not(any(target_env = "gnu", target_env = ""))))]
const HOST_OS: &str = "Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "netbsd")]
const HOST_OS: &str = "NetBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";

#[uucore_procs::gen_uumain]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let usage = format!("{} [OPTION]...", uucore::execution_phrase());
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let uname =
        PlatformInfo::new().map_err_context(|| "failed to create PlatformInfo".to_string())?;
    let mut output = String::new();

    let all = matches.is_present(options::ALL);
    let kernelname = matches.is_present(options::KERNELNAME);
    let nodename = matches.is_present(options::NODENAME);
    let kernelrelease = matches.is_present(options::KERNELRELEASE);
    let kernelversion = matches.is_present(options::KERNELVERSION);
    let machine = matches.is_present(options::MACHINE);
    let processor = matches.is_present(options::PROCESSOR);
    let hwplatform = matches.is_present(options::HWPLATFORM);
    let os = matches.is_present(options::OS);

    let none = !(all
        || kernelname
        || nodename
        || kernelrelease
        || kernelversion
        || machine
        || os
        || processor
        || hwplatform);

    if kernelname || all || none {
        output.push_str(&uname.sysname());
        output.push(' ');
    }

    if nodename || all {
        output.push_str(&uname.nodename());
        output.push(' ');
    }
    if kernelrelease || all {
        output.push_str(&uname.release());
        output.push(' ');
    }
    if kernelversion || all {
        output.push_str(&uname.version());
        output.push(' ');
    }
    if machine || all {
        output.push_str(&uname.machine());
        output.push(' ');
    }
    if processor || all {
        // According to https://stackoverflow.com/posts/394271/revisions
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if hwplatform || all {
        // According to https://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if os || all {
        output.push_str(HOST_OS);
        output.push(' ');
    }
    println!("{}", output.trim_end());

    Ok(())
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .arg(Arg::with_name(options::ALL)
            .short("a")
            .long(options::ALL)
            .help("Behave as though all of the options -mnrsv were specified."))
        .arg(Arg::with_name(options::KERNELNAME)
            .short("s")
            .long(options::KERNELNAME)
            .alias("sysname") // Obsolescent option in GNU uname
            .help("print the kernel name."))
        .arg(Arg::with_name(options::NODENAME)
            .short("n")
            .long(options::NODENAME)
            .help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
        .arg(Arg::with_name(options::KERNELRELEASE)
            .short("r")
            .long(options::KERNELRELEASE)
            .alias("release") // Obsolescent option in GNU uname
            .help("print the operating system release."))
        .arg(Arg::with_name(options::KERNELVERSION)
            .short("v")
            .long(options::KERNELVERSION)
            .help("print the operating system version."))
        .arg(Arg::with_name(options::HWPLATFORM)
            .short("i")
            .long(options::HWPLATFORM)
            .help("print the hardware platform (non-portable)"))
        .arg(Arg::with_name(options::MACHINE)
            .short("m")
            .long(options::MACHINE)
            .help("print the machine hardware name."))
        .arg(Arg::with_name(options::PROCESSOR)
            .short("p")
            .long(options::PROCESSOR)
            .help("print the processor type (non-portable)"))
        .arg(Arg::with_name(options::OS)
            .short("o")
            .long(options::OS)
            .help("print the operating system name."))
}
<|endoftext|>


<commit_before>extern crate rand;

use std::borrow::Cow;
use std::cmp;
use self::rand::{Rand, Rng};
use parse::{Node, NodeRef, ParsedFile, RangeRef};

#[derive(Debug)]
pub struct FuzzFile<'buf: 'parse, 'parse> {
    root: Cow<'parse, [NodeRef]>,
    nodes: Cow<'parse, [Node<'buf>]>,
    ranges: Cow<'parse, [Vec<NodeRef>]>,
}

#[derive(Clone)]
pub enum FuzzAction {
    DuplicateRange,
    DuplicateRootNode,
    RemoveDelim,
    ShuffleRanges,
    SwapDelim,
    SwapRanges,
}

pub struct FuzzConfig {
    pub max_mutations: usize,
    pub max_duplications: usize,
}

impl Rand for FuzzAction {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        let actions = vec![
            FuzzAction::DuplicateRange,
            FuzzAction::DuplicateRootNode,
            FuzzAction::RemoveDelim,
            FuzzAction::ShuffleRanges,
            FuzzAction::SwapDelim,
            FuzzAction::SwapRanges,
        ];
        rng.choose(&actions).unwrap().clone()
    }
}

fn rand_indices<R: Rng, T>(mut rng: &mut Rng, x: &[T]) -> Option<(usize, usize)> {
    if x.len() > 1 {
        let indices = rand::sample(&mut rng, 0..x.len(), 2);
        Some((indices[0], indices[1]))
    } else {
        None
    }
}

fn rand_delim<'buf, R: Rng>(mut rng: &mut R, nodes: &[Node<'buf>]) -> Option<(usize, &'buf [u8], RangeRef, &'buf [u8])> {
    let delims: Vec<_> = nodes.iter().enumerate().filter_map(|item| {
        match item {
            (index, &Node::Delim(start_pattern, rangeref, end_pattern)) => {
                Some((index, start_pattern, rangeref, end_pattern))
            },
            _ => None,
        }
    }).collect();
    rng.choose(&delims[..]).cloned()
}

struct SerializeState {
    have_serialized_range: Vec<bool>,
}

impl SerializeState {
    fn new(ranges: &[Vec<NodeRef>]) -> Self {
        SerializeState {
            have_serialized_range: ranges.iter().map(|_| false).collect()
        }
    }

    fn should_serialize(self: &mut Self, rangeref: RangeRef) -> bool {
        if self.have_serialized_range[rangeref] {
            false
        } else {
            self.have_serialized_range[rangeref] = true;
            true
        }
    }

    fn reset(self: &mut Self, rangeref: RangeRef) {
        self.have_serialized_range[rangeref] = false;
    }
}

pub trait SerializeInto {
    fn push(&mut self, &[u8]);
}

impl SerializeInto for Vec<u8> {
    fn push(self: &mut Self, token: &[u8]) {
        self.extend(token);
    }
}

pub struct SliceSerializer<'buf> {
    slice: &'buf mut [u8],
    cur_offset: usize,
}

impl<'buf> SliceSerializer<'buf> {
    pub fn new(slice: &'buf mut [u8]) -> SliceSerializer {
        SliceSerializer {
            slice: slice,
            cur_offset: 0,
        }
    }

    pub fn bytes_written(self: &Self) -> usize {
        self.cur_offset
    }
}

impl<'buf> SerializeInto for SliceSerializer<'buf> {
    fn push(self: &mut Self, token: &[u8]) {
        let remaining = self.slice.len() - self.cur_offset;
        let num_bytes_to_write = cmp::min(remaining, token.len());
        if num_bytes_to_write > 0 {
            self.slice[self.cur_offset..self.cur_offset+num_bytes_to_write].copy_from_slice(&token[..num_bytes_to_write]);
            self.cur_offset += num_bytes_to_write
        }
    }
}

impl<'buf, 'parse> FuzzFile<'buf, 'parse> {
    pub fn new(parsed: &'parse ParsedFile<'buf>) -> Self {
        FuzzFile {
            root: Cow::from(parsed.root.as_slice()),
            nodes: Cow::from(parsed.nodes.as_slice()),
            ranges: Cow::from(parsed.ranges.as_slice()),
        }
    }

    fn serialize_noderef<S: SerializeInto>(self: &Self, noderef: NodeRef, mut state: &mut SerializeState, mut out: &mut S) {
        match self.nodes[noderef] {
            Node::Delim(prefix, rangeref, postfix) => {
                out.push(prefix);
                if state.should_serialize(rangeref) {
                    for noderef in &self.ranges[rangeref] {
                        self.serialize_noderef(*noderef, &mut state, out)
                    }
                    state.reset(rangeref);
                }
                out.push(postfix);
            },
            Node::Range(rangeref) => {
                if state.should_serialize(rangeref) {
                    for noderef in &self.ranges[rangeref] {
                        self.serialize_noderef(*noderef, &mut state, out)
                    }
                    state.reset(rangeref);
                }
            },
            Node::Token(token) => out.push(token),
        }
    }

    pub fn serialize<S: SerializeInto>(self: &Self, out: &mut S) {
        let mut state = SerializeState::new(&self.ranges[..]);

        for noderef in self.root.iter() {
            self.serialize_noderef(*noderef, &mut state, out);
        }
    }

    pub fn swap_ranges<R: Rng>(self: &mut Self, rng: &mut R) -> bool {
        match rand_indices::<R, _>(rng, &self.ranges[..]) {
            Some((index0, index1)) => {
                let mut ranges = self.ranges.to_mut();
                ranges.swap(index0, index1);
                true
            },
            None => false,
        }
    }

    pub fn shuffle_range<R: Rng>(self: &mut Self, rng: &mut R) -> bool {
        match rng.choose_mut(self.ranges.to_mut()) {
            Some(range) => {
                rng.shuffle(range);
                true
            },
            None => false,
        }
    }

    pub fn duplicate_range<R: Rng>(self: &mut Self, rng: &mut R, max_duplications: usize) -> bool {
        if max_duplications < 1 {
            return false
        }

        match rng.choose_mut(self.ranges.to_mut()) {
            Some(range) => {
                let num_duplications = rng.gen_range(1, max_duplications);
                let mut extension = Vec::new();
                for _ in 0..num_duplications {
                    extension.extend(&range[..])
                }
                range.extend(&extension[..]);
                true
            },
            None => false,
        }
    }

    pub fn duplicate_root_node<R: Rng>(self: &mut Self, rng: &mut R) -> bool {
        match rand_indices::<R, _>(rng, &self.ranges[..]) {
            Some((src_index, dst_index)) => {
                let mut nodes = self.nodes.to_mut();

                let dup_node = nodes[dst_index].clone();
                let noderef = nodes.len();
                nodes.push(dup_node);

                let ranges = self.ranges.to_mut();
                let range = vec![noderef, src_index];
                let rangeref = ranges.len();
                ranges.push(range);

                nodes[dst_index] = Node::Range(rangeref);
                true
            },
            None => false,
        }
    }

    pub fn remove_delim<R: Rng>(self: &mut Self, mut rng: &mut R) -> bool {
        match rand_delim(&mut rng, &self.nodes[..]) {
            Some((index, _, rangeref, _)) => {
                let mut nodes = self.nodes.to_mut();
                nodes[index] = Node::Range(rangeref);
                true
            },
            None => false,
        }
    }

    pub fn swap_delim<R: Rng>(self: &mut Self, mut rng: &mut R) -> bool {
        match rand_delim(&mut rng, &self.nodes[..]) {
            Some((index, start_pattern, rangeref, end_pattern)) => {
                let mut nodes = self.nodes.to_mut();
                nodes[index] = Node::Delim(end_pattern, rangeref, start_pattern);
                true
            },
            None => false,
        }
    }
}

pub fn fuzz_one<'buf, 'parse, R: Rng>(parsed: &'parse ParsedFile<'buf>, mut rng: &mut R, config: &FuzzConfig) -> Option<FuzzFile<'buf, 'parse>> {
    let mut ff = FuzzFile::new(parsed);
    let mut did_mutate = false;
    for _ in 0..config.max_mutations {
        did_mutate |= match rng.gen() {
            FuzzAction::DuplicateRange => ff.duplicate_range(&mut rng, config.max_duplications),
            FuzzAction::DuplicateRootNode => ff.duplicate_root_node(&mut rng),
            FuzzAction::RemoveDelim => ff.remove_delim(&mut rng),
            FuzzAction::ShuffleRanges => ff.shuffle_range(&mut rng),
            FuzzAction::SwapDelim => ff.swap_delim(&mut rng),
            FuzzAction::SwapRanges => ff.swap_ranges(&mut rng),
        }
    }

    if did_mutate {
        Some(ff)
    } else {
        None
    }
}
<commit_msg>rand_delim returns a NodeRef.<commit_after>extern crate rand;

use std::borrow::Cow;
use std::cmp;
use self::rand::{Rand, Rng};
use parse::{Node, NodeRef, ParsedFile, RangeRef};

#[derive(Debug)]
pub struct FuzzFile<'buf: 'parse, 'parse> {
    root: Cow<'parse, [NodeRef]>,
    nodes: Cow<'parse, [Node<'buf>]>,
    ranges: Cow<'parse, [Vec<NodeRef>]>,
}

#[derive(Clone)]
pub enum FuzzAction {
    DuplicateRange,
    DuplicateRootNode,
    RemoveDelim,
    ShuffleRanges,
    SwapDelim,
    SwapRanges,
}

pub struct FuzzConfig {
    pub max_mutations: usize,
    pub max_duplications: usize,
}

impl Rand for FuzzAction {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        let actions = vec![
            FuzzAction::DuplicateRange,
            FuzzAction::DuplicateRootNode,
            FuzzAction::RemoveDelim,
            FuzzAction::ShuffleRanges,
            FuzzAction::SwapDelim,
            FuzzAction::SwapRanges,
        ];
        rng.choose(&actions).unwrap().clone()
    }
}

fn rand_indices<R: Rng, T>(mut rng: &mut Rng, x: &[T]) -> Option<(usize, usize)> {
    if x.len() > 1 {
        let indices = rand::sample(&mut rng, 0..x.len(), 2);
        Some((indices[0], indices[1]))
    } else {
        None
    }
}

fn rand_delim<'buf, R: Rng>(mut rng: &mut R, nodes: &[Node<'buf>]) -> Option<(NodeRef, &'buf [u8], RangeRef, &'buf [u8])> {
    let delims: Vec<_> = nodes.iter().enumerate().filter_map(|item| {
        match item {
            (index, &Node::Delim(start_pattern, rangeref, end_pattern)) => {
                Some((index, start_pattern, rangeref, end_pattern))
            },
            _ => None,
        }
    }).collect();
    rng.choose(&delims[..]).cloned()
}

struct SerializeState {
    have_serialized_range: Vec<bool>,
}

impl SerializeState {
    fn new(ranges: &[Vec<NodeRef>]) -> Self {
        SerializeState {
            have_serialized_range: ranges.iter().map(|_| false).collect()
        }
    }

    fn should_serialize(self: &mut Self, rangeref: RangeRef) -> bool {
        if self.have_serialized_range[rangeref] {
            false
        } else {
            self.have_serialized_range[rangeref] = true;
            true
        }
    }

    fn reset(self: &mut Self, rangeref: RangeRef) {
        self.have_serialized_range[rangeref] = false;
    }
}

pub trait SerializeInto {
    fn push(&mut self, &[u8]);
}

impl SerializeInto for Vec<u8> {
    fn push(self: &mut Self, token: &[u8]) {
        self.extend(token);
    }
}

pub struct SliceSerializer<'buf> {
    slice: &'buf mut [u8],
    cur_offset: usize,
}

impl<'buf> SliceSerializer<'buf> {
    pub fn new(slice: &'buf mut [u8]) -> SliceSerializer {
        SliceSerializer {
            slice: slice,
            cur_offset: 0,
        }
    }

    pub fn bytes_written(self: &Self) -> usize {
        self.cur_offset
    }
}

impl<'buf> SerializeInto for SliceSerializer<'buf> {
    fn push(self: &mut Self, token: &[u8]) {
        let remaining = self.slice.len() - self.cur_offset;
        let num_bytes_to_write = cmp::min(remaining, token.len());
        if num_bytes_to_write > 0 {
            self.slice[self.cur_offset..self.cur_offset+num_bytes_to_write].copy_from_slice(&token[..num_bytes_to_write]);
            self.cur_offset += num_bytes_to_write
        }
    }
}

impl<'buf, 'parse> FuzzFile<'buf, 'parse> {
    pub fn new(parsed: &'parse ParsedFile<'buf>) -> Self {
        FuzzFile {
            root: Cow::from(parsed.root.as_slice()),
            nodes: Cow::from(parsed.nodes.as_slice()),
            ranges: Cow::from(parsed.ranges.as_slice()),
        }
    }

    fn serialize_noderef<S: SerializeInto>(self: &Self, noderef: NodeRef, mut state: &mut SerializeState, mut out: &mut S) {
        match self.nodes[noderef] {
            Node::Delim(prefix, rangeref, postfix) => {
                out.push(prefix);
                if state.should_serialize(rangeref) {
                    for noderef in &self.ranges[rangeref] {
                        self.serialize_noderef(*noderef, &mut state, out)
                    }
                    state.reset(rangeref);
                }
                out.push(postfix);
            },
            Node::Range(rangeref) => {
                if state.should_serialize(rangeref) {
                    for noderef in &self.ranges[rangeref] {
                        self.serialize_noderef(*noderef, &mut state, out)
                    }
                    state.reset(rangeref);
                }
            },
            Node::Token(token) => out.push(token),
        }
    }

    pub fn serialize<S: SerializeInto>(self: &Self, out: &mut S) {
        let mut state = SerializeState::new(&self.ranges[..]);

        for noderef in self.root.iter() {
            self.serialize_noderef(*noderef, &mut state, out);
        }
    }

    pub fn swap_ranges<R: Rng>(self: &mut Self, rng: &mut R) -> bool {
        match rand_indices::<R, _>(rng, &self.ranges[..]) {
            Some((index0, index1)) => {
                let mut ranges = self.ranges.to_mut();
                ranges.swap(index0, index1);
                true
            },
            None => false,
        }
    }

    pub fn shuffle_range<R: Rng>(self: &mut Self, rng: &mut R) -> bool {
        match rng.choose_mut(self.ranges.to_mut()) {
            Some(range) => {
                rng.shuffle(range);
                true
            },
            None => false,
        }
    }

    pub fn duplicate_range<R: Rng>(self: &mut Self, rng: &mut R, max_duplications: usize) -> bool {
        if max_duplications < 1 {
            return false
        }

        match rng.choose_mut(self.ranges.to_mut()) {
            Some(range) => {
                let num_duplications = rng.gen_range(1, max_duplications);
                let mut extension = Vec::new();
                for _ in 0..num_duplications {
                    extension.extend(&range[..])
                }
                range.extend(&extension[..]);
                true
            },
            None => false,
        }
    }

    pub fn duplicate_root_node<R: Rng>(self: &mut Self, rng: &mut R) -> bool {
        match rand_indices::<R, _>(rng, &self.ranges[..]) {
            Some((src_index, dst_index)) => {
                let mut nodes = self.nodes.to_mut();

                let dup_node = nodes[dst_index].clone();
                let noderef = nodes.len();
                nodes.push(dup_node);

                let ranges = self.ranges.to_mut();
                let range = vec![noderef, src_index];
                let rangeref = ranges.len();
                ranges.push(range);

                nodes[dst_index] = Node::Range(rangeref);
                true
            },
            None => false,
        }
    }

    pub fn remove_delim<R: Rng>(self: &mut Self, mut rng: &mut R) -> bool {
        match rand_delim(&mut rng, &self.nodes[..]) {
            Some((index, _, rangeref, _)) => {
                let mut nodes = self.nodes.to_mut();
                nodes[index] = Node::Range(rangeref);
                true
            },
            None => false,
        }
    }

    pub fn swap_delim<R: Rng>(self: &mut Self, mut rng: &mut R) -> bool {
        match rand_delim(&mut rng, &self.nodes[..]) {
            Some((index, start_pattern, rangeref, end_pattern)) => {
                let mut nodes = self.nodes.to_mut();
                nodes[index] = Node::Delim(end_pattern, rangeref, start_pattern);
                true
            },
            None => false,
        }
    }
}

pub fn fuzz_one<'buf, 'parse, R: Rng>(parsed: &'parse ParsedFile<'buf>, mut rng: &mut R, config: &FuzzConfig) -> Option<FuzzFile<'buf, 'parse>> {
    let mut ff = FuzzFile::new(parsed);
    let mut did_mutate = false;
    for _ in 0..config.max_mutations {
        did_mutate |= match rng.gen() {
            FuzzAction::DuplicateRange => ff.duplicate_range(&mut rng, config.max_duplications),
            FuzzAction::DuplicateRootNode => ff.duplicate_root_node(&mut rng),
            FuzzAction::RemoveDelim => ff.remove_delim(&mut rng),
            FuzzAction::ShuffleRanges => ff.shuffle_range(&mut rng),
            FuzzAction::SwapDelim => ff.swap_delim(&mut rng),
            FuzzAction::SwapRanges => ff.swap_ranges(&mut rng),
        }
    }

    if did_mutate {
        Some(ff)
    } else {
        None
    }
}
<|endoftext|>


<commit_before>fn last<'a, T>(list: &'a [T]) -> Option<&'a T> {
    match list {
        [] => None,
        [.., ref x] => Some(x)
    }
}

fn main() {
    let list: ~[char] = ~['a', 'b', 'c'];
    println!("{:?}", last(list));
    println!("{:?}", list.last()); // Cheat
}
<commit_msg>Remove unnecessary type annotation in Problem 01<commit_after>fn last<'a, T>(list: &'a [T]) -> Option<&'a T> {
    match list {
        [] => None,
        [.., ref x] => Some(x)
    }
}

fn main() {
    let list = ~['a', 'b', 'c'];
    println!("{:?}", last(list));
    println!("{:?}", list.last()); // Cheat
}
<|endoftext|>