<commit_before>//! The parser module is responsible for parsing FITS files.

named!(fits<&[u8], ((Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >), Vec<&[u8]>) >,
       pair!(primary_header, many0!( take!(2880) )));

named!(primary_header<&[u8], (Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >)>,
       tuple!(
           many0!(keyword_record),
           end_header,
           many0!(blank_header)
       ));

named!(keyword_record<&[u8], (&[u8], &[u8], &[u8])>,
       tuple!(
           take!(8),
           tag!("="),
           take!(71)
       ));

named!(end_header<&[u8],(&[u8], Vec<&[u8]>)>, pair!(tag!("END"), count!(tag!(" "), 77)));

named!(blank_header<&[u8],Vec<&[u8]> >, count!(tag!(" "), 80));

#[cfg(test)]
mod tests {
    use nom::{IResult};
    use super::{fits, primary_header, end_header, blank_header, keyword_record};

    #[test]
    fn it_should_parse_a_fits_file(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = fits(data);

        match result {
            IResult::Done(_, (header, blocks)) => {
                assert_eq!(blocks.len(), 3675);
            },
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn primary_header_should_parse_a_primary_header(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = primary_header(&data[0..(2*2880)]);

        match result {
            IResult::Done(_, _) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn keyword_record_should_parse_a_keyword_record(){
        let data = "OBJECT  = 'EPIC 200164267'     / string version of target id                    "
            .as_bytes();

        let result = keyword_record(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn end_header_should_parse_an_END_header(){
        let data = "END                                                                             "
            .as_bytes();

        let result = end_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn blank_header_should_parse_a_BLANK_header(){
        let data = "                                                                                "
            .as_bytes();

        let result = blank_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }
}
<commit_msg>Rename end_header to end_record<commit_after>//! The parser module is responsible for parsing FITS files.

named!(fits<&[u8], ((Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >), Vec<&[u8]>) >,
       pair!(primary_header, many0!( take!(2880) )));

named!(primary_header<&[u8], (Vec<(&[u8], &[u8], &[u8])>, (&[u8], Vec<&[u8]>), Vec<Vec<&[u8]> >)>,
       tuple!(
           many0!(keyword_record),
           end_record,
           many0!(blank_header)
       ));

named!(keyword_record<&[u8], (&[u8], &[u8], &[u8])>,
       tuple!(
           take!(8),
           tag!("="),
           take!(71)
       ));

named!(end_record<&[u8],(&[u8], Vec<&[u8]>)>, pair!(tag!("END"), count!(tag!(" "), 77)));

named!(blank_header<&[u8],Vec<&[u8]> >, count!(tag!(" "), 80));

#[cfg(test)]
mod tests {
    use nom::{IResult};
    use super::{fits, primary_header, end_record, blank_header, keyword_record};

    #[test]
    fn it_should_parse_a_fits_file(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = fits(data);

        match result {
            IResult::Done(_, (header, blocks)) => {
                assert_eq!(blocks.len(), 3675);
            },
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn primary_header_should_parse_a_primary_header(){
        let data = include_bytes!("../../assets/images/k2-trappist1-unofficial-tpf-long-cadence.fits");

        let result = primary_header(&data[0..(2*2880)]);

        match result {
            IResult::Done(_, _) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn keyword_record_should_parse_a_keyword_record(){
        let data = "OBJECT  = 'EPIC 200164267'     / string version of target id                    "
            .as_bytes();

        let result = keyword_record(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn end_record_should_parse_an_END_record(){
        let data = "END                                                                             "
            .as_bytes();

        let result = end_record(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }

    #[test]
    fn blank_header_should_parse_a_BLANK_header(){
        let data = "                                                                                "
            .as_bytes();

        let result = blank_header(data);

        match result {
            IResult::Done(_,_) => assert!(true),
            IResult::Error(_) => panic!("Did not expect an error"),
            IResult::Incomplete(_) => panic!("Did not expect to be incomplete")
        }
    }
}
<|endoftext|>


<commit_before>//! # Command Parser
//!
//! The `commands::parser` module provides:
//!
//! * Functionality for building a tree of commands based on their names.
//! * Parsing tokenized input to select a command. Input tokenization can
//!   be performed by the `commands::tokenizer` module.
//! * Validating parameters.
//! * Performing completion on commands and parameters.
//!
//! The parser is still a work in progress but is rapidly advancing.

pub mod nodes;
pub mod completion;

use std::collections::HashMap;
use std::rc::Rc;
use parser::nodes::*;
use tokenizer::{Token, TokenType};
use parser::completion::{Complete, Completion};

/// Command parser
///
/// The lifetime parameter `'p` refers to the lifetime of the
/// parser itself, the root node of the command tree that was
/// used to create this parser, as well as the tokens passed
/// into the parser.
pub struct Parser<'p> {
    current_node: &'p Rc<Node>,
    /// The nodes which have been accepted during `parse` or `advance`.
    pub nodes: Vec<&'p Rc<Node>>,
    /// The tokens which have been accepted during `parse` or `advance`.
    pub tokens: Vec<Token<'p>>,
    commands: Vec<&'p Rc<CommandNode>>,
    parameters: HashMap<String, String>,
}

impl<'p> Parser<'p> {
    /// Construct a parser with a root node.
    pub fn new(initial_node: &'p Rc<Node>) -> Parser<'p> {
        Parser {
            current_node: initial_node,
            nodes: vec![],
            tokens: vec![],
            commands: vec![],
            parameters: HashMap::new(),
        }
    }

    /// Given an optional token, get the possible valid completions
    /// for the current parser state.
    pub fn complete(&self, token: Option<Token<'p>>) -> Vec<Completion> {
        self.current_node
            .successors()
            .into_iter()
            .filter(|n| {
                // To be a possible completion, the node should not be
                // hidden, it should be acceptable, and if there's a token,
                // it should be a valid match for the node.
                !n.hidden() && n.acceptable(self) &&
                if let Some(t) = token {
                    n.matches(self, t)
                } else {
                    true
                }
            })
            .map(|n| n.complete(token))
            .collect::<Vec<_>>()
    }

    /// Parse a vector of tokens, advancing through the
    /// node hierarchy.
    pub fn parse(&mut self, tokens: Vec<Token<'p>>) {
        for token in tokens {
            match token.token_type {
                TokenType::Invalid => unreachable!(),
                TokenType::Whitespace => {}
                TokenType::Word => self.advance(token),
            }
        }
    }

    /// Parse a single token, advancing through the node hierarchy.
    pub fn advance(&mut self, token: Token<'p>) {
        let matches = self.current_node
                          .successors()
                          .into_iter()
                          .filter(|n| n.acceptable(self) && n.matches(self, token))
                          .collect::<Vec<_>>();
        match matches.len() {
            1 => {
                let matching_node = &matches[0];
                matching_node.accept(self, token);
                self.current_node = matching_node.clone();
                self.nodes.push(matching_node);
                self.tokens.push(token);
            }
            0 => panic!("No matches for '{}'.", token.text),
            _ => panic!("Ambiguous matches for '{}'.", token.text),
        }
    }

    /// Execute the command that has been accepted by the parser.
    ///
    /// * XXX: This should be returning a Result probably.
    pub fn execute(&self) {
        if !self.commands.is_empty() {
            unimplemented!();
            // self.commands[0].execute(self)
        }
    }

    /// Verify that the parser is in a valid state with
    /// respect to having accepted a command and all
    /// required parameters.
    ///
    /// * XXX: This should be returning Option or Result
    ///        with an enum for the various error conditions.
    pub fn verify(&self) -> bool {
        if self.commands.is_empty() {
            // XXX: We'll want an enum error here with a Result.
            return false;
        } else {
            for expected in self.commands[0].parameters() {
                if expected.required() && !self.parameters.contains_key(expected.name()) {
                    return false;
                }
            }
        }
        true
    }
}

trait Acceptable {
    fn acceptable(&self, parser: &Parser) -> bool;
}

impl Acceptable for Rc<Node> {
    fn acceptable(&self, parser: &Parser) -> bool {
        !parser.nodes.contains(&self)
    }
}

impl Acceptable for RepeatableNode {
    fn acceptable(&self, _parser: &Parser) -> bool {
        if self.repeatable() {
            return true;
        }
        unimplemented!()
        // This should check nodes.contains, but then go on to check
        // for a repeat marker and whether or not that's been seen.
    }
}

trait Matches {
    fn matches(&self, parser: &Parser, token: Token) -> bool;
}

impl Matches for Node {
    fn matches(&self, _parser: &Parser, token: Token) -> bool {
        self.name().starts_with(token.text)
    }
}

trait Accept {
    fn accept<'p>(&'p self, parser: &mut Parser<'p>, token: Token);
}

impl Accept for Node {
    fn accept<'p>(&'p self, _parser: &mut Parser<'p>, _token: Token) {}
}

impl Accept for Rc<CommandNode> {
    fn accept<'p>(&'p self, parser: &mut Parser<'p>, _token: Token) {
        if let Some(_) = self.handler() {
            parser.commands.push(self)
        }
    }
}

impl Accept for Rc<ParameterNode> {
    fn accept<'p>(&'p self, parser: &mut Parser<'p>, token: Token) {
        if self.repeatable() {
            unimplemented!();
        } else {
            parser.parameters.insert(self.name().clone(), token.text.to_string());
        }
    }
}
<commit_msg>Parser: commands, nodes are Vec<Rc<_>> now.<commit_after>//! # Command Parser
//!
//! The `commands::parser` module provides:
//!
//! * Functionality for building a tree of commands based on their names.
//! * Parsing tokenized input to select a command. Input tokenization can
//!   be performed by the `commands::tokenizer` module.
//! * Validating parameters.
//! * Performing completion on commands and parameters.
//!
//! The parser is still a work in progress but is rapidly advancing.

pub mod nodes;
pub mod completion;

use std::collections::HashMap;
use std::rc::Rc;
use parser::nodes::*;
use tokenizer::{Token, TokenType};
use parser::completion::{Complete, Completion};

/// Command parser
///
/// The lifetime parameter `'p` refers to the lifetime of the
/// parser itself, the root node of the command tree that was
/// used to create this parser, as well as the tokens passed
/// into the parser.
pub struct Parser<'p> {
    current_node: &'p Rc<Node>,
    /// The nodes which have been accepted during `parse` or `advance`.
    pub nodes: Vec<Rc<Node>>,
    /// The tokens which have been accepted during `parse` or `advance`.
    pub tokens: Vec<Token<'p>>,
    commands: Vec<Rc<CommandNode>>,
    parameters: HashMap<String, String>,
}

impl<'p> Parser<'p> {
    /// Construct a parser with a root node.
    pub fn new(initial_node: &'p Rc<Node>) -> Parser<'p> {
        Parser {
            current_node: initial_node,
            nodes: vec![],
            tokens: vec![],
            commands: vec![],
            parameters: HashMap::new(),
        }
    }

    /// Given an optional token, get the possible valid completions
    /// for the current parser state.
    pub fn complete(&self, token: Option<Token<'p>>) -> Vec<Completion> {
        self.current_node
            .successors()
            .into_iter()
            .filter(|n| {
                // To be a possible completion, the node should not be
                // hidden, it should be acceptable, and if there's a token,
                // it should be a valid match for the node.
                !n.hidden() && n.acceptable(self) &&
                if let Some(t) = token {
                    n.matches(self, t)
                } else {
                    true
                }
            })
            .map(|n| n.complete(token))
            .collect::<Vec<_>>()
    }

    /// Parse a vector of tokens, advancing through the
    /// node hierarchy.
    pub fn parse(&mut self, tokens: Vec<Token<'p>>) {
        for token in tokens {
            match token.token_type {
                TokenType::Invalid => unreachable!(),
                TokenType::Whitespace => {}
                TokenType::Word => self.advance(token),
            }
        }
    }

    /// Parse a single token, advancing through the node hierarchy.
    pub fn advance(&mut self, token: Token<'p>) {
        let matches = self.current_node
                          .successors()
                          .into_iter()
                          .filter(|n| n.acceptable(self) && n.matches(self, token))
                          .collect::<Vec<_>>();
        match matches.len() {
            1 => {
                let matching_node = matches[0];
                matching_node.accept(self, token);
                self.current_node = matching_node;
                self.nodes.push(matching_node.clone());
                self.tokens.push(token);
            }
            0 => panic!("No matches for '{}'.", token.text),
            _ => panic!("Ambiguous matches for '{}'.", token.text),
        }
    }

    /// Execute the command that has been accepted by the parser.
    ///
    /// * XXX: This should be returning a Result probably.
    pub fn execute(&self) {
        if !self.commands.is_empty() {
            unimplemented!();
            // self.commands[0].execute(self)
        }
    }

    /// Verify that the parser is in a valid state with
    /// respect to having accepted a command and all
    /// required parameters.
    ///
    /// * XXX: This should be returning Option or Result
    ///        with an enum for the various error conditions.
    pub fn verify(&self) -> bool {
        if self.commands.is_empty() {
            // XXX: We'll want an enum error here with a Result.
            return false;
        } else {
            for expected in self.commands[0].parameters() {
                if expected.required() && !self.parameters.contains_key(expected.name()) {
                    return false;
                }
            }
        }
        true
    }
}

trait Acceptable {
    fn acceptable(&self, parser: &Parser) -> bool;
}

impl Acceptable for Rc<Node> {
    fn acceptable(&self, parser: &Parser) -> bool {
        !parser.nodes.contains(self)
    }
}

impl Acceptable for RepeatableNode {
    fn acceptable(&self, _parser: &Parser) -> bool {
        if self.repeatable() {
            return true;
        }
        unimplemented!()
        // This should check nodes.contains, but then go on to check
        // for a repeat marker and whether or not that's been seen.
    }
}

trait Matches {
    fn matches(&self, parser: &Parser, token: Token) -> bool;
}

impl Matches for Node {
    fn matches(&self, _parser: &Parser, token: Token) -> bool {
        self.name().starts_with(token.text)
    }
}

trait Accept {
    fn accept<'p>(&self, parser: &mut Parser<'p>, token: Token);
}

impl Accept for Node {
    fn accept<'p>(&self, _parser: &mut Parser<'p>, _token: Token) {}
}

impl Accept for Rc<CommandNode> {
    fn accept<'p>(&self, parser: &mut Parser<'p>, _token: Token) {
        if let Some(_) = self.handler() {
            parser.commands.push(self.clone())
        }
    }
}

impl Accept for Rc<ParameterNode> {
    fn accept<'p>(&self, parser: &mut Parser<'p>, token: Token) {
        if self.repeatable() {
            unimplemented!();
        } else {
            parser.parameters.insert(self.name().clone(), token.text.to_string());
        }
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::rc::Rc;
use std::time::Duration;

use futures::{Future};
use futures::future::{result};
use serde_json;
use tokio_core::reactor::{Handle, Timeout};

use telegram_bot_raw::{Request, ResponseWrapper, Response};

use connector::{Connector, ConnectorConfig, SpecifiedConnector, DefaultConnector};
use errors::ErrorKind;
use future::{TelegramFuture, NewTelegramFuture};
use stream::UpdatesStream;

const TELEGRAM_URL: &'static str = "https://api.telegram.org/";

/// Main type for sending requests to the Telegram bot API.
#[derive(Clone)]
pub struct Api {
    inner: Rc<ApiInner>,
}

struct ApiInner {
    token: String,
    connector: Box<Connector>,
    handle: Handle,
}

pub trait HasHandle {
    fn handle(&self) -> &Handle;
}

impl HasHandle for Api {
    fn handle(&self) -> &Handle {
        &self.inner.handle
    }
}

#[derive(Debug)]
pub struct Config<Connector> {
    token: String,
    connector: Connector,
}

impl<C: ConnectorConfig> Config<C> {
    pub fn connector(self, connector: Box<Connector>) -> Config<SpecifiedConnector> {
        Config {
            token: self.token,
            connector: SpecifiedConnector::new(connector)
        }
    }

    pub fn build<H: Borrow<Handle>>(self, handle: H) -> Api {
        let handle = handle.borrow().clone();
        Api {
            inner: Rc::new(ApiInner {
                token: self.token,
                connector: self.connector.take(&handle),
                handle: handle,
            }),
        }
    }
}

impl Api {
    /// Start construction of the `Api` instance.
    ///
    /// # Examples
    ///
    /// Using default connector.
    ///
    /// ```rust
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// use telegram_bot::Api;
    /// use tokio_core::reactor::Core;
    ///
    /// # fn main() {
    /// let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// let api = Api::configure(telegram_token).build(core.handle());
    /// # }
    /// ```
    ///
    /// Using custom connector.
    ///
    ///
    /// ```rust
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # #[cfg(feature = "hyper_connector")]
    /// # fn main() {
    /// use telegram_bot::Api;
    /// use telegram_bot::connector::hyper;
    /// use tokio_core::reactor::Core;
    ///
    /// let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// let api = Api::configure(telegram_token)
    ///     .connector(hyper::default_connector(&core.handle()))
    ///     .build(core.handle());
    /// # }
    ///
    /// # #[cfg(not(feature = "hyper_connector"))]
    /// # fn main() {}
    /// ```
    pub fn configure<T: AsRef<str>>(token: T) -> Config<DefaultConnector> {
        Config {
            token: token.as_ref().to_string(),
            connector: DefaultConnector,
        }
    }

    /// Create a stream which produces updates from the Telegram server.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use telegram_bot::Api;
    /// # use tokio_core::reactor::Core;
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let api: Api = Api::configure("token").build(core.handle());
    /// use futures::Stream;
    ///
    /// let future = api.stream().for_each(|update| {
    ///     println!("{:?}", update);
    ///     Ok(())
    /// });
    /// # }
    /// ```
    pub fn stream(&self) -> UpdatesStream {
        UpdatesStream::new(self)
    }

    /// Send a request to the Telegram server and do not wait for a response.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use futures::Future;
    /// # use telegram_bot::{Api, GetMe, ChatId};
    /// # use telegram_bot::prelude::*;
    /// # use tokio_core::reactor::Core;
    /// #
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// # let api = Api::configure(telegram_token).build(core.handle());
    /// # if false {
    /// let chat = ChatId::new(61031);
    /// api.spawn(chat.text("Message"))
    /// # }
    /// # }
    pub fn spawn<Req: Request>(&self, request: Req) {
        self.inner.handle.spawn(self.send(request).then(|_| Ok(())))
    }

    /// Send a request to the Telegram server and wait for a response, timing out after `duration`.
    /// Future will resolve to `None` if timeout fired.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use futures::Future;
    /// # use telegram_bot::{Api, GetMe};
    /// # use tokio_core::reactor::Core;
    /// #
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// # let api = Api::configure(telegram_token).build(core.handle());
    /// # if false {
    /// use std::time::Duration;
    ///
    /// let future = api.send_timeout(GetMe, Duration::from_secs(5));
    /// future.and_then(|me| Ok(assert!(me.is_some())));
    /// # }
    /// # }
    /// ```
    pub fn send_timeout<Req: Request>(
        &self, request: Req, duration: Duration)
        -> TelegramFuture<Option<<Req::Response as Response>::Type>> {

        let timeout_future = result(Timeout::new(duration, &self.inner.handle))
            .flatten().map_err(From::from).map(|()| None);
        let send_future = self.send(request).map(|resp| Some(resp));

        let future = timeout_future.select(send_future)
            .map(|(item, _next)| item)
            .map_err(|(item, _next)| item);

        TelegramFuture::new(Box::new(future))
    }

    /// Send a request to the Telegram server and wait for a response.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use futures::Future;
    /// # use telegram_bot::{Api, GetMe};
    /// # use tokio_core::reactor::Core;
    /// #
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// # let api = Api::configure(telegram_token).build(core.handle());
    /// # if false {
    /// let future = api.send(GetMe);
    /// future.and_then(|me| Ok(println!("{:?}", me)));
    /// # }
    /// # }
    /// ```
    pub fn send<Req: Request>(&self, request: Req)
        -> TelegramFuture<<Req::Response as Response>::Type> {

        let name = request.name();
        let encoded = result(serde_json::to_vec(&request).map_err(From::from));
        let url = url(&self.inner.token, name);

        let api = self.clone();
        let response = encoded.and_then(move |data| {
            api.inner.connector.post_json(&url, data)
        });

        let future = response.and_then(|bytes| {
            result(serde_json::from_slice(&bytes).map_err(From::from).and_then(|value| {
                match value {
                    ResponseWrapper::Success {result} => Ok(Req::Response::map(result)),
                    ResponseWrapper::Error { description, parameters } => {
                        Err(ErrorKind::TelegramError {
                            description: description,
                            parameters: parameters
                        }.into())
                    },
                }
            }))
        });

        TelegramFuture::new(Box::new(future))
    }
}

fn url(token: &str, method: &str) -> String {
    format!("{}bot{}/{}", TELEGRAM_URL, token, method)
}
<commit_msg>docs: document Config type<commit_after>use std::borrow::Borrow;
use std::rc::Rc;
use std::time::Duration;

use futures::{Future};
use futures::future::{result};
use serde_json;
use tokio_core::reactor::{Handle, Timeout};

use telegram_bot_raw::{Request, ResponseWrapper, Response};

use connector::{Connector, ConnectorConfig, SpecifiedConnector, DefaultConnector};
use errors::ErrorKind;
use future::{TelegramFuture, NewTelegramFuture};
use stream::UpdatesStream;

const TELEGRAM_URL: &'static str = "https://api.telegram.org/";

/// Main type for sending requests to the Telegram bot API.
#[derive(Clone)]
pub struct Api {
    inner: Rc<ApiInner>,
}

struct ApiInner {
    token: String,
    connector: Box<Connector>,
    handle: Handle,
}

pub trait HasHandle {
    fn handle(&self) -> &Handle;
}

impl HasHandle for Api {
    fn handle(&self) -> &Handle {
        &self.inner.handle
    }
}

/// Configuration for an `Api`.
#[derive(Debug)]
pub struct Config<Connector> {
    token: String,
    connector: Connector,
}

impl<C: ConnectorConfig> Config<C> {
    /// Set connector type for an `Api`.
    pub fn connector(self, connector: Box<Connector>) -> Config<SpecifiedConnector> {
        Config {
            token: self.token,
            connector: SpecifiedConnector::new(connector)
        }
    }

    /// Create new `Api` instance.
    pub fn build<H: Borrow<Handle>>(self, handle: H) -> Api {
        let handle = handle.borrow().clone();
        Api {
            inner: Rc::new(ApiInner {
                token: self.token,
                connector: self.connector.take(&handle),
                handle: handle,
            }),
        }
    }
}

impl Api {
    /// Start construction of the `Api` instance.
    ///
    /// # Examples
    ///
    /// Using default connector.
    ///
    /// ```rust
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// use telegram_bot::Api;
    /// use tokio_core::reactor::Core;
    ///
    /// # fn main() {
    /// let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// let api = Api::configure(telegram_token).build(core.handle());
    /// # }
    /// ```
    ///
    /// Using custom connector.
    ///
    ///
    /// ```rust
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # #[cfg(feature = "hyper_connector")]
    /// # fn main() {
    /// use telegram_bot::Api;
    /// use telegram_bot::connector::hyper;
    /// use tokio_core::reactor::Core;
    ///
    /// let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// let api = Api::configure(telegram_token)
    ///     .connector(hyper::default_connector(&core.handle()))
    ///     .build(core.handle());
    /// # }
    ///
    /// # #[cfg(not(feature = "hyper_connector"))]
    /// # fn main() {}
    /// ```
    pub fn configure<T: AsRef<str>>(token: T) -> Config<DefaultConnector> {
        Config {
            token: token.as_ref().to_string(),
            connector: DefaultConnector,
        }
    }

    /// Create a stream which produces updates from the Telegram server.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use telegram_bot::Api;
    /// # use tokio_core::reactor::Core;
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let api: Api = Api::configure("token").build(core.handle());
    /// use futures::Stream;
    ///
    /// let future = api.stream().for_each(|update| {
    ///     println!("{:?}", update);
    ///     Ok(())
    /// });
    /// # }
    /// ```
    pub fn stream(&self) -> UpdatesStream {
        UpdatesStream::new(self)
    }

    /// Send a request to the Telegram server and do not wait for a response.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use futures::Future;
    /// # use telegram_bot::{Api, GetMe, ChatId};
    /// # use telegram_bot::prelude::*;
    /// # use tokio_core::reactor::Core;
    /// #
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// # let api = Api::configure(telegram_token).build(core.handle());
    /// # if false {
    /// let chat = ChatId::new(61031);
    /// api.spawn(chat.text("Message"))
    /// # }
    /// # }
    pub fn spawn<Req: Request>(&self, request: Req) {
        self.inner.handle.spawn(self.send(request).then(|_| Ok(())))
    }

    /// Send a request to the Telegram server and wait for a response, timing out after `duration`.
    /// Future will resolve to `None` if timeout fired.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use futures::Future;
    /// # use telegram_bot::{Api, GetMe};
    /// # use tokio_core::reactor::Core;
    /// #
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// # let api = Api::configure(telegram_token).build(core.handle());
    /// # if false {
    /// use std::time::Duration;
    ///
    /// let future = api.send_timeout(GetMe, Duration::from_secs(5));
    /// future.and_then(|me| Ok(assert!(me.is_some())));
    /// # }
    /// # }
    /// ```
    pub fn send_timeout<Req: Request>(
        &self, request: Req, duration: Duration)
        -> TelegramFuture<Option<<Req::Response as Response>::Type>> {

        let timeout_future = result(Timeout::new(duration, &self.inner.handle))
            .flatten().map_err(From::from).map(|()| None);
        let send_future = self.send(request).map(|resp| Some(resp));

        let future = timeout_future.select(send_future)
            .map(|(item, _next)| item)
            .map_err(|(item, _next)| item);

        TelegramFuture::new(Box::new(future))
    }

    /// Send a request to the Telegram server and wait for a response.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate telegram_bot;
    /// # extern crate tokio_core;
    /// # use futures::Future;
    /// # use telegram_bot::{Api, GetMe};
    /// # use tokio_core::reactor::Core;
    /// #
    /// # fn main() {
    /// # let core = Core::new().unwrap();
    /// # let telegram_token = "token";
    /// # let api = Api::configure(telegram_token).build(core.handle());
    /// # if false {
    /// let future = api.send(GetMe);
    /// future.and_then(|me| Ok(println!("{:?}", me)));
    /// # }
    /// # }
    /// ```
    pub fn send<Req: Request>(&self, request: Req)
        -> TelegramFuture<<Req::Response as Response>::Type> {

        let name = request.name();
        let encoded = result(serde_json::to_vec(&request).map_err(From::from));
        let url = url(&self.inner.token, name);

        let api = self.clone();
        let response = encoded.and_then(move |data| {
            api.inner.connector.post_json(&url, data)
        });

        let future = response.and_then(|bytes| {
            result(serde_json::from_slice(&bytes).map_err(From::from).and_then(|value| {
                match value {
                    ResponseWrapper::Success {result} => Ok(Req::Response::map(result)),
                    ResponseWrapper::Error { description, parameters } => {
                        Err(ErrorKind::TelegramError {
                            description: description,
                            parameters: parameters
                        }.into())
                    },
                }
            }))
        });

        TelegramFuture::new(Box::new(future))
    }
}

fn url(token: &str, method: &str) -> String {
    format!("{}bot{}/{}", TELEGRAM_URL, token, method)
}
<|endoftext|>


<commit_before>use crate::errno::errno;

/*
    Helper function to get errno
*/
pub fn get_errno_with_message(ret: i32) -> String {
    let e = errno();
    let code = e.0 as i32;
    format!("return code = {}, errno = {}, message = '{}'", ret, code, e)
}

/// Helper function that depending on the `ret` value:
/// - is negative or 0, then form an error message from the `errno` value
/// - is positive, take `ret` as the length of the success message in `buf` in bytes
pub fn check_errno(ret: i32, buf: &mut Vec<u8>) -> Result<String, String> {
    if ret <= 0 {
        Err(get_errno_with_message(ret))
    } else {
        unsafe {
            buf.set_len(ret as usize);
        }

        match String::from_utf8(buf.to_vec()) {
            Ok(return_value) => Ok(return_value),
            Err(e) => Err(format!("Invalid UTF-8 sequence: {}", e))
        }
    }
}

#[cfg(test)]
mod test {
    use crate::errno::{set_errno, Errno};
    use super::check_errno;

    #[test]
    fn invalid_utf8() {
        let mut buf: Vec<u8> = vec!(255, 0, 0);

        // Test
        match check_errno(buf.len() as i32, &mut buf) {
            Err(msg) => assert_eq!(msg, "Invalid UTF-8 sequence: invalid utf-8 sequence of 1 bytes from index 0"),
            Ok(_) => panic!("Unexpected success"),
        }
    }

    #[test]
    fn positive_ret() {
        let message = "custom message";
        let mut buf: Vec<u8> = Vec::from(message.as_bytes());

        // Test
        match check_errno(buf.len() as i32, &mut buf) {
            Err(e) => panic!("Unexpected error {}", e),
            Ok(mes) => assert_eq!(mes, message)
        }
    }

    #[test]
    fn negative_ret() {
        let mut buf: Vec<u8> = vec!();
        set_errno(Errno(-1));

        // Test
        match check_errno(-1, &mut buf) {
            #[cfg(target_os = "macos")]
            Err(mes) => assert_eq!(mes, "return code = -1, errno = -1, message = 'Unknown error: -1'"),
            #[cfg(target_os = "linux")]
            Err(mes) => assert_eq!(mes, "return code = -1, errno = -1, message = 'Unknown error -1'"),
            Ok(_) => panic!("Unexpected success")
        }
    }

    #[test]
    fn zero_ret() {
        let mut buf: Vec<u8> = vec!();
        set_errno(Errno(0));

        // Test
        match check_errno(0, &mut buf) {
            #[cfg(target_os = "macos")]
            Err(mes) => assert_eq!(mes, "return code = 0, errno = 0, message = 'Undefined error: 0'"),
            #[cfg(target_os = "macos")]
            Ok(_) => panic!("Unexpected success"),
            #[cfg(target_os = "linux")]
            Err(e) => panic!("Unexpected failure {}", e),
            #[cfg(target_os = "linux")]
            Ok(msg) => assert_eq!(msg, "return code = 0, errno = 0, message = 'Success'")
        }
    }

}<commit_msg>errno differences in linux<commit_after>use crate::errno::errno;

/*
    Helper function to get errno
*/
pub fn get_errno_with_message(ret: i32) -> String {
    let e = errno();
    let code = e.0 as i32;
    format!("return code = {}, errno = {}, message = '{}'", ret, code, e)
}

/// Helper function that depending on the `ret` value:
/// - is negative or 0, then form an error message from the `errno` value
/// - is positive, take `ret` as the length of the success message in `buf` in bytes
pub fn check_errno(ret: i32, buf: &mut Vec<u8>) -> Result<String, String> {
    if ret <= 0 {
        Err(get_errno_with_message(ret))
    } else {
        unsafe {
            buf.set_len(ret as usize);
        }

        match String::from_utf8(buf.to_vec()) {
            Ok(return_value) => Ok(return_value),
            Err(e) => Err(format!("Invalid UTF-8 sequence: {}", e))
        }
    }
}

#[cfg(test)]
mod test {
    use crate::errno::{set_errno, Errno};
    use super::check_errno;

    #[test]
    fn invalid_utf8() {
        let mut buf: Vec<u8> = vec!(255, 0, 0);

        // Test
        match check_errno(buf.len() as i32, &mut buf) {
            Err(msg) => assert_eq!(msg, "Invalid UTF-8 sequence: invalid utf-8 sequence of 1 bytes from index 0"),
            Ok(_) => panic!("Unexpected success"),
        }
    }

    #[test]
    fn positive_ret() {
        let message = "custom message";
        let mut buf: Vec<u8> = Vec::from(message.as_bytes());

        // Test
        match check_errno(buf.len() as i32, &mut buf) {
            Err(e) => panic!("Unexpected error {}", e),
            Ok(mes) => assert_eq!(mes, message)
        }
    }

    #[test]
    fn negative_ret() {
        let mut buf: Vec<u8> = vec!();
        set_errno(Errno(-1));

        // Test
        match check_errno(-1, &mut buf) {
            #[cfg(target_os = "macos")]
            Err(mes) => assert_eq!(mes, "return code = -1, errno = -1, message = 'Unknown error: -1'"),
            #[cfg(target_os = "linux")]
            Err(mes) => assert_eq!(mes, "return code = -1, errno = -1, message = 'Unknown error -1'"),
            Ok(_) => panic!("Unexpected success")
        }
    }

    #[test]
    fn zero_ret() {
        let mut buf: Vec<u8> = vec!();
        set_errno(Errno(2));

        // Test
        match check_errno(0, &mut buf) {
            #[cfg(target_os = "macos")]
            Err(mes) => assert_eq!(mes, "return code = 0, errno = 2, message = 'No such file or directory'"),
            #[cfg(target_os = "macos")]
            Ok(_) => panic!("Unexpected success"),
            #[cfg(target_os = "linux")]
            Err(e) => panic!("Unexpected failure {}", e),
            #[cfg(target_os = "linux")]
            Ok(msg) => assert_eq!(msg, "return code = 0, errno = 0, message = 'Success'")
        }
    }

}<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![experimental]
#![macro_escape]

//! A typesafe bitmask flag generator.

/// The `bitflags!` macro generates a `struct` that holds a set of C-style
/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
///
/// The flags should only be defined for integer types, otherwise unexpected
/// type errors may occur at compile time.
///
/// # Example
///
/// ~~~rust
/// bitflags! {
///     flags Flags: u32 {
///         static FlagA       = 0x00000001,
///         static FlagB       = 0x00000010,
///         static FlagC       = 0x00000100,
///         static FlagABC     = FlagA.bits
///                            | FlagB.bits
///                            | FlagC.bits,
///     }
/// }
///
/// fn main() {
///     let e1 = FlagA | FlagC;
///     let e2 = FlagB | FlagC;
///     assert!((e1 | e2) == FlagABC);   // union
///     assert!((e1 & e2) == FlagC);     // intersection
///     assert!((e1 - e2) == FlagA);     // set difference
///     assert!(!e2 == FlagA);           // set complement
/// }
/// ~~~
///
/// The generated `struct`s can also be extended with type and trait implementations:
///
/// ~~~rust
/// use std::fmt;
///
/// bitflags! {
///     flags Flags: u32 {
///         static FlagA   = 0x00000001,
///         static FlagB   = 0x00000010,
///     }
/// }
///
/// impl Flags {
///     pub fn clear(&mut self) {
///         self.bits = 0;  // The `bits` field can be accessed from within the
///                         // same module where the `bitflags!` macro was invoked.
///     }
/// }
///
/// impl fmt::Show for Flags {
///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
///         write!(f, "hi!")
///     }
/// }
///
/// fn main() {
///     let mut flags = FlagA | FlagB;
///     flags.clear();
///     assert!(flags.is_empty());
///     assert_eq!(format!("{}", flags).as_slice(), "hi!");
/// }
/// ~~~
///
/// # Attributes
///
/// Attributes can be attached to the generated `struct` by placing them
/// before the `flags` keyword.
///
/// # Derived traits
///
/// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
/// the `deriving` attribute. Additional traits can be derived by providing an
/// explicit `deriving` attribute on `flags`.
///
/// # Operators
///
/// The following operator traits are implemented for the generated `struct`:
///
/// - `BitOr`: union
/// - `BitAnd`: intersection
/// - `Sub`: set difference
/// - `Not`: set complement
///
/// # Methods
///
/// The following methods are defined for the generated `struct`:
///
/// - `empty`: an empty set of flags
/// - `all`: the set of all flags
/// - `bits`: the raw value of the flags currently stored
/// - `is_empty`: `true` if no flags are currently stored
/// - `is_all`: `true` if all flags are currently set
/// - `intersects`: `true` if there are flags common to both `self` and `other`
/// - `contains`: `true` all of the flags in `other` are contained within `self`
/// - `insert`: inserts the specified flags in-place
/// - `remove`: removes the specified flags in-place
#[macro_export]
macro_rules! bitflags {
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
    }) => {
        #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
        $(#[$attr])*
        pub struct $BitFlags {
            bits: $T,
        }

        $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+

        impl $BitFlags {
            /// Returns an empty set of flags.
            pub fn empty() -> $BitFlags {
                $BitFlags { bits: 0 }
            }

            /// Returns the set containing all flags.
            pub fn all() -> $BitFlags {
                $BitFlags { bits: $($value)|+ }
            }

            /// Returns the raw value of the flags currently stored.
            pub fn bits(&self) -> $T {
                self.bits
            }

            /// Convert from underlying bit representation, unless that
            /// representation contains bits that do not correspond to a flag.
            pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                if (bits & !$BitFlags::all().bits()) != 0 {
                    ::std::option::None
                } else {
                    ::std::option::Some($BitFlags { bits: bits })
                }
            }

            /// Convert from underlying bit representation, dropping any bits
            /// that do not correspond to flags.
            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
                $BitFlags { bits: bits } & $BitFlags::all()
            }

            /// Returns `true` if no flags are currently stored.
            pub fn is_empty(&self) -> bool {
                *self == $BitFlags::empty()
            }

            /// Returns `true` if all flags are currently set.
            pub fn is_all(&self) -> bool {
                *self == $BitFlags::all()
            }

            /// Returns `true` if there are flags common to both `self` and `other`.
            pub fn intersects(&self, other: $BitFlags) -> bool {
                !(self & other).is_empty()
            }

            /// Returns `true` all of the flags in `other` are contained within `self`.
            #[inline]
            pub fn contains(&self, other: $BitFlags) -> bool {
                (self & other) == other
            }

            /// Inserts the specified flags in-place.
            pub fn insert(&mut self, other: $BitFlags) {
                self.bits |= other.bits;
            }

            /// Removes the specified flags in-place.
            pub fn remove(&mut self, other: $BitFlags) {
                self.bits &= !other.bits;
            }
        }

        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the union of the two sets of flags.
            #[inline]
            fn bitor(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits | other.bits }
            }
        }

        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the intersection between the two sets of flags.
            #[inline]
            fn bitand(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & other.bits }
            }
        }

        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the set difference of the two sets of flags.
            #[inline]
            fn sub(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & !other.bits }
            }
        }

        impl Not<$BitFlags> for $BitFlags {
            /// Returns the complement of this set of flags.
            #[inline]
            fn not(&self) -> $BitFlags {
                $BitFlags { bits: !self.bits } & $BitFlags::all()
            }
        }
    };
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
    }) => {
        bitflags! {
            $(#[$attr])*
            flags $BitFlags: u32 {
                $($(#[$Flag_attr])* static $Flag = $value),+
            }
        }
    };
}

#[cfg(test)]
mod tests {
    use hash;
    use option::{Some, None};
    use ops::{BitOr, BitAnd, Sub, Not};

    bitflags! {
        #[doc = "> The first principle is that you must not fool yourself — and"]
        #[doc = "> you are the easiest person to fool."]
        #[doc = "> "]
        #[doc = "> - Richard Feynman"]
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            #[doc = "* cmr bed"]
            #[doc = "* strcat table"]
            #[doc = "<strcat> wait what?"]
            static FlagABC     = FlagA.bits
                               | FlagB.bits
                               | FlagC.bits,
        }
    }

    #[test]
    fn test_bits(){
        assert_eq!(Flags::empty().bits(), 0x00000000);
        assert_eq!(FlagA.bits(), 0x00000001);
        assert_eq!(FlagABC.bits(), 0x00000111);
    }

    #[test]
    fn test_from_bits() {
        assert!(Flags::from_bits(0) == Some(Flags::empty()));
        assert!(Flags::from_bits(0x1) == Some(FlagA));
        assert!(Flags::from_bits(0x10) == Some(FlagB));
        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
        assert!(Flags::from_bits(0x1000) == None);
    }

    #[test]
    fn test_from_bits_truncate() {
        assert!(Flags::from_bits_truncate(0) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1) == FlagA);
        assert!(Flags::from_bits_truncate(0x10) == FlagB);
        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
    }

    #[test]
    fn test_is_empty(){
        assert!(Flags::empty().is_empty());
        assert!(!FlagA.is_empty());
        assert!(!FlagABC.is_empty());
    }

    #[test]
    fn test_is_all() {
        assert!(Flags::all().is_all());
        assert!(!FlagA.is_all());
        assert!(FlagABC.is_all());
    }

    #[test]
    fn test_two_empties_do_not_intersect() {
        let e1 = Flags::empty();
        let e2 = Flags::empty();
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_empty_does_not_intersect_with_full() {
        let e1 = Flags::empty();
        let e2 = FlagABC;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_disjoint_intersects() {
        let e1 = FlagA;
        let e2 = FlagB;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_overlapping_intersects() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(e1.intersects(e2));
    }

    #[test]
    fn test_contains() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(!e1.contains(e2));
        assert!(e2.contains(e1));
        assert!(FlagABC.contains(e2));
    }

    #[test]
    fn test_insert(){
        let mut e1 = FlagA;
        let e2 = FlagA | FlagB;
        e1.insert(e2);
        assert!(e1 == e2);
    }

    #[test]
    fn test_remove(){
        let mut e1 = FlagA | FlagB;
        let e2 = FlagA | FlagC;
        e1.remove(e2);
        assert!(e1 == FlagB);
    }

    #[test]
    fn test_operators() {
        let e1 = FlagA | FlagC;
        let e2 = FlagB | FlagC;
        assert!((e1 | e2) == FlagABC);   // union
        assert!((e1 & e2) == FlagC);     // intersection
        assert!((e1 - e2) == FlagA);     // set difference
        assert!(!e2 == FlagA);           // set complement
    }

    #[test]
    fn test_lt() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(!(a < b) && !(b < a));
        b = FlagB;
        assert!(a < b);
        a = FlagC;
        assert!(!(a < b) && b < a);
        b = FlagC | FlagB;
        assert!(a < b);
    }

    #[test]
    fn test_ord() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(a <= b && a >= b);
        a = FlagA;
        assert!(a > b && a >= b);
        assert!(b < a && b <= a);
        b = FlagB;
        assert!(b > a && b >= a);
        assert!(a < b && a <= b);
    }

    #[test]
    fn test_hash() {
      let mut x = Flags::empty();
      let mut y = Flags::empty();
      assert!(hash::hash(&x) == hash::hash(&y));
      x = Flags::all();
      y = FlagABC;
      assert!(hash::hash(&x) == hash::hash(&y));
    }
}
<commit_msg>auto merge of #17404 : alexcrichton/rust/bitflags-u32, r=sfackler<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![experimental]
#![macro_escape]

//! A typesafe bitmask flag generator.

/// The `bitflags!` macro generates a `struct` that holds a set of C-style
/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
///
/// The flags should only be defined for integer types, otherwise unexpected
/// type errors may occur at compile time.
///
/// # Example
///
/// ~~~rust
/// bitflags! {
///     flags Flags: u32 {
///         static FlagA       = 0x00000001,
///         static FlagB       = 0x00000010,
///         static FlagC       = 0x00000100,
///         static FlagABC     = FlagA.bits
///                            | FlagB.bits
///                            | FlagC.bits,
///     }
/// }
///
/// fn main() {
///     let e1 = FlagA | FlagC;
///     let e2 = FlagB | FlagC;
///     assert!((e1 | e2) == FlagABC);   // union
///     assert!((e1 & e2) == FlagC);     // intersection
///     assert!((e1 - e2) == FlagA);     // set difference
///     assert!(!e2 == FlagA);           // set complement
/// }
/// ~~~
///
/// The generated `struct`s can also be extended with type and trait implementations:
///
/// ~~~rust
/// use std::fmt;
///
/// bitflags! {
///     flags Flags: u32 {
///         static FlagA   = 0x00000001,
///         static FlagB   = 0x00000010,
///     }
/// }
///
/// impl Flags {
///     pub fn clear(&mut self) {
///         self.bits = 0;  // The `bits` field can be accessed from within the
///                         // same module where the `bitflags!` macro was invoked.
///     }
/// }
///
/// impl fmt::Show for Flags {
///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
///         write!(f, "hi!")
///     }
/// }
///
/// fn main() {
///     let mut flags = FlagA | FlagB;
///     flags.clear();
///     assert!(flags.is_empty());
///     assert_eq!(format!("{}", flags).as_slice(), "hi!");
/// }
/// ~~~
///
/// # Attributes
///
/// Attributes can be attached to the generated `struct` by placing them
/// before the `flags` keyword.
///
/// # Derived traits
///
/// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
/// the `deriving` attribute. Additional traits can be derived by providing an
/// explicit `deriving` attribute on `flags`.
///
/// # Operators
///
/// The following operator traits are implemented for the generated `struct`:
///
/// - `BitOr`: union
/// - `BitAnd`: intersection
/// - `Sub`: set difference
/// - `Not`: set complement
///
/// # Methods
///
/// The following methods are defined for the generated `struct`:
///
/// - `empty`: an empty set of flags
/// - `all`: the set of all flags
/// - `bits`: the raw value of the flags currently stored
/// - `is_empty`: `true` if no flags are currently stored
/// - `is_all`: `true` if all flags are currently set
/// - `intersects`: `true` if there are flags common to both `self` and `other`
/// - `contains`: `true` all of the flags in `other` are contained within `self`
/// - `insert`: inserts the specified flags in-place
/// - `remove`: removes the specified flags in-place
#[macro_export]
macro_rules! bitflags {
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
    }) => {
        #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
        $(#[$attr])*
        pub struct $BitFlags {
            bits: $T,
        }

        $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+

        impl $BitFlags {
            /// Returns an empty set of flags.
            pub fn empty() -> $BitFlags {
                $BitFlags { bits: 0 }
            }

            /// Returns the set containing all flags.
            pub fn all() -> $BitFlags {
                $BitFlags { bits: $($value)|+ }
            }

            /// Returns the raw value of the flags currently stored.
            pub fn bits(&self) -> $T {
                self.bits
            }

            /// Convert from underlying bit representation, unless that
            /// representation contains bits that do not correspond to a flag.
            pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                if (bits & !$BitFlags::all().bits()) != 0 {
                    ::std::option::None
                } else {
                    ::std::option::Some($BitFlags { bits: bits })
                }
            }

            /// Convert from underlying bit representation, dropping any bits
            /// that do not correspond to flags.
            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
                $BitFlags { bits: bits } & $BitFlags::all()
            }

            /// Returns `true` if no flags are currently stored.
            pub fn is_empty(&self) -> bool {
                *self == $BitFlags::empty()
            }

            /// Returns `true` if all flags are currently set.
            pub fn is_all(&self) -> bool {
                *self == $BitFlags::all()
            }

            /// Returns `true` if there are flags common to both `self` and `other`.
            pub fn intersects(&self, other: $BitFlags) -> bool {
                !(self & other).is_empty()
            }

            /// Returns `true` all of the flags in `other` are contained within `self`.
            #[inline]
            pub fn contains(&self, other: $BitFlags) -> bool {
                (self & other) == other
            }

            /// Inserts the specified flags in-place.
            pub fn insert(&mut self, other: $BitFlags) {
                self.bits |= other.bits;
            }

            /// Removes the specified flags in-place.
            pub fn remove(&mut self, other: $BitFlags) {
                self.bits &= !other.bits;
            }
        }

        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the union of the two sets of flags.
            #[inline]
            fn bitor(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits | other.bits }
            }
        }

        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the intersection between the two sets of flags.
            #[inline]
            fn bitand(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & other.bits }
            }
        }

        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the set difference of the two sets of flags.
            #[inline]
            fn sub(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & !other.bits }
            }
        }

        impl Not<$BitFlags> for $BitFlags {
            /// Returns the complement of this set of flags.
            #[inline]
            fn not(&self) -> $BitFlags {
                $BitFlags { bits: !self.bits } & $BitFlags::all()
            }
        }
    };
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
    }) => {
        bitflags! {
            $(#[$attr])*
            flags $BitFlags: $T {
                $($(#[$Flag_attr])* static $Flag = $value),+
            }
        }
    };
}

#[cfg(test)]
mod tests {
    use hash;
    use option::{Some, None};
    use ops::{BitOr, BitAnd, Sub, Not};

    bitflags! {
        #[doc = "> The first principle is that you must not fool yourself — and"]
        #[doc = "> you are the easiest person to fool."]
        #[doc = "> "]
        #[doc = "> - Richard Feynman"]
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            #[doc = "* cmr bed"]
            #[doc = "* strcat table"]
            #[doc = "<strcat> wait what?"]
            static FlagABC     = FlagA.bits
                               | FlagB.bits
                               | FlagC.bits,
        }
    }

    bitflags! {
        flags AnotherSetOfFlags: uint {
            static AnotherFlag = 1u,
        }
    }

    #[test]
    fn test_bits(){
        assert_eq!(Flags::empty().bits(), 0x00000000);
        assert_eq!(FlagA.bits(), 0x00000001);
        assert_eq!(FlagABC.bits(), 0x00000111);
    }

    #[test]
    fn test_from_bits() {
        assert!(Flags::from_bits(0) == Some(Flags::empty()));
        assert!(Flags::from_bits(0x1) == Some(FlagA));
        assert!(Flags::from_bits(0x10) == Some(FlagB));
        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
        assert!(Flags::from_bits(0x1000) == None);
    }

    #[test]
    fn test_from_bits_truncate() {
        assert!(Flags::from_bits_truncate(0) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1) == FlagA);
        assert!(Flags::from_bits_truncate(0x10) == FlagB);
        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
    }

    #[test]
    fn test_is_empty(){
        assert!(Flags::empty().is_empty());
        assert!(!FlagA.is_empty());
        assert!(!FlagABC.is_empty());
    }

    #[test]
    fn test_is_all() {
        assert!(Flags::all().is_all());
        assert!(!FlagA.is_all());
        assert!(FlagABC.is_all());
    }

    #[test]
    fn test_two_empties_do_not_intersect() {
        let e1 = Flags::empty();
        let e2 = Flags::empty();
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_empty_does_not_intersect_with_full() {
        let e1 = Flags::empty();
        let e2 = FlagABC;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_disjoint_intersects() {
        let e1 = FlagA;
        let e2 = FlagB;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_overlapping_intersects() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(e1.intersects(e2));
    }

    #[test]
    fn test_contains() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(!e1.contains(e2));
        assert!(e2.contains(e1));
        assert!(FlagABC.contains(e2));
    }

    #[test]
    fn test_insert(){
        let mut e1 = FlagA;
        let e2 = FlagA | FlagB;
        e1.insert(e2);
        assert!(e1 == e2);
    }

    #[test]
    fn test_remove(){
        let mut e1 = FlagA | FlagB;
        let e2 = FlagA | FlagC;
        e1.remove(e2);
        assert!(e1 == FlagB);
    }

    #[test]
    fn test_operators() {
        let e1 = FlagA | FlagC;
        let e2 = FlagB | FlagC;
        assert!((e1 | e2) == FlagABC);   // union
        assert!((e1 & e2) == FlagC);     // intersection
        assert!((e1 - e2) == FlagA);     // set difference
        assert!(!e2 == FlagA);           // set complement
    }

    #[test]
    fn test_lt() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(!(a < b) && !(b < a));
        b = FlagB;
        assert!(a < b);
        a = FlagC;
        assert!(!(a < b) && b < a);
        b = FlagC | FlagB;
        assert!(a < b);
    }

    #[test]
    fn test_ord() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(a <= b && a >= b);
        a = FlagA;
        assert!(a > b && a >= b);
        assert!(b < a && b <= a);
        b = FlagB;
        assert!(b > a && b >= a);
        assert!(a < b && a <= b);
    }

    #[test]
    fn test_hash() {
      let mut x = Flags::empty();
      let mut y = Flags::empty();
      assert!(hash::hash(&x) == hash::hash(&y));
      x = Flags::all();
      y = FlagABC;
      assert!(hash::hash(&x) == hash::hash(&y));
    }
}
<|endoftext|>


<commit_before>use ::ast::*;
use ::ast::ExprNode::*;
use super::*;
use super::parser_combinators::{Parser,parser};

#[test]
fn test_basic_ident() {
    assert_eq!(
        parser(expr).parse("ident"),
        Ok((Name(NameNode { name: "ident".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("a"),
        Ok((Name(NameNode { name: "a".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("ident_With\\special!Chars:~-+"),
        Ok((Name(NameNode { name: "ident_With\\special!Chars:~-+".to_string() }), ""))
        );
}

#[test]
fn test_basic_sexpr() {
    assert_eq!(
        parser(expr).parse("(ident arg1 arg2)"),
        Ok((SExpr(SExprNode {
            operator: NameNode { name: "ident".to_string() },
            operands: vec![
                Name(NameNode { name: "arg1".to_string() }),
                Name(NameNode { name: "arg2".to_string() })
            ]
        }), ""))
        );
}

#[test]
fn test_parse_sint_pos() {
    assert_eq!(
        parser(number).parse("1234"),
        Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#d1234"),
        Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#D1234"),
        Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
        );
}

#[test]
fn test_parse_sint_neg() {
    assert_eq!(
        parser(number).parse("-1234"),
        Ok((NumNode::IntConst(IntNode { value: -1234isize }), ""))
        );
}

#[test]
fn test_parse_sint_hex() {
    assert_eq!(
        parser(number).parse("#x0ff"),
        Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FF"),
        Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
        );
}
/* // Currently unsupported
#[test]
fn test_parse_sint_bin_upper() {
    assert_eq!(
        parser(number).parse("0B01"),
        Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
        );
    assert_eq!(
        parser(number).parse("0b01"),
        Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
        );
}*/

#[test]
fn test_parse_uint() {
    assert_eq!(
        parser(number).parse("1234u"),
        Ok((NumNode::UIntConst(UIntNode { value: 1234usize }), ""))
        );
    assert_eq!(
        parser(number).parse("4321U"),
        Ok((NumNode::UIntConst(UIntNode { value: 4321usize }), ""))
        );
}

#[test]
fn test_parse_uint_hex() {
    assert_eq!(
        parser(number).parse("#x0ffu"),
        Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FFu"),
        Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
}

#[test]
fn test_parse_float() {
    assert_eq!(
        parser(number).parse("1.0"),
        Ok((NumNode::FloatConst(FloatNode { value: 1.0f64 }), ""))
        );/* // Unsupported
    assert_eq!(
        parser(number).parse("1f").unwrap(),
        (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222").unwrap(),
        (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222f").unwrap(),
        (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
        );*/
}

#[test]
fn test_parse_bool() {
    assert_eq!(
        parser(bool_const).parse("#t"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#T"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("true"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#f"),
        Ok((BoolNode { value: false}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#F"),
        Ok((BoolNode { value: false}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("false"),
        Ok((BoolNode { value: false}, ""))
        );
}

#[test]
fn test_parse_char() {
    assert_eq!(
        parser(character).parse("#\\c"),
        Ok((CharNode { value: 'c'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\A"),
        Ok((CharNode { value: 'A'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\tab"),
        Ok((CharNode { value: '\t'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\newline"),
        Ok((CharNode { value: '\n'}, ""))
        );
}

<commit_msg>Add tests for R6RS named characters<commit_after>use ::ast::*;
use ::ast::ExprNode::*;
use super::*;
use super::parser_combinators::{Parser,parser};
use std::char;

#[test]
fn test_basic_ident() {
    assert_eq!(
        parser(expr).parse("ident"),
        Ok((Name(NameNode { name: "ident".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("a"),
        Ok((Name(NameNode { name: "a".to_string() }), ""))
        );
    assert_eq!(
        parser(expr).parse("ident_With\\special!Chars:~-+"),
        Ok((Name(NameNode { name: "ident_With\\special!Chars:~-+".to_string() }), ""))
        );
}

#[test]
fn test_basic_sexpr() {
    assert_eq!(
        parser(expr).parse("(ident arg1 arg2)"),
        Ok((SExpr(SExprNode {
            operator: NameNode { name: "ident".to_string() },
            operands: vec![
                Name(NameNode { name: "arg1".to_string() }),
                Name(NameNode { name: "arg2".to_string() })
            ]
        }), ""))
        );
}

#[test]
fn test_parse_sint_pos() {
    assert_eq!(
        parser(number).parse("1234"),
        Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#d1234"),
        Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
        );
    assert_eq!(
        parser(number).parse("#D1234"),
        Ok((NumNode::IntConst(IntNode { value: 1234isize }), ""))
        );
}

#[test]
fn test_parse_sint_neg() {
    assert_eq!(
        parser(number).parse("-1234"),
        Ok((NumNode::IntConst(IntNode { value: -1234isize }), ""))
        );
}

#[test]
fn test_parse_sint_hex() {
    assert_eq!(
        parser(number).parse("#x0ff"),
        Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FF"),
        Ok((NumNode::IntConst(IntNode { value: 0x0ffisize }), ""))
        );
}
/* // Currently unsupported
#[test]
fn test_parse_sint_bin_upper() {
    assert_eq!(
        parser(number).parse("0B01"),
        Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
        );
    assert_eq!(
        parser(number).parse("0b01"),
        Ok((NumNode::IntConst(IntNode { value: 0b01isize }), ""))
        );
}*/

#[test]
fn test_parse_uint() {
    assert_eq!(
        parser(number).parse("1234u"),
        Ok((NumNode::UIntConst(UIntNode { value: 1234usize }), ""))
        );
    assert_eq!(
        parser(number).parse("4321U"),
        Ok((NumNode::UIntConst(UIntNode { value: 4321usize }), ""))
        );
}

#[test]
fn test_parse_uint_hex() {
    assert_eq!(
        parser(number).parse("#x0ffu"),
        Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
    assert_eq!(
        parser(number).parse("#X0FFu"),
        Ok((NumNode::UIntConst(UIntNode { value: 0x0ffusize }), ""))
        );
}

#[test]
fn test_parse_float() {
    assert_eq!(
        parser(number).parse("1.0"),
        Ok((NumNode::FloatConst(FloatNode { value: 1.0f64 }), ""))
        );/* // Unsupported
    assert_eq!(
        parser(number).parse("1f").unwrap(),
        (NumNode::FloatConst(FloatNode { value: 1.0f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222").unwrap(),
        (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
        );
    assert_eq!(
        parser(number).parse("22.2222f").unwrap(),
        (NumNode::FloatConst(FloatNode { value: 22.2222f64 }), "")
        );*/
}

#[test]
fn test_parse_bool() {
    assert_eq!(
        parser(bool_const).parse("#t"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#T"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("true"),
        Ok((BoolNode { value: true}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#f"),
        Ok((BoolNode { value: false}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("#F"),
        Ok((BoolNode { value: false}, ""))
        );
    assert_eq!(
        parser(bool_const).parse("false"),
        Ok((BoolNode { value: false}, ""))
        );
}

#[test]
fn test_parse_char() {
    assert_eq!(
        parser(character).parse("#\\c"),
        Ok((CharNode { value: 'c'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\A"),
        Ok((CharNode { value: 'A'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\tab"),
        Ok((CharNode { value: '\t'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\newline"),
        Ok((CharNode { value: '\n'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\nul"),
        Ok((CharNode { value: char::from_u32(0x0000).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\backspace"),
        Ok((CharNode { value: char::from_u32(0x0008).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\vtab"),
        Ok((CharNode { value: char::from_u32(0x000B).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\page"),
        Ok((CharNode { value: char::from_u32(0x000C).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\return"),
        Ok((CharNode { value: char::from_u32(0x000D).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\esc"),
        Ok((CharNode { value: char::from_u32(0x001B).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\delete"),
        Ok((CharNode { value: char::from_u32(0x007F).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\alarm"),
        Ok((CharNode { value: char::from_u32(0x0007).unwrap()}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\linefeed"),
        Ok((CharNode { value: '\n'}, ""))
        );
    assert_eq!(
        parser(character).parse("#\\space"),
        Ok((CharNode { value: ' '}, ""))
        );
}

<|endoftext|>