rust/chg/src/message.rs
author Yuya Nishihara <yuya@tcha.org>
Thu, 04 Oct 2018 23:01:34 +0900
changeset 44674 8a7beeea655f
parent 43818 ce088b38f92b
child 44679 82adc720c0a3
permissions -rw-r--r--
rust-chg: add helper to pack environment variables On my machine, "printenv | wc -c" says 3422. That's the only reason why the initial buffer capacity is set to 4kB. Differential Revision: https://phab.mercurial-scm.org/D8363
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     1
// Copyright 2018 Yuya Nishihara <yuya@tcha.org>
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
//
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     3
// This software may be used and distributed according to the terms of the
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     4
// GNU General Public License version 2 or any later version.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     5
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     6
//! Utility for parsing and building command-server messages.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     7
44674
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
     8
use bytes::{BufMut, Bytes, BytesMut};
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     9
use std::error;
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    10
use std::ffi::{OsStr, OsString};
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    11
use std::io;
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    12
use std::os::unix::ffi::OsStrExt;
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    13
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    14
pub use tokio_hglib::message::*; // re-exports
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    15
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    16
/// Shell command type requested by the server.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    17
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    18
pub enum CommandType {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    19
    /// Pager should be spawned.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    20
    Pager,
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
    /// Shell command should be executed to send back the result code.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    22
    System,
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    23
}
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    24
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    25
/// Shell command requested by the server.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    26
#[derive(Clone, Debug, Eq, PartialEq)]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    27
pub struct CommandSpec {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    28
    pub command: OsString,
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    29
    pub current_dir: OsString,
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    30
    pub envs: Vec<(OsString, OsString)>,
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    31
}
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    32
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    33
/// Parses "S" channel request into command type and spec.
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    34
pub fn parse_command_spec(data: Bytes) -> io::Result<(CommandType, CommandSpec)> {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    35
    let mut split = data.split(|&c| c == b'\0');
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    36
    let ctype = parse_command_type(split.next().ok_or(new_parse_error("missing type"))?)?;
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    37
    let command = split.next().ok_or(new_parse_error("missing command"))?;
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    38
    let current_dir = split.next().ok_or(new_parse_error("missing current dir"))?;
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    39
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    40
    let mut envs = Vec::new();
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    41
    for l in split {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
        let mut s = l.splitn(2, |&c| c == b'=');
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    43
        let k = s.next().unwrap();
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    44
        let v = s.next().ok_or(new_parse_error("malformed env"))?;
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    45
        envs.push((
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    46
            OsStr::from_bytes(k).to_owned(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    47
            OsStr::from_bytes(v).to_owned(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    48
        ));
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    49
    }
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    50
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    51
    let spec = CommandSpec {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    52
        command: OsStr::from_bytes(command).to_owned(),
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    53
        current_dir: OsStr::from_bytes(current_dir).to_owned(),
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    54
        envs: envs,
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    55
    };
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    56
    Ok((ctype, spec))
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    57
}
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    58
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    59
fn parse_command_type(value: &[u8]) -> io::Result<CommandType> {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    60
    match value {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    61
        b"pager" => Ok(CommandType::Pager),
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    62
        b"system" => Ok(CommandType::System),
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    63
        _ => Err(new_parse_error(format!(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    64
            "unknown command type: {}",
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    65
            decode_latin1(value)
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
    66
        ))),
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    67
    }
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    68
}
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    69
44674
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    70
// allocate large buffer as environment variables can be quite long
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    71
const INITIAL_PACKED_ENV_VARS_CAPACITY: usize = 4096;
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    72
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    73
/// Packs environment variables of platform encoding into bytes.
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    74
///
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    75
/// # Panics
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    76
///
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    77
/// Panics if key or value contains `\0` character, or key contains '='
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    78
/// character.
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    79
pub fn pack_env_vars_os<I, P>(vars: I) -> Bytes
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    80
where
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    81
    I: IntoIterator<Item = (P, P)>,
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    82
    P: AsRef<OsStr>,
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    83
{
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    84
    let mut vars_iter = vars.into_iter();
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    85
    if let Some((k, v)) = vars_iter.next() {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    86
        let mut dst = BytesMut::with_capacity(INITIAL_PACKED_ENV_VARS_CAPACITY);
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    87
        pack_env_into(&mut dst, k.as_ref(), v.as_ref());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    88
        for (k, v) in vars_iter {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    89
            dst.reserve(1);
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    90
            dst.put_u8(b'\0');
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    91
            pack_env_into(&mut dst, k.as_ref(), v.as_ref());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    92
        }
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    93
        dst.freeze()
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    94
    } else {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    95
        Bytes::new()
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    96
    }
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    97
}
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    98
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
    99
fn pack_env_into(dst: &mut BytesMut, k: &OsStr, v: &OsStr) {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   100
    assert!(!k.as_bytes().contains(&0), "key shouldn't contain NUL");
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   101
    assert!(!k.as_bytes().contains(&b'='), "key shouldn't contain '='");
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   102
    assert!(!v.as_bytes().contains(&0), "value shouldn't contain NUL");
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   103
    dst.reserve(k.as_bytes().len() + 1 + v.as_bytes().len());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   104
    dst.put_slice(k.as_bytes());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   105
    dst.put_u8(b'=');
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   106
    dst.put_slice(v.as_bytes());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   107
}
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   108
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   109
fn decode_latin1<S>(s: S) -> String
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   110
where
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   111
    S: AsRef<[u8]>,
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   112
{
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   113
    s.as_ref().iter().map(|&c| c as char).collect()
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   114
}
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   115
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   116
fn new_parse_error<E>(error: E) -> io::Error
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   117
where
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   118
    E: Into<Box<error::Error + Send + Sync>>,
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   119
{
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   120
    io::Error::new(io::ErrorKind::InvalidData, error)
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   121
}
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   122
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   123
#[cfg(test)]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   124
mod tests {
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   125
    use super::*;
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   126
    use std::os::unix::ffi::OsStringExt;
44674
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   127
    use std::panic;
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   128
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   129
    #[test]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   130
    fn parse_command_spec_good() {
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   131
        let src = [
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   132
            b"pager".as_ref(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   133
            b"less -FRX".as_ref(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   134
            b"/tmp".as_ref(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   135
            b"LANG=C".as_ref(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   136
            b"HGPLAIN=".as_ref(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   137
        ]
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   138
        .join(&0);
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   139
        let spec = CommandSpec {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   140
            command: os_string_from(b"less -FRX"),
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   141
            current_dir: os_string_from(b"/tmp"),
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   142
            envs: vec![
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   143
                (os_string_from(b"LANG"), os_string_from(b"C")),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   144
                (os_string_from(b"HGPLAIN"), os_string_from(b"")),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   145
            ],
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   146
        };
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   147
        assert_eq!(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   148
            parse_command_spec(Bytes::from(src)).unwrap(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   149
            (CommandType::Pager, spec)
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39971
diff changeset
   150
        );
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   151
    }
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   152
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   153
    #[test]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   154
    fn parse_command_spec_too_short() {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   155
        assert!(parse_command_spec(Bytes::from_static(b"")).is_err());
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   156
        assert!(parse_command_spec(Bytes::from_static(b"pager")).is_err());
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   157
        assert!(parse_command_spec(Bytes::from_static(b"pager\0less")).is_err());
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   158
    }
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   159
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   160
    #[test]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   161
    fn parse_command_spec_malformed_env() {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   162
        assert!(parse_command_spec(Bytes::from_static(b"pager\0less\0/tmp\0HOME")).is_err());
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   163
    }
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   164
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   165
    #[test]
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   166
    fn parse_command_spec_unknown_type() {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   167
        assert!(parse_command_spec(Bytes::from_static(b"paper\0less")).is_err());
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   168
    }
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   169
44674
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   170
    #[test]
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   171
    fn pack_env_vars_os_good() {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   172
        assert_eq!(
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   173
            pack_env_vars_os(vec![] as Vec<(OsString, OsString)>),
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   174
            Bytes::new()
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   175
        );
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   176
        assert_eq!(
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   177
            pack_env_vars_os(vec![os_string_pair_from(b"FOO", b"bar")]),
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   178
            Bytes::from_static(b"FOO=bar")
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   179
        );
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   180
        assert_eq!(
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   181
            pack_env_vars_os(vec![
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   182
                os_string_pair_from(b"FOO", b""),
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   183
                os_string_pair_from(b"BAR", b"baz")
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   184
            ]),
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   185
            Bytes::from_static(b"FOO=\0BAR=baz")
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   186
        );
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   187
    }
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   188
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   189
    #[test]
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   190
    fn pack_env_vars_os_large_key() {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   191
        let mut buf = vec![b'A'; INITIAL_PACKED_ENV_VARS_CAPACITY];
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   192
        let envs = vec![os_string_pair_from(&buf, b"")];
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   193
        buf.push(b'=');
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   194
        assert_eq!(pack_env_vars_os(envs), Bytes::from(buf));
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   195
    }
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   196
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   197
    #[test]
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   198
    fn pack_env_vars_os_large_value() {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   199
        let mut buf = vec![b'A', b'='];
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   200
        buf.resize(INITIAL_PACKED_ENV_VARS_CAPACITY + 1, b'a');
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   201
        let envs = vec![os_string_pair_from(&buf[..1], &buf[2..])];
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   202
        assert_eq!(pack_env_vars_os(envs), Bytes::from(buf));
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   203
    }
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   204
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   205
    #[test]
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   206
    fn pack_env_vars_os_nul_eq() {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   207
        assert!(panic::catch_unwind(|| {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   208
            pack_env_vars_os(vec![os_string_pair_from(b"\0", b"")])
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   209
        })
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   210
        .is_err());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   211
        assert!(panic::catch_unwind(|| {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   212
            pack_env_vars_os(vec![os_string_pair_from(b"FOO", b"\0bar")])
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   213
        })
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   214
        .is_err());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   215
        assert!(panic::catch_unwind(|| {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   216
            pack_env_vars_os(vec![os_string_pair_from(b"FO=", b"bar")])
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   217
        })
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   218
        .is_err());
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   219
        assert_eq!(
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   220
            pack_env_vars_os(vec![os_string_pair_from(b"FOO", b"=ba")]),
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   221
            Bytes::from_static(b"FOO==ba")
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   222
        );
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   223
    }
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   224
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   225
    fn os_string_from(s: &[u8]) -> OsString {
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   226
        OsString::from_vec(s.to_vec())
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   227
    }
44674
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   228
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   229
    fn os_string_pair_from(k: &[u8], v: &[u8]) -> (OsString, OsString) {
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   230
        (os_string_from(k), os_string_from(v))
8a7beeea655f rust-chg: add helper to pack environment variables
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
   231
    }
39971
b1d8acd82d60 rust-chg: add parser for request messages sent to "S" channel
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   232
}