<commit_before>use clap::{App, Arg};

#[test]
fn flag_subcommand_normal() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").short_flag('S').long_flag("some").arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "some", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_normal_with_alias() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .long_flag("S")
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .alias("result"),
        )
        .get_matches_from(vec!["myprog", "result", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").short_flag('S').arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "-S", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short_with_args() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").short_flag('S').arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "-St"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short_with_alias() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_alias('M')
                .short_flag_alias('B'),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short_with_aliases_vis_and_hidden() {
    let app = App::new("test").subcommand(
        App::new("some")
            .short_flag('S')
            .arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            )
            .visible_short_flag_aliases(&['M', 'B'])
            .short_flag_alias('C'),
    );
    let app1 = app.clone();
    let matches1 = app1.get_matches_from(vec!["test", "-M"]);
    assert_eq!(matches1.subcommand_name().unwrap(), "some");

    let app2 = app.clone();
    let matches2 = app2.get_matches_from(vec!["test", "-C"]);
    assert_eq!(matches2.subcommand_name().unwrap(), "some");

    let app3 = app.clone();
    let matches3 = app3.get_matches_from(vec!["test", "-B"]);
    assert_eq!(matches3.subcommand_name().unwrap(), "some");
}

#[test]
fn flag_subcommand_short_with_aliases() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_aliases(&['M', 'B']),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
#[should_panic]
fn flag_subcommand_short_with_alias_hyphen() {
    let _ = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_alias('-'),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
}

#[test]
#[should_panic]
fn flag_subcommand_short_with_aliases_hyphen() {
    let _ = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_aliases(&['-', '-', '-']),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
}

#[test]
fn flag_subcommand_long() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").long_flag("some").arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "--some", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_long_with_alias() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .long_flag("some")
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .alias("result"),
        )
        .get_matches_from(vec!["myprog", "--result", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_multiple() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .long_flag("some")
                .arg(Arg::from("-f, --flag 'some flag'"))
                .arg(Arg::from("-p, --print 'print something'"))
                .subcommand(
                    App::new("result")
                        .short_flag('R')
                        .long_flag("result")
                        .arg(Arg::from("-f, --flag 'some flag'"))
                        .arg(Arg::from("-p, --print 'print something'")),
                ),
        )
        .get_matches_from(vec!["myprog", "-SfpRfp"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("flag"));
    assert!(sub_matches.is_present("print"));
    assert_eq!(sub_matches.subcommand_name().unwrap(), "result");
    let result_matches = sub_matches.subcommand_matches("result").unwrap();
    assert!(result_matches.is_present("flag"));
    assert!(result_matches.is_present("print"));
}

#[test]
#[should_panic = "Short option names must be unique for each argument, but \'-f\' is used by both an App named \'some\' and an Arg named \'test\'"]
fn flag_subcommand_short_conflict_with_arg() {
    let _ = App::new("test")
        .subcommand(App::new("some").short_flag('f').long_flag("some"))
        .arg(Arg::new("test").short('f'))
        .get_matches_from(vec!["myprog", "-ff"]);
}

#[test]
#[should_panic = "Long option names must be unique for each argument, but \'--flag\' is used by both an App named \'some\' and an Arg named \'flag\'"]
fn flag_subcommand_long_conflict_with_arg() {
    let _ = App::new("test")
        .subcommand(App::new("some").short_flag('a').long_flag("flag"))
        .arg(Arg::new("flag").long("flag"))
        .get_matches_from(vec!["myprog", "--flag"]);
}

#[test]
fn flag_subcommand_conflict_with_help() {
    let _ = App::new("test")
        .subcommand(App::new("help").short_flag('h').long_flag("help"))
        .get_matches_from(vec!["myprog", "--help"]);
}

#[test]
fn flag_subcommand_conflict_with_version() {
    let _ = App::new("test")
        .subcommand(App::new("ver").short_flag('V').long_flag("version"))
        .get_matches_from(vec!["myprog", "--version"]);
}
<commit_msg>fix: duplicate short flags in Flag Subcommand test<commit_after>use clap::{App, Arg};

#[test]
fn flag_subcommand_normal() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").short_flag('S').long_flag("some").arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "some", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_normal_with_alias() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .long_flag("S")
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .alias("result"),
        )
        .get_matches_from(vec!["myprog", "result", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").short_flag('S').arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "-S", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short_with_args() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").short_flag('S').arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "-St"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short_with_alias() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_alias('M')
                .short_flag_alias('B'),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_short_with_aliases_vis_and_hidden() {
    let app = App::new("test").subcommand(
        App::new("some")
            .short_flag('S')
            .arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            )
            .visible_short_flag_aliases(&['M', 'B'])
            .short_flag_alias('C'),
    );
    let app1 = app.clone();
    let matches1 = app1.get_matches_from(vec!["test", "-M"]);
    assert_eq!(matches1.subcommand_name().unwrap(), "some");

    let app2 = app.clone();
    let matches2 = app2.get_matches_from(vec!["test", "-C"]);
    assert_eq!(matches2.subcommand_name().unwrap(), "some");

    let app3 = app.clone();
    let matches3 = app3.get_matches_from(vec!["test", "-B"]);
    assert_eq!(matches3.subcommand_name().unwrap(), "some");
}

#[test]
fn flag_subcommand_short_with_aliases() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_aliases(&['M', 'B']),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
#[should_panic]
fn flag_subcommand_short_with_alias_hyphen() {
    let _ = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_alias('-'),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
}

#[test]
#[should_panic]
fn flag_subcommand_short_with_aliases_hyphen() {
    let _ = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .short_flag_aliases(&['-', '-', '-']),
        )
        .get_matches_from(vec!["myprog", "-Bt"]);
}

#[test]
fn flag_subcommand_long() {
    let matches = App::new("test")
        .subcommand(
            App::new("some").long_flag("some").arg(
                Arg::new("test")
                    .short('t')
                    .long("test")
                    .about("testing testing"),
            ),
        )
        .get_matches_from(vec!["myprog", "--some", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_long_with_alias() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .long_flag("some")
                .arg(
                    Arg::new("test")
                        .short('t')
                        .long("test")
                        .about("testing testing"),
                )
                .alias("result"),
        )
        .get_matches_from(vec!["myprog", "--result", "--test"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("test"));
}

#[test]
fn flag_subcommand_multiple() {
    let matches = App::new("test")
        .subcommand(
            App::new("some")
                .short_flag('S')
                .long_flag("some")
                .arg(Arg::from("-f, --flag 'some flag'"))
                .arg(Arg::from("-p, --print 'print something'"))
                .subcommand(
                    App::new("result")
                        .short_flag('R')
                        .long_flag("result")
                        .arg(Arg::from("-f, --flag 'some flag'"))
                        .arg(Arg::from("-p, --print 'print something'")),
                ),
        )
        .get_matches_from(vec!["myprog", "-SfpRfp"]);
    assert_eq!(matches.subcommand_name().unwrap(), "some");
    let sub_matches = matches.subcommand_matches("some").unwrap();
    assert!(sub_matches.is_present("flag"));
    assert!(sub_matches.is_present("print"));
    assert_eq!(sub_matches.subcommand_name().unwrap(), "result");
    let result_matches = sub_matches.subcommand_matches("result").unwrap();
    assert!(result_matches.is_present("flag"));
    assert!(result_matches.is_present("print"));
}

#[test]
#[should_panic = "Short option names must be unique for each argument, but \'-f\' is used by both an App named \'some\' and an Arg named \'test\'"]
fn flag_subcommand_short_conflict_with_arg() {
    let _ = App::new("test")
        .subcommand(App::new("some").short_flag('f').long_flag("some"))
        .arg(Arg::new("test").short('f'))
        .get_matches_from(vec!["myprog", "-f"]);
}

#[test]
#[should_panic = "Long option names must be unique for each argument, but \'--flag\' is used by both an App named \'some\' and an Arg named \'flag\'"]
fn flag_subcommand_long_conflict_with_arg() {
    let _ = App::new("test")
        .subcommand(App::new("some").short_flag('a').long_flag("flag"))
        .arg(Arg::new("flag").long("flag"))
        .get_matches_from(vec!["myprog", "--flag"]);
}

#[test]
fn flag_subcommand_conflict_with_help() {
    let _ = App::new("test")
        .subcommand(App::new("help").short_flag('h').long_flag("help"))
        .get_matches_from(vec!["myprog", "--help"]);
}

#[test]
fn flag_subcommand_conflict_with_version() {
    let _ = App::new("test")
        .subcommand(App::new("ver").short_flag('V').long_flag("version"))
        .get_matches_from(vec!["myprog", "--version"]);
}
<|endoftext|>


<commit_before>//! Connector with hyper backend.

use std::str::FromStr;

use futures::TryStreamExt;
use hyper::client::Client;
use hyper::header::CONTENT_TYPE;
use hyper::{Method, Request, Uri};
use hyper_tls::HttpsConnector;

use telegram_bot_raw::{Body as TelegramBody, HttpRequest, HttpResponse, Method as TelegramMethod};

use crate::errors::Error;

pub(crate) async fn request(token: &str, req: HttpRequest) -> Result<HttpResponse, Error> {
    let uri = Uri::from_str(&req.url.url(token))?;

    let method = match req.method {
        TelegramMethod::Get => Method::GET,
        TelegramMethod::Post => Method::POST,
    };

    let mut http_request = Request::builder();
    http_request.method(method).uri(uri);

    let request = match req.body {
        TelegramBody::Empty => http_request.body(Into::<hyper::Body>::into(vec![])),
        TelegramBody::Json(body) => {
            http_request
                .headers_mut()
                .map(|headers| headers.insert(CONTENT_TYPE, "application/json".parse().unwrap()));
            http_request.body(Into::<hyper::Body>::into(body))
        }
        body => panic!("Unknown body type {:?}", body),
    };

    let connector = HttpsConnector::new(1).map_err(|err| {
        ::std::io::Error::new(::std::io::ErrorKind::Other, format!("tls error: {}", err))
    })?;

    let client = Client::builder().build(connector);

    let response = client.request(request.unwrap()).await?;

    let whole_chunk = response.into_body().try_concat().await;

    let body = whole_chunk
        .iter()
        .fold(vec![], |mut acc, chunk| -> Vec<u8> {
            acc.extend_from_slice(&chunk);
            acc
        });

    Ok(HttpResponse { body: Some(body) })
}
<commit_msg>Fix HttpsConnector<commit_after>//! Connector with hyper backend.

use std::str::FromStr;

use futures::TryStreamExt;
use hyper::client::Client;
use hyper::header::CONTENT_TYPE;
use hyper::{Method, Request, Uri};
use hyper_tls::HttpsConnector;

use telegram_bot_raw::{Body as TelegramBody, HttpRequest, HttpResponse, Method as TelegramMethod};

use crate::errors::Error;

pub(crate) async fn request(token: &str, req: HttpRequest) -> Result<HttpResponse, Error> {
    let uri = Uri::from_str(&req.url.url(token))?;

    let method = match req.method {
        TelegramMethod::Get => Method::GET,
        TelegramMethod::Post => Method::POST,
    };

    let mut http_request = Request::builder();
    http_request.method(method).uri(uri);

    let request = match req.body {
        TelegramBody::Empty => http_request.body(Into::<hyper::Body>::into(vec![])),
        TelegramBody::Json(body) => {
            http_request
                .headers_mut()
                .map(|headers| headers.insert(CONTENT_TYPE, "application/json".parse().unwrap()));
            http_request.body(Into::<hyper::Body>::into(body))
        }
        body => panic!("Unknown body type {:?}", body),
    };

    let connector = HttpsConnector::new().map_err(|err| {
        ::std::io::Error::new(::std::io::ErrorKind::Other, format!("tls error: {}", err))
    })?;

    let client = Client::builder().build(connector);

    let response = client.request(request.unwrap()).await?;

    let whole_chunk = response.into_body().try_concat().await;

    let body = whole_chunk
        .iter()
        .fold(vec![], |mut acc, chunk| -> Vec<u8> {
            acc.extend_from_slice(&chunk);
            acc
        });

    Ok(HttpResponse { body: Some(body) })
}
<|endoftext|>


<commit_before>use bytecount::naive_count_32;
use regex::Regex;

lazy_static! {
    static ref PAT_TOKENS: Regex = Regex::new(r#"(?xm)
          (?:\(:)
        | (?:=>)
        | "
        | (?:\n\x20*)
        | =
        | \(
        | \)
        | \s+
        | [^\(\)=\s"]+"#).expect("Failed to compile lexer regex");
}

#[derive(Debug, PartialEq)]
pub enum Token<'a> {
    StartBlock(i32),
    RightParen,
    Rocket,
    Indent,
    Dedent,
    Text(i32, &'a str),
    Character(i32, char),
    Quote(i32),
}

pub fn lex(data: &str) -> Vec<Token> {
    let data_bytes = data.as_bytes();
    let mut lineno: i32 = 0;
    let mut last_match_start: usize = 0;
    let mut tokens: Vec<Token> = vec![];
    let mut indent: Vec<usize> = vec![0];
    let mut start_rocket = false;

    for pat_match in PAT_TOKENS.find_iter(data) {
        lineno += naive_count_32(&data_bytes[last_match_start..pat_match.start()], b'\n') as i32;
        last_match_start = pat_match.start();
        let token_text = pat_match.as_str();
        let bytes = token_text.as_bytes();
        let token = match bytes[0] {
            b')' => Token::RightParen,
            b'"' => Token::Quote(lineno),
            b'\n' => {
                tokens.push(Token::Character(lineno, '\n'));

                // If the line is empty, ignore it.
                if data_bytes.get(pat_match.end()) == Some(&b'\n') {
                    continue;
                }

                // Subtract one for the leading newline
                let new_indentation_level = token_text.len() - 1;

                let mut current_indentation_level =
                    *(indent.last().expect("Indentation stack is empty"));
                while new_indentation_level < current_indentation_level {
                    indent.pop();
                    current_indentation_level =
                        *(indent.last().expect("Indentation stack is empty"));
                    tokens.push(Token::Dedent);
                }

                if start_rocket {
                    indent.push(new_indentation_level);
                    tokens.push(Token::Indent);
                    start_rocket = false;
                }

                continue;
            }
            b'(' => match bytes.get(1) {
                Some(&b':') => Token::StartBlock(lineno),
                None => Token::Character(lineno, '('),
                _ => panic!("Bad character matched: Expected ':' or nothing"),
            },
            b'=' => match bytes.get(1) {
                Some(&b'>') => {
                    start_rocket = true;
                    Token::Rocket
                }
                None => Token::Character(lineno, '='),
                _ => panic!("Bad character matched: Expected '>' or nothing"),
            },
            _ => Token::Text(lineno, token_text),
        };

        tokens.push(token)
    }

    while indent.len() > 1 {
        tokens.push(Token::Dedent);
        indent.pop();
    }

    tokens
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_empty() {
        assert_eq!(lex(""), vec![]);
    }

    #[test]
    fn test_expression() {
        assert_eq!(
            lex(r#"(:foo bar (:a "b c") "baz" )"#),
            vec![
                Token::StartBlock(0),
                Token::Text(0, "foo"),
                Token::Text(0, " "),
                Token::Text(0, "bar"),
                Token::Text(0, " "),
                Token::StartBlock(0),
                Token::Text(0, "a"),
                Token::Text(0, " "),
                Token::Quote(0),
                Token::Text(0, "b"),
                Token::Text(0, " "),
                Token::Text(0, "c"),
                Token::Quote(0),
                Token::RightParen,
                Token::Text(0, " "),
                Token::Quote(0),
                Token::Text(0, "baz"),
                Token::Quote(0),
                Token::Text(0, " "),
                Token::RightParen,
            ]
        );
    }

    #[test]
    fn test_rocket() {
        assert_eq!(
            lex(
                r#"
(:note "a title" =>
  stuff 1

  stuff 2

  (:note =>
    more stuff

    second paragraph

  closing nested
"#
            ),
            vec![
                Token::Character(0, '\n'),
                Token::StartBlock(1),
                Token::Text(1, "note"),
                Token::Text(1, " "),
                Token::Quote(1),
                Token::Text(1, "a"),
                Token::Text(1, " "),
                Token::Text(1, "title"),
                Token::Quote(1),
                Token::Text(1, " "),
                Token::Rocket,
                Token::Character(1, '\n'),
                Token::Indent,
                Token::Text(2, "stuff"),
                Token::Text(2, " "),
                Token::Text(2, "1"),
                Token::Character(2, '\n'),
                Token::Character(3, '\n'),
                Token::Text(4, "stuff"),
                Token::Text(4, " "),
                Token::Text(4, "2"),
                Token::Character(4, '\n'),
                Token::Character(5, '\n'),
                Token::StartBlock(6),
                Token::Text(6, "note"),
                Token::Text(6, " "),
                Token::Rocket,
                Token::Character(6, '\n'),
                Token::Indent,
                Token::Text(7, "more"),
                Token::Text(7, " "),
                Token::Text(7, "stuff"),
                Token::Character(7, '\n'),
                Token::Character(8, '\n'),
                Token::Text(9, "second"),
                Token::Text(9, " "),
                Token::Text(9, "paragraph"),
                Token::Character(9, '\n'),
                Token::Character(10, '\n'),
                Token::Dedent,
                Token::Text(11, "closing"),
                Token::Text(11, " "),
                Token::Text(11, "nested"),
                Token::Character(11, '\n'),
                Token::Dedent,
            ]
        );
    }
}
<commit_msg>Only lex => as a rocket at the end of a line<commit_after>use bytecount::naive_count_32;
use regex::Regex;

lazy_static! {
    static ref PAT_TOKENS: Regex = Regex::new(r#"(?xm)
          (?:\(:)
        | (?:=>)
        | "
        | (?:\n\x20*)
        | =
        | \(
        | \)
        | \s+
        | [^\(\)=\s"]+"#).expect("Failed to compile lexer regex");
}

#[derive(Debug, PartialEq)]
pub enum Token<'a> {
    StartBlock(i32),
    RightParen,
    Rocket,
    Indent,
    Dedent,
    Text(i32, &'a str),
    Character(i32, char),
    Quote(i32),
}

pub fn lex(data: &str) -> Vec<Token> {
    let data_bytes = data.as_bytes();
    let mut lineno: i32 = 0;
    let mut last_match_start: usize = 0;
    let mut tokens: Vec<Token> = vec![];
    let mut indent: Vec<usize> = vec![0];
    let mut start_rocket = false;

    for pat_match in PAT_TOKENS.find_iter(data) {
        lineno += naive_count_32(&data_bytes[last_match_start..pat_match.start()], b'\n') as i32;
        last_match_start = pat_match.start();
        let token_text = pat_match.as_str();
        let bytes = token_text.as_bytes();
        let token = match bytes[0] {
            b')' => Token::RightParen,
            b'"' => Token::Quote(lineno),
            b'\n' => {
                tokens.push(Token::Character(lineno, '\n'));

                // If the line is empty, ignore it.
                if data_bytes.get(pat_match.end()) == Some(&b'\n') {
                    continue;
                }

                // Subtract one for the leading newline
                let new_indentation_level = token_text.len() - 1;

                let mut current_indentation_level =
                    *(indent.last().expect("Indentation stack is empty"));
                while new_indentation_level < current_indentation_level {
                    indent.pop();
                    current_indentation_level =
                        *(indent.last().expect("Indentation stack is empty"));
                    tokens.push(Token::Dedent);
                }

                if start_rocket {
                    indent.push(new_indentation_level);
                    tokens.push(Token::Indent);
                    start_rocket = false;
                }

                continue;
            }
            b'(' => match bytes.get(1) {
                Some(&b':') => Token::StartBlock(lineno),
                None => Token::Character(lineno, '('),
                _ => panic!("Bad character matched: Expected ':' or nothing"),
            },
            b'=' => {
                let next = data_bytes.get(pat_match.end());
                if next != Some(&b'\n') {
                    Token::Text(lineno, token_text)
                } else if bytes == b"=>" {
                    start_rocket = true;
                    Token::Rocket
                } else {
                    Token::Character(lineno, '=')
                }
            },
            _ => Token::Text(lineno, token_text),
        };

        tokens.push(token)
    }

    while indent.len() > 1 {
        tokens.push(Token::Dedent);
        indent.pop();
    }

    tokens
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_empty() {
        assert_eq!(lex(""), vec![]);
    }

    #[test]
    fn test_expression() {
        assert_eq!(
            lex(r#"(:foo bar (:a "b c") "baz" )"#),
            vec![
                Token::StartBlock(0),
                Token::Text(0, "foo"),
                Token::Text(0, " "),
                Token::Text(0, "bar"),
                Token::Text(0, " "),
                Token::StartBlock(0),
                Token::Text(0, "a"),
                Token::Text(0, " "),
                Token::Quote(0),
                Token::Text(0, "b"),
                Token::Text(0, " "),
                Token::Text(0, "c"),
                Token::Quote(0),
                Token::RightParen,
                Token::Text(0, " "),
                Token::Quote(0),
                Token::Text(0, "baz"),
                Token::Quote(0),
                Token::Text(0, " "),
                Token::RightParen,
            ]
        );
    }

    #[test]
    fn test_rocket() {
        assert_eq!(
            lex(
                r#"
(:note "a title" =>
  stuff 1

  stuff 2

  (:note =>
    more stuff

    second =>paragraph

  closing nested
"#
            ),
            vec![
                Token::Character(0, '\n'),
                Token::StartBlock(1),
                Token::Text(1, "note"),
                Token::Text(1, " "),
                Token::Quote(1),
                Token::Text(1, "a"),
                Token::Text(1, " "),
                Token::Text(1, "title"),
                Token::Quote(1),
                Token::Text(1, " "),
                Token::Rocket,
                Token::Character(1, '\n'),
                Token::Indent,
                Token::Text(2, "stuff"),
                Token::Text(2, " "),
                Token::Text(2, "1"),
                Token::Character(2, '\n'),
                Token::Character(3, '\n'),
                Token::Text(4, "stuff"),
                Token::Text(4, " "),
                Token::Text(4, "2"),
                Token::Character(4, '\n'),
                Token::Character(5, '\n'),
                Token::StartBlock(6),
                Token::Text(6, "note"),
                Token::Text(6, " "),
                Token::Rocket,
                Token::Character(6, '\n'),
                Token::Indent,
                Token::Text(7, "more"),
                Token::Text(7, " "),
                Token::Text(7, "stuff"),
                Token::Character(7, '\n'),
                Token::Character(8, '\n'),
                Token::Text(9, "second"),
                Token::Text(9, " "),
                Token::Text(9, "=>"),
                Token::Text(9, "paragraph"),
                Token::Character(9, '\n'),
                Token::Character(10, '\n'),
                Token::Dedent,
                Token::Text(11, "closing"),
                Token::Text(11, " "),
                Token::Text(11, "nested"),
                Token::Character(11, '\n'),
                Token::Dedent,
            ]
        );
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate pretty_assertions;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

// we get an unused import when using macro use, but a
// "this has no effect without macro_use" message otherwise
#[allow(unused_imports)]
#[macro_use]
extern crate snapshot_proc_macro;

pub use snapshot_proc_macro::*;

use std::collections::HashMap;
use std::ffi::OsString;
use std::fmt::Debug;
use std::fs::File;
use std::io::BufReader;
use std::path::{Path, PathBuf};
use serde::Serialize;
use serde::de::DeserializeOwned;

pub trait Snapable {}
impl<T> Snapable for T where T: Debug + DeserializeOwned + Serialize {}

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Snapshot<S: Snapable> {
    pub file: String,
    pub module_path: String,
    pub test_function: String,
    pub recorded_value: S,
}

impl<S> Snapshot<S>
    where S: Snapable + Debug + DeserializeOwned + PartialEq + Serialize
{
    pub fn check_snapshot(&self, manifest_dir: &str) {
        let SnapFileSpec {
            absolute_path,
            relative_path,
            ..
        } = self.path(manifest_dir);

        let snap_file = match File::open(&absolute_path) {
            Ok(f) => f,
            Err(why) => {
                panic!("Unable to open snapshot file {:?}: {:?}",
                       relative_path,
                       why.kind())
            }
        };

        let rdr = BufReader::new(snap_file);
        let module_snapshots: HashMap<String, Snapshot<S>> = match serde_json::from_reader(rdr) {
            Ok(ps) => ps,
            Err(why) => {
                panic!("Unable to parse previous snapshot as the correct type:\n{:#?}",
                       why);
            }
        };

        let snap_key = self.module_key();
        let previous_snapshot = match module_snapshots.get(&snap_key) {
            Some(s) => s,
            None => {
                panic!("Unable to find snapshot for test {:?} in {:?}",
                       snap_key,
                       relative_path)
            }
        };

        assert_eq!(self.file,
                   previous_snapshot.file,
                   "Filename for snapshot test function doesn't match recorded one");

        assert_eq!(self.module_path,
                   previous_snapshot.module_path,
                   "Module paths for snapshot test function doesn't match recorded one");

        assert_eq!(self.test_function,
                   previous_snapshot.test_function,
                   "Test function name doesn't match recorded one");

        assert_eq!(self.recorded_value,
                   previous_snapshot.recorded_value,
                   "Test output doesn't match recorded snapshot!");

        // just as a catch all in case we need other fields?
        assert_eq!(self, previous_snapshot, "Snapshot metadata is corrupt!");
    }

    pub fn update_snapshot(&self, manifest_dir: &str) {
        let SnapFileSpec {
            dir: snap_dir,
            filename: snap_filename,
            absolute_path,
            relative_path,
        } = self.path(manifest_dir);

        let snap_file = match File::open(&absolute_path) {
            Ok(f) => f,
            Err(why) => {
                panic!("Unable to create snapshot file {:?}: {:?}",
                       relative_path,
                       why.kind())
            }
        };

        unimplemented!();
    }

    fn module_key(&self) -> String {
        let mut snapshot_key = self.module_path.to_owned();
        snapshot_key.push_str("::");
        snapshot_key.push_str(&self.test_function);
        snapshot_key
    }

    fn path(&self, manifest_dir: &str) -> SnapFileSpec {
        let file_path = &Path::new(&self.file);

        let mut components = file_path.components();

        // strip the filename
        let mut filename = components.next_back().unwrap().as_os_str().to_owned();
        filename.push(".snap");

        let mut dir = PathBuf::new();
        for directory in components {
            dir.push(directory.as_os_str());
        }

        dir.push("__snapshots__");

        let mut absolute_path = PathBuf::from(manifest_dir);
        absolute_path.push(dir.clone());
        absolute_path.push(filename.clone());

        let mut relative_path = PathBuf::from(dir.clone());
        relative_path.push(filename.clone());

        SnapFileSpec {
            dir,
            filename,
            absolute_path,
            relative_path,
        }
    }
}

struct SnapFileSpec {
    dir: PathBuf,
    filename: OsString,
    relative_path: PathBuf,
    absolute_path: PathBuf,
}
<commit_msg>Recursively create snapshot dir and create snapshot file.<commit_after>#[macro_use]
extern crate pretty_assertions;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

// we get an unused import when using macro use, but a
// "this has no effect without macro_use" message otherwise
#[allow(unused_imports)]
#[macro_use]
extern crate snapshot_proc_macro;

pub use snapshot_proc_macro::*;

use std::collections::HashMap;
use std::ffi::OsString;
use std::fmt::Debug;
use std::fs::{create_dir_all, File};
use std::io::BufReader;
use std::path::{Path, PathBuf};
use serde::Serialize;
use serde::de::DeserializeOwned;

pub trait Snapable {}
impl<T> Snapable for T where T: Debug + DeserializeOwned + Serialize {}

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Snapshot<S: Snapable> {
    pub file: String,
    pub module_path: String,
    pub test_function: String,
    pub recorded_value: S,
}

impl<S> Snapshot<S>
    where S: Snapable + Debug + DeserializeOwned + PartialEq + Serialize
{
    pub fn check_snapshot(&self, manifest_dir: &str) {
        let SnapFileSpec {
            absolute_path,
            relative_path,
            ..
        } = self.path(manifest_dir);

        let snap_file = match File::open(&absolute_path) {
            Ok(f) => f,
            Err(why) => {
                panic!("Unable to open snapshot file {:?}: {:?}",
                       relative_path,
                       why.kind())
            }
        };

        let rdr = BufReader::new(snap_file);
        let module_snapshots: HashMap<String, Snapshot<S>> = match serde_json::from_reader(rdr) {
            Ok(ps) => ps,
            Err(why) => {
                panic!("Unable to parse previous snapshot as the correct type:\n{:#?}",
                       why);
            }
        };

        let snap_key = self.module_key();
        let previous_snapshot = match module_snapshots.get(&snap_key) {
            Some(s) => s,
            None => {
                panic!("Unable to find snapshot for test {:?} in {:?}",
                       snap_key,
                       relative_path)
            }
        };

        assert_eq!(self.file,
                   previous_snapshot.file,
                   "Filename for snapshot test function doesn't match recorded one");

        assert_eq!(self.module_path,
                   previous_snapshot.module_path,
                   "Module paths for snapshot test function doesn't match recorded one");

        assert_eq!(self.test_function,
                   previous_snapshot.test_function,
                   "Test function name doesn't match recorded one");

        assert_eq!(self.recorded_value,
                   previous_snapshot.recorded_value,
                   "Test output doesn't match recorded snapshot!");

        // just as a catch all in case we need other fields?
        assert_eq!(self, previous_snapshot, "Snapshot metadata is corrupt!");
    }

    pub fn update_snapshot(&self, manifest_dir: &str) {
        let SnapFileSpec {
            dir: snap_dir,
            filename: snap_filename,
            absolute_path,
            relative_path,
        } = self.path(manifest_dir);

        let mut dir_to_create = PathBuf::from(manifest_dir);
        dir_to_create.push(snap_dir.clone());
        match create_dir_all(&dir_to_create) {
            Ok(_) => (),
            Err(why) => {
                panic!("Unable to create snapshots directory {:?}: {:?}",
                       snap_dir,
                       why.kind())
            }
        }

        let snap_file = match File::create(&absolute_path) {
            Ok(f) => f,
            Err(why) => {
                panic!("Unable to create snapshot file {:?}: {:?}",
                       relative_path,
                       why.kind())
            }
        };

        // TODO write snapshot to disk

        unimplemented!();
    }

    fn module_key(&self) -> String {
        let mut snapshot_key = self.module_path.to_owned();
        snapshot_key.push_str("::");
        snapshot_key.push_str(&self.test_function);
        snapshot_key
    }

    fn path(&self, manifest_dir: &str) -> SnapFileSpec {
        let file_path = &Path::new(&self.file);

        let mut components = file_path.components();

        // strip the filename
        let mut filename = components.next_back().unwrap().as_os_str().to_owned();
        filename.push(".snap");

        let mut dir = PathBuf::new();
        for directory in components {
            dir.push(directory.as_os_str());
        }

        dir.push("__snapshots__");

        let mut absolute_path = PathBuf::from(manifest_dir);
        absolute_path.push(dir.clone());
        absolute_path.push(filename.clone());

        let mut relative_path = PathBuf::from(dir.clone());
        relative_path.push(filename.clone());

        SnapFileSpec {
            dir,
            filename,
            absolute_path,
            relative_path,
        }
    }
}

struct SnapFileSpec {
    dir: PathBuf,
    filename: OsString,
    relative_path: PathBuf,
    absolute_path: PathBuf,
}
<|endoftext|>


<commit_before>extern crate opus_sys as ffi;
extern crate libc;

use std::ffi::CStr;

use libc::{c_int};

// TODO: Documentation

// ============================================================================
// Constants

// Generic CTLs
const OPUS_RESET_STATE: c_int = 4028; // void
const OPUS_GET_FINAL_RANGE: c_int = 4031; // *uint
const OPUS_GET_BANDWIDTH: c_int = 4009; // *int
const OPUS_GET_SAMPLE_RATE: c_int = 4029; // *int

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum CodingMode {
	Voip = 2048,
	Audio = 2049,
	LowDelay = 2051,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Channels {
	Stereo = 1,
	Mono = 2,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Bandwidth {
	Narrowband = 1101,
	Mediumband = 1102,
	Wideband = 1103,
	Superwideband = 1104,
	Fullband = 1105,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ErrorCode {
	BadArg = -1,
	BufferTooSmall = -2,
	InternalError = -3,
	InvalidPacket = -4,
	Unimplemented = -5,
	InvalidState = -6,
	AllocFail = -7,
	Unknown = -8,
}

pub fn version() -> &'static str {
	// verison string should always be ASCII
	unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
}

// ============================================================================
// Encoder

pub struct Encoder {
	ptr: *mut ffi::OpusEncoder,
	channels: Channels,
}

impl Encoder {
	pub fn new(sample_rate: u32, channels: Channels, mode: CodingMode) -> Result<Encoder> {
		let mut error = 0;
		let ptr = unsafe { ffi::opus_encoder_create(
			sample_rate as i32,
			channels as c_int,
			mode as c_int,
			&mut error) };
		if error != ffi::OPUS_OK || ptr.is_null() {
			Err(Error::from_code("opus_encoder_create", error))
		} else {
			Ok(Encoder { ptr: ptr, channels: channels })
		}
	}

	pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
		let len = unsafe { ffi::opus_encode(self.ptr,
			input.as_ptr(), input.len() as c_int / self.channels as c_int,
			output.as_mut_ptr(), output.len() as c_int) };
		try!(check("opus_encode", len));
		Ok(len as usize)
	}

	pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
		let len = unsafe { ffi::opus_encode_float(self.ptr,
			input.as_ptr(), input.len() as c_int / self.channels as c_int,
			output.as_mut_ptr(), output.len() as c_int) };
		try!(check("opus_encode_float", len));
		Ok(len as usize)
	}

	pub fn reset_state(&mut self) -> Result<()> {
		check("opus_encoder_ctl(OPUS_RESET_STATE)", unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_RESET_STATE) })
	}

	pub fn get_final_range(&mut self) -> Result<u32> {
		let mut value = 0;
		let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_FINAL_RANGE, &mut value) };
		try!(check("opus_encoder_ctl(OPUS_GET_FINAL_RANGE)", result));
		Ok(value)
	}

	pub fn get_bandwidth(&mut self) -> Result<i32> {
		let mut value = 0;
		let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_BANDWIDTH, &mut value) };
		try!(check("opus_encoder_ctl(OPUS_GET_BANDWIDTH)", result));
		Ok(value)
	}

	pub fn get_sample_rate(&mut self) -> Result<i32> {
		let mut value = 0;
		let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_SAMPLE_RATE, &mut value) };
		try!(check("opus_encoder_ctl(OPUS_GET_SAMPLE_RATE)", result));
		Ok(value)
	}

	// TODO: Encoder-specific CTLs
}

impl Drop for Encoder {
	fn drop(&mut self) {
		unsafe { ffi::opus_encoder_destroy(self.ptr) }
	}
}

// ============================================================================
// Decoder

pub struct Decoder {
	ptr: *mut ffi::OpusDecoder,
	channels: Channels,
}

impl Decoder {
	pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
		let mut error = 0;
		let ptr = unsafe { ffi::opus_decoder_create(
			sample_rate as i32,
			channels as c_int,
			&mut error) };
		if error != ffi::OPUS_OK || ptr.is_null() {
			Err(Error::from_code("opus_decoder_create", error))
		} else {
			Ok(Decoder { ptr: ptr, channels: channels })
		}
	}

	// TODO: support null inputs ("packet loss")
	pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
		let len = unsafe { ffi::opus_decode(self.ptr,
			input.as_ptr(), input.len() as c_int,
			output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
			fec as c_int) };
		try!(check("opus_decode", len));
		Ok(len as usize)
	}

	pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
		let len = unsafe { ffi::opus_decode_float(self.ptr,
			input.as_ptr(), input.len() as c_int,
			output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
			fec as c_int) };
		try!(check("opus_decode_float", len));
		Ok(len as usize)
	}

	pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
		let len = unsafe { ffi::opus_decoder_get_nb_samples(self.ptr,
			packet.as_ptr(), packet.len() as i32) };
		try!(check("opus_decoder_get_nb_samples", len));
		Ok(len as usize)
	}

	// TODO: Generic CTLs
	// TODO: Decoder-specific CTLs
}

impl Drop for Decoder {
	fn drop(&mut self) {
		unsafe { ffi::opus_decoder_destroy(self.ptr) }
	}
}

// ============================================================================
// Packet Analysis

pub mod packet {
	use super::*;
	use super::{ffi, check};
	use std::{ptr, slice};
	use libc::c_int;

	pub fn get_bandwidth(packet: &[u8]) -> Result<Bandwidth> {
		if packet.len() < 1 {
			return Err(Error::from_code("opus_packet_get_bandwidth", ffi::OPUS_BAD_ARG))
		}
		let bandwidth = unsafe { ffi::opus_packet_get_bandwidth(packet.as_ptr()) };
		try!(check("opus_packet_get_bandwidth", bandwidth));
		match bandwidth {
			1101 => Ok(Bandwidth::Narrowband),
			1102 => Ok(Bandwidth::Mediumband),
			1103 => Ok(Bandwidth::Wideband),
			1104 => Ok(Bandwidth::Superwideband),
			1105 => Ok(Bandwidth::Fullband),
			_ => Err(Error::from_code("opus_packet_get_bandwidth", ffi::OPUS_BAD_ARG)),
		}
	}

	pub fn get_nb_channels(packet: &[u8]) -> Result<Channels> {
		if packet.len() < 1 {
			return Err(Error::from_code("opus_packet_get_nb_channels", ffi::OPUS_BAD_ARG))
		}
		let channels = unsafe { ffi::opus_packet_get_nb_channels(packet.as_ptr()) };
		try!(check("opus_packet_get_nb_channels", channels));
		match channels {
			1 => Ok(Channels::Mono),
			2 => Ok(Channels::Stereo),
			_ => Err(Error::from_code("opus_packet_get_nb_channels", ffi::OPUS_BAD_ARG)),
		}
	}

	pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
		let frames = unsafe { ffi::opus_packet_get_nb_frames(packet.as_ptr(), packet.len() as c_int) };
		try!(check("opus_packet_get_nb_frames", frames));
		Ok(frames as usize)
	}

	pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
		let frames = unsafe { ffi::opus_packet_get_nb_samples(
			packet.as_ptr(), packet.len() as c_int,
			sample_rate as c_int) };
		try!(check("opus_packet_get_nb_samples", frames));
		Ok(frames as usize)
	}

	pub fn get_samples_per_frame(packet: &[u8], sample_rate: u32) -> Result<usize> {
		if packet.len() < 1 {
			return Err(Error::from_code("opus_packet_get_samples_per_frame", ffi::OPUS_BAD_ARG))
		}
		let samples = unsafe { ffi::opus_packet_get_samples_per_frame(packet.as_ptr(), sample_rate as c_int) };
		try!(check("opus_packet_get_samples_per_frame", samples));
		Ok(samples as usize)
	}

	pub fn parse(packet: &[u8]) -> Result<Packet> {
		let mut toc: u8 = 0;
		let mut frames = [ptr::null(); 48];
		let mut sizes = [0i16; 48];
		let mut payload_offset: i32 = 0;
		let num_frames = unsafe { ffi::opus_packet_parse(
			packet.as_ptr(), packet.len() as c_int,
			&mut toc, frames.as_mut_ptr(),
			sizes.as_mut_ptr(), &mut payload_offset) };
		try!(check("opus_packet_parse", num_frames));

		let mut frames_vec = Vec::with_capacity(num_frames as usize);
		for i in 0..num_frames as usize {
			frames_vec.push(unsafe { slice::from_raw_parts(frames[i], sizes[i] as usize) });
		}

		Ok(Packet {
			toc: toc,
			frames: frames_vec,
			payload_offset: payload_offset as usize,
		})
	}

	pub struct Packet<'a> {
		pub toc: u8,
		pub frames: Vec<&'a [u8]>,
		pub payload_offset: usize,
	}
}

// ============================================================================
// Float Soft Clipping

pub struct SoftClip {
	channels: Channels,
	memory: [f32; 2],
}

impl SoftClip {
	pub fn new(channels: Channels) -> SoftClip {
		SoftClip { channels: channels, memory: [0.0; 2] }
	}

	pub fn apply(&mut self, signal: &mut [f32]) {
		unsafe { ffi::opus_pcm_soft_clip(
			signal.as_mut_ptr(),
			signal.len() as c_int / self.channels as c_int,
			self.channels as c_int,
			self.memory.as_mut_ptr()) };
	}
}

// ============================================================================
// TODO: Repacketizer

// ============================================================================
// TODO: Multistream API

// ============================================================================
// Error Handling

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Error {
	function: &'static str,
	description: &'static str,
	code: ErrorCode,
}

impl Error {
	fn from_code(what: &'static str, code: c_int) -> Error {
		// description should always be ASCII
		let description = unsafe { CStr::from_ptr(ffi::opus_strerror(code)) }.to_str().unwrap();
		let code = match code {
			-1 => ErrorCode::BadArg,
			-2 => ErrorCode::BufferTooSmall,
			-3 => ErrorCode::InternalError,
			-4 => ErrorCode::InvalidPacket,
			-5 => ErrorCode::Unimplemented,
			-6 => ErrorCode::InvalidState,
			-7 => ErrorCode::AllocFail,
			_ => ErrorCode::Unknown,
		};
		Error { function: what, description: description, code: code }
	}

	pub fn function(&self) -> &'static str { self.function }
	pub fn description(&self) -> &'static str { self.description }
	pub fn code(&self) -> ErrorCode { self.code }
}

impl std::fmt::Display for Error {
	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
		write!(f, "{}: {}", self.function, self.description)
	}
}

impl std::error::Error for Error {
	fn description(&self) -> &str {
		self.description
	}
}

fn check(what: &'static str, code: c_int) -> Result<()> {
	if code < 0 {
		Err(Error::from_code(what, code))
	} else {
		Ok(())
	}
}
<commit_msg>Add Repacketizer<commit_after>extern crate opus_sys as ffi;
extern crate libc;

use std::ffi::CStr;

use libc::{c_int};

// TODO: Documentation

// ============================================================================
// Constants

// Generic CTLs
const OPUS_RESET_STATE: c_int = 4028; // void
const OPUS_GET_FINAL_RANGE: c_int = 4031; // *uint
const OPUS_GET_BANDWIDTH: c_int = 4009; // *int
const OPUS_GET_SAMPLE_RATE: c_int = 4029; // *int

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum CodingMode {
	Voip = 2048,
	Audio = 2049,
	LowDelay = 2051,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Channels {
	Stereo = 1,
	Mono = 2,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Bandwidth {
	Narrowband = 1101,
	Mediumband = 1102,
	Wideband = 1103,
	Superwideband = 1104,
	Fullband = 1105,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ErrorCode {
	BadArg = -1,
	BufferTooSmall = -2,
	InternalError = -3,
	InvalidPacket = -4,
	Unimplemented = -5,
	InvalidState = -6,
	AllocFail = -7,
	Unknown = -8,
}

pub fn version() -> &'static str {
	// verison string should always be ASCII
	unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
}

// ============================================================================
// Encoder

pub struct Encoder {
	ptr: *mut ffi::OpusEncoder,
	channels: Channels,
}

impl Encoder {
	pub fn new(sample_rate: u32, channels: Channels, mode: CodingMode) -> Result<Encoder> {
		let mut error = 0;
		let ptr = unsafe { ffi::opus_encoder_create(
			sample_rate as i32,
			channels as c_int,
			mode as c_int,
			&mut error) };
		if error != ffi::OPUS_OK || ptr.is_null() {
			Err(Error::from_code("opus_encoder_create", error))
		} else {
			Ok(Encoder { ptr: ptr, channels: channels })
		}
	}

	pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
		let len = unsafe { ffi::opus_encode(self.ptr,
			input.as_ptr(), input.len() as c_int / self.channels as c_int,
			output.as_mut_ptr(), output.len() as c_int) };
		try!(check("opus_encode", len));
		Ok(len as usize)
	}

	pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
		let len = unsafe { ffi::opus_encode_float(self.ptr,
			input.as_ptr(), input.len() as c_int / self.channels as c_int,
			output.as_mut_ptr(), output.len() as c_int) };
		try!(check("opus_encode_float", len));
		Ok(len as usize)
	}

	pub fn reset_state(&mut self) -> Result<()> {
		check("opus_encoder_ctl(OPUS_RESET_STATE)", unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_RESET_STATE) })
	}

	pub fn get_final_range(&mut self) -> Result<u32> {
		let mut value = 0;
		let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_FINAL_RANGE, &mut value) };
		try!(check("opus_encoder_ctl(OPUS_GET_FINAL_RANGE)", result));
		Ok(value)
	}

	pub fn get_bandwidth(&mut self) -> Result<i32> {
		let mut value = 0;
		let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_BANDWIDTH, &mut value) };
		try!(check("opus_encoder_ctl(OPUS_GET_BANDWIDTH)", result));
		Ok(value)
	}

	pub fn get_sample_rate(&mut self) -> Result<i32> {
		let mut value = 0;
		let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_SAMPLE_RATE, &mut value) };
		try!(check("opus_encoder_ctl(OPUS_GET_SAMPLE_RATE)", result));
		Ok(value)
	}

	// TODO: Encoder-specific CTLs
}

impl Drop for Encoder {
	fn drop(&mut self) {
		unsafe { ffi::opus_encoder_destroy(self.ptr) }
	}
}

// ============================================================================
// Decoder

pub struct Decoder {
	ptr: *mut ffi::OpusDecoder,
	channels: Channels,
}

impl Decoder {
	pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
		let mut error = 0;
		let ptr = unsafe { ffi::opus_decoder_create(
			sample_rate as i32,
			channels as c_int,
			&mut error) };
		if error != ffi::OPUS_OK || ptr.is_null() {
			Err(Error::from_code("opus_decoder_create", error))
		} else {
			Ok(Decoder { ptr: ptr, channels: channels })
		}
	}

	// TODO: support null inputs ("packet loss")
	pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
		let len = unsafe { ffi::opus_decode(self.ptr,
			input.as_ptr(), input.len() as c_int,
			output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
			fec as c_int) };
		try!(check("opus_decode", len));
		Ok(len as usize)
	}

	pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
		let len = unsafe { ffi::opus_decode_float(self.ptr,
			input.as_ptr(), input.len() as c_int,
			output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
			fec as c_int) };
		try!(check("opus_decode_float", len));
		Ok(len as usize)
	}

	pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
		let len = unsafe { ffi::opus_decoder_get_nb_samples(self.ptr,
			packet.as_ptr(), packet.len() as i32) };
		try!(check("opus_decoder_get_nb_samples", len));
		Ok(len as usize)
	}

	// TODO: Generic CTLs
	// TODO: Decoder-specific CTLs
}

impl Drop for Decoder {
	fn drop(&mut self) {
		unsafe { ffi::opus_decoder_destroy(self.ptr) }
	}
}

// ============================================================================
// Packet Analysis

pub mod packet {
	use super::*;
	use super::{ffi, check};
	use std::{ptr, slice};
	use libc::c_int;

	pub fn get_bandwidth(packet: &[u8]) -> Result<Bandwidth> {
		if packet.len() < 1 {
			return Err(Error::from_code("opus_packet_get_bandwidth", ffi::OPUS_BAD_ARG))
		}
		let bandwidth = unsafe { ffi::opus_packet_get_bandwidth(packet.as_ptr()) };
		try!(check("opus_packet_get_bandwidth", bandwidth));
		match bandwidth {
			1101 => Ok(Bandwidth::Narrowband),
			1102 => Ok(Bandwidth::Mediumband),
			1103 => Ok(Bandwidth::Wideband),
			1104 => Ok(Bandwidth::Superwideband),
			1105 => Ok(Bandwidth::Fullband),
			_ => Err(Error::from_code("opus_packet_get_bandwidth", ffi::OPUS_BAD_ARG)),
		}
	}

	pub fn get_nb_channels(packet: &[u8]) -> Result<Channels> {
		if packet.len() < 1 {
			return Err(Error::from_code("opus_packet_get_nb_channels", ffi::OPUS_BAD_ARG))
		}
		let channels = unsafe { ffi::opus_packet_get_nb_channels(packet.as_ptr()) };
		try!(check("opus_packet_get_nb_channels", channels));
		match channels {
			1 => Ok(Channels::Mono),
			2 => Ok(Channels::Stereo),
			_ => Err(Error::from_code("opus_packet_get_nb_channels", ffi::OPUS_BAD_ARG)),
		}
	}

	pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
		let frames = unsafe { ffi::opus_packet_get_nb_frames(packet.as_ptr(), packet.len() as c_int) };
		try!(check("opus_packet_get_nb_frames", frames));
		Ok(frames as usize)
	}

	pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
		let frames = unsafe { ffi::opus_packet_get_nb_samples(
			packet.as_ptr(), packet.len() as c_int,
			sample_rate as c_int) };
		try!(check("opus_packet_get_nb_samples", frames));
		Ok(frames as usize)
	}

	pub fn get_samples_per_frame(packet: &[u8], sample_rate: u32) -> Result<usize> {
		if packet.len() < 1 {
			return Err(Error::from_code("opus_packet_get_samples_per_frame", ffi::OPUS_BAD_ARG))
		}
		let samples = unsafe { ffi::opus_packet_get_samples_per_frame(packet.as_ptr(), sample_rate as c_int) };
		try!(check("opus_packet_get_samples_per_frame", samples));
		Ok(samples as usize)
	}

	pub fn parse(packet: &[u8]) -> Result<Packet> {
		let mut toc: u8 = 0;
		let mut frames = [ptr::null(); 48];
		let mut sizes = [0i16; 48];
		let mut payload_offset: i32 = 0;
		let num_frames = unsafe { ffi::opus_packet_parse(
			packet.as_ptr(), packet.len() as c_int,
			&mut toc, frames.as_mut_ptr(),
			sizes.as_mut_ptr(), &mut payload_offset) };
		try!(check("opus_packet_parse", num_frames));

		let mut frames_vec = Vec::with_capacity(num_frames as usize);
		for i in 0..num_frames as usize {
			frames_vec.push(unsafe { slice::from_raw_parts(frames[i], sizes[i] as usize) });
		}

		Ok(Packet {
			toc: toc,
			frames: frames_vec,
			payload_offset: payload_offset as usize,
		})
	}

	pub struct Packet<'a> {
		pub toc: u8,
		pub frames: Vec<&'a [u8]>,
		pub payload_offset: usize,
	}

	pub fn pad(packet: &mut [u8], prev_len: usize) -> Result<usize> {
		let result = unsafe { ffi::opus_packet_pad(packet.as_mut_ptr(), prev_len as c_int, packet.len() as c_int) };
		try!(check("opus_packet_pad", result));
		Ok(result as usize)
	}

	pub fn unpad(packet: &mut [u8]) -> Result<usize> {
		let result = unsafe { ffi::opus_packet_unpad(packet.as_mut_ptr(), packet.len() as c_int) };
		try!(check("opus_packet_unpad", result));
		Ok(result as usize)
	}
}

// ============================================================================
// Float Soft Clipping

pub struct SoftClip {
	channels: Channels,
	memory: [f32; 2],
}

impl SoftClip {
	pub fn new(channels: Channels) -> SoftClip {
		SoftClip { channels: channels, memory: [0.0; 2] }
	}

	pub fn apply(&mut self, signal: &mut [f32]) {
		unsafe { ffi::opus_pcm_soft_clip(
			signal.as_mut_ptr(),
			signal.len() as c_int / self.channels as c_int,
			self.channels as c_int,
			self.memory.as_mut_ptr()) };
	}
}

// ============================================================================
// Repacketizer

pub struct Repacketizer {
	ptr: *mut ffi::OpusRepacketizer,
}

impl Repacketizer {
	pub fn new() -> Result<Repacketizer> {
		let ptr = unsafe { ffi::opus_repacketizer_create() };
		if ptr.is_null() {
			Err(Error::from_code("opus_repacketizer_create", ffi::OPUS_ALLOC_FAIL))
		} else {
			Ok(Repacketizer { ptr: ptr })
		}
	}

	pub fn reset(&mut self) {
		unsafe { ffi::opus_repacketizer_init(self.ptr); }
	}

	pub fn get_nb_frames(&mut self) -> usize {
		unsafe { ffi::opus_repacketizer_get_nb_frames(self.ptr) as usize }
	}

	pub fn cat(&mut self, packet: &[u8]) -> Result<()> {
		let result = unsafe { ffi::opus_repacketizer_cat(self.ptr,
			packet.as_ptr(), packet.len() as c_int) };
		check("opus_repacketizer_cat", result)
	}

	pub fn out(&mut self, buffer: &mut [u8]) -> Result<usize> {
		let result = unsafe { ffi::opus_repacketizer_out(self.ptr,
			buffer.as_mut_ptr(), buffer.len() as c_int) };
		try!(check("opus_repacketizer_out", result));
		Ok(result as usize)
	}

	pub fn out_range(&mut self, begin: usize, end: usize, buffer: &mut [u8]) -> Result<usize> {
		let result = unsafe { ffi::opus_repacketizer_out_range(self.ptr,
			begin as c_int, end as c_int,
			buffer.as_mut_ptr(), buffer.len() as c_int) };
		try!(check("opus_repacketizer_out_range", result));
		Ok(result as usize)
	}
}

impl Drop for Repacketizer {
	fn drop(&mut self) {
		unsafe { ffi::opus_repacketizer_destroy(self.ptr) }
	}
}

// ============================================================================
// TODO: Multistream API

// ============================================================================
// Error Handling

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Error {
	function: &'static str,
	description: &'static str,
	code: ErrorCode,
}

impl Error {
	fn from_code(what: &'static str, code: c_int) -> Error {
		// description should always be ASCII
		let description = unsafe { CStr::from_ptr(ffi::opus_strerror(code)) }.to_str().unwrap();
		let code = match code {
			-1 => ErrorCode::BadArg,
			-2 => ErrorCode::BufferTooSmall,
			-3 => ErrorCode::InternalError,
			-4 => ErrorCode::InvalidPacket,
			-5 => ErrorCode::Unimplemented,
			-6 => ErrorCode::InvalidState,
			-7 => ErrorCode::AllocFail,
			_ => ErrorCode::Unknown,
		};
		Error { function: what, description: description, code: code }
	}

	pub fn function(&self) -> &'static str { self.function }
	pub fn description(&self) -> &'static str { self.description }
	pub fn code(&self) -> ErrorCode { self.code }
}

impl std::fmt::Display for Error {
	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
		write!(f, "{}: {}", self.function, self.description)
	}
}

impl std::error::Error for Error {
	fn description(&self) -> &str {
		self.description
	}
}

fn check(what: &'static str, code: c_int) -> Result<()> {
	if code < 0 {
		Err(Error::from_code(what, code))
	} else {
		Ok(())
	}
}
<|endoftext|>


<commit_before>//! Actix web is a small, pragmatic, extremely fast, web framework for Rust.
//!
//! ```rust
//! use actix_web::*;
//! # use std::thread;
//!
//! fn index(req: HttpRequest) -> String {
//!     format!("Hello {}!", &req.match_info()["name"])
//! }
//!
//! fn main() {
//! # thread::spawn(|| {
//!     HttpServer::new(
//!         || Application::new()
//!             .resource("/{name}", |r| r.f(index)))
//!         .bind("127.0.0.1:8080").unwrap()
//!         .run();
//! # });
//! }
//! ```
//!
//! ## Documentation
//!
//! * [User Guide](http://actix.github.io/actix-web/guide/)
//! * [Chat on gitter](https://gitter.im/actix/actix)
//! * [GitHub repository](https://github.com/actix/actix-web)
//! * [Cargo package](https://crates.io/crates/actix-web)
//! * Supported Rust version: 1.21 or later
//!
//! ## Features
//!
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * `WebSockets` server/client
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Configurable request routing
//! * Graceful server shutdown
//! * Multipart streams
//! * SSL support with openssl or native-tls
//! * Middlewares (`Logger`, `Session`, `CORS`, `CSRF`, `DefaultHeaders`)
//! * Built on top of [Actix actor framework](https://github.com/actix/actix).

#![cfg_attr(actix_nightly, feature(
    specialization, // for impl ErrorResponse for std::error::Error
))]
#![cfg_attr(feature = "cargo-clippy", allow(
    decimal_literal_representation,suspicious_arithmetic_impl,))]

#[macro_use]
extern crate log;
extern crate time;
extern crate base64;
extern crate bytes;
extern crate byteorder;
extern crate sha1;
extern crate regex;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate futures;
extern crate futures_cpupool;
extern crate tokio_io;
extern crate tokio_core;
extern crate mio;
extern crate net2;
extern crate cookie;
extern crate http;
extern crate httparse;
extern crate http_range;
extern crate mime;
extern crate mime_guess;
extern crate language_tags;
extern crate rand;
extern crate url;
extern crate libc;
extern crate serde;
extern crate serde_json;
extern crate serde_urlencoded;
extern crate flate2;
#[cfg(feature="brotli")]
extern crate brotli2;
extern crate encoding;
extern crate percent_encoding;
extern crate smallvec;
extern crate num_cpus;
extern crate h2 as http2;
extern crate trust_dns_resolver;
#[macro_use] extern crate actix;

#[cfg(test)]
#[macro_use] extern crate serde_derive;

#[cfg(feature="tls")]
extern crate native_tls;
#[cfg(feature="tls")]
extern crate tokio_tls;

#[cfg(feature="openssl")]
extern crate openssl;
#[cfg(feature="openssl")]
extern crate tokio_openssl;

mod application;
mod body;
mod context;
mod handler;
mod helpers;
mod httpmessage;
mod httprequest;
mod httpresponse;
mod info;
mod json;
mod route;
mod router;
mod resource;
mod param;
mod payload;
mod pipeline;
mod with;
mod extractor;

pub mod client;
pub mod fs;
pub mod ws;
pub mod error;
pub mod header;
pub mod httpcodes;
pub mod multipart;
pub mod middleware;
pub mod pred;
pub mod test;
pub mod server;
pub use error::{Error, Result, ResponseError};
pub use body::{Body, Binary};
pub use json::Json;
pub use application::Application;
pub use httpmessage::HttpMessage;
pub use httprequest::HttpRequest;
pub use httpresponse::HttpResponse;
pub use handler::{Either, Reply, Responder, NormalizePath, AsyncResponder, FutureResponse};
pub use route::Route;
pub use resource::Resource;
pub use context::HttpContext;
pub use server::HttpServer;
pub use extractor::{Path, PathAndQuery, Query};

// re-exports
pub use http::{Method, StatusCode, Version};

#[cfg(feature="openssl")]
pub(crate) const HAS_OPENSSL: bool = true;
#[cfg(not(feature="openssl"))]
pub(crate) const HAS_OPENSSL: bool = false;

#[cfg(feature="tls")]
pub(crate) const HAS_TLS: bool = true;
#[cfg(not(feature="tls"))]
pub(crate) const HAS_TLS: bool = false;

#[doc(hidden)]
#[deprecated(since="0.4.4", note="please use `actix::header` module")]
pub mod headers {
//! Headers implementation

    pub use httpresponse::ConnectionType;
    pub use cookie::{Cookie, CookieBuilder};
    pub use http_range::HttpRange;
    pub use header::ContentEncoding;
}

pub mod dev {
//! The `actix-web` prelude for library developers
//!
//! The purpose of this module is to alleviate imports of many common actix traits
//! by adding a glob import to the top of actix heavy modules:
//!
//! ```
//! # #![allow(unused_imports)]
//! use actix_web::dev::*;
//! ```

    pub use body::BodyStream;
    pub use context::Drain;
    pub use info::ConnectionInfo;
    pub use handler::Handler;
    pub use with::WithHandler;
    pub use json::JsonBody;
    pub use router::{Router, Pattern};
    pub use param::{FromParam, Params};
    pub use extractor::HttpRequestExtractor;
    pub use httpmessage::{UrlEncoded, MessageBody};
    pub use httpresponse::HttpResponseBuilder;
}
<commit_msg>remove unneeded import<commit_after>//! Actix web is a small, pragmatic, extremely fast, web framework for Rust.
//!
//! ```rust
//! use actix_web::*;
//! # use std::thread;
//!
//! fn index(req: HttpRequest) -> String {
//!     format!("Hello {}!", &req.match_info()["name"])
//! }
//!
//! fn main() {
//! # thread::spawn(|| {
//!     HttpServer::new(
//!         || Application::new()
//!             .resource("/{name}", |r| r.f(index)))
//!         .bind("127.0.0.1:8080").unwrap()
//!         .run();
//! # });
//! }
//! ```
//!
//! ## Documentation
//!
//! * [User Guide](http://actix.github.io/actix-web/guide/)
//! * [Chat on gitter](https://gitter.im/actix/actix)
//! * [GitHub repository](https://github.com/actix/actix-web)
//! * [Cargo package](https://crates.io/crates/actix-web)
//! * Supported Rust version: 1.21 or later
//!
//! ## Features
//!
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * `WebSockets` server/client
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Configurable request routing
//! * Graceful server shutdown
//! * Multipart streams
//! * SSL support with openssl or native-tls
//! * Middlewares (`Logger`, `Session`, `CORS`, `CSRF`, `DefaultHeaders`)
//! * Built on top of [Actix actor framework](https://github.com/actix/actix).

#![cfg_attr(actix_nightly, feature(
    specialization, // for impl ErrorResponse for std::error::Error
))]
#![cfg_attr(feature = "cargo-clippy", allow(
    decimal_literal_representation,suspicious_arithmetic_impl,))]

#[macro_use]
extern crate log;
extern crate time;
extern crate base64;
extern crate bytes;
extern crate byteorder;
extern crate sha1;
extern crate regex;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate futures;
extern crate futures_cpupool;
extern crate tokio_io;
extern crate tokio_core;
extern crate mio;
extern crate net2;
extern crate cookie;
extern crate http;
extern crate httparse;
extern crate http_range;
extern crate mime;
extern crate mime_guess;
extern crate language_tags;
extern crate rand;
extern crate url;
extern crate libc;
extern crate serde;
extern crate serde_json;
extern crate serde_urlencoded;
extern crate flate2;
#[cfg(feature="brotli")]
extern crate brotli2;
extern crate encoding;
extern crate percent_encoding;
extern crate smallvec;
extern crate num_cpus;
extern crate h2 as http2;
extern crate trust_dns_resolver;
#[macro_use] extern crate actix;

#[cfg(test)]
#[macro_use] extern crate serde_derive;

#[cfg(feature="tls")]
extern crate native_tls;
#[cfg(feature="tls")]
extern crate tokio_tls;

#[cfg(feature="openssl")]
extern crate openssl;
#[cfg(feature="openssl")]
extern crate tokio_openssl;

mod application;
mod body;
mod context;
mod handler;
mod helpers;
mod httpmessage;
mod httprequest;
mod httpresponse;
mod info;
mod json;
mod route;
mod router;
mod resource;
mod param;
mod payload;
mod pipeline;
mod with;
mod extractor;

pub mod client;
pub mod fs;
pub mod ws;
pub mod error;
pub mod header;
pub mod httpcodes;
pub mod multipart;
pub mod middleware;
pub mod pred;
pub mod test;
pub mod server;
pub use error::{Error, Result, ResponseError};
pub use body::{Body, Binary};
pub use json::Json;
pub use application::Application;
pub use httpmessage::HttpMessage;
pub use httprequest::HttpRequest;
pub use httpresponse::HttpResponse;
pub use handler::{Either, Reply, Responder, NormalizePath, AsyncResponder, FutureResponse};
pub use route::Route;
pub use resource::Resource;
pub use context::HttpContext;
pub use server::HttpServer;
pub use extractor::{Path, Query};

// re-exports
pub use http::{Method, StatusCode, Version};

#[cfg(feature="openssl")]
pub(crate) const HAS_OPENSSL: bool = true;
#[cfg(not(feature="openssl"))]
pub(crate) const HAS_OPENSSL: bool = false;

#[cfg(feature="tls")]
pub(crate) const HAS_TLS: bool = true;
#[cfg(not(feature="tls"))]
pub(crate) const HAS_TLS: bool = false;

#[doc(hidden)]
#[deprecated(since="0.4.4", note="please use `actix::header` module")]
pub mod headers {
//! Headers implementation

    pub use httpresponse::ConnectionType;
    pub use cookie::{Cookie, CookieBuilder};
    pub use http_range::HttpRange;
    pub use header::ContentEncoding;
}

pub mod dev {
//! The `actix-web` prelude for library developers
//!
//! The purpose of this module is to alleviate imports of many common actix traits
//! by adding a glob import to the top of actix heavy modules:
//!
//! ```
//! # #![allow(unused_imports)]
//! use actix_web::dev::*;
//! ```

    pub use body::BodyStream;
    pub use context::Drain;
    pub use info::ConnectionInfo;
    pub use handler::Handler;
    pub use with::WithHandler;
    pub use json::JsonBody;
    pub use router::{Router, Pattern};
    pub use param::{FromParam, Params};
    pub use extractor::HttpRequestExtractor;
    pub use httpmessage::{UrlEncoded, MessageBody};
    pub use httpresponse::HttpResponseBuilder;
}
<|endoftext|>