<commit_before>/* Copyright 2018 Torbjørn Birch Moltu
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://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.
 */

// uses /usr/share/dict/ for text to convert to Vec<Utf*Char> and iterate over
#![cfg(all(unix, feature="std"))]
#![feature(test)]
extern crate test;
use test::{Bencher, black_box};
#[macro_use] extern crate lazy_static;
extern crate encode_unicode;
use encode_unicode::{CharExt, Utf8Char, Utf16Char, IterExt};

static ENGLISH: &str = include_str!("/usr/share/dict/american-english");
// TODO find a big chinese file; `aptitude search '?provides(wordlist)'` didn't have one
lazy_static!{
    static ref UTF8CHARS: Vec<Utf8Char> = ENGLISH.chars().map(|c| c.to_utf8() ).collect();
    static ref UTF16CHARS: Vec<Utf16Char> = ENGLISH.chars().map(|c| c.to_utf16() ).collect();
}

#[bench]
fn utf16_split_all_single_mulititerator(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF16CHARS).iter().to_units().for_each(|u| assert!(u != 0) );
    });
}
#[bench]
fn utf16_split_all_single_flatmap(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF16CHARS).iter().cloned().flatten().for_each(|u| assert!(u != 0) );
    });
}
#[bench]
fn utf16_split_all_single_cloned_flatten(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF16CHARS).iter().cloned().flatten().for_each(|u| assert!(u != 0) );
    });
}

#[bench]
fn utf8_split_mostly_ascii_multiiterator(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF8CHARS).iter().to_bytes().for_each(|b| assert!(b != 0) );
    });
}
#[bench]
fn utf8_split_mostly_ascii_flatmap(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF8CHARS).iter().cloned().flatten().for_each(|b| assert!(b != 0) );
    });
}
#[bench]
fn utf8_split_mostly_ascii_cloned_flatten(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF8CHARS).iter().cloned().flatten().for_each(|b| assert!(b != 0) );
    });
}

#[bench]
fn utf8_extend_mostly_ascii_multiiterator(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u8> = black_box(&*UTF8CHARS).iter().to_bytes().collect();
        assert_eq!(black_box(vec).len(), ENGLISH.len());
    });
}
#[bench]
fn utf8_extend_mostly_ascii_custom(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u8> = black_box(&*UTF8CHARS).iter().collect();
        assert_eq!(black_box(vec).len(), ENGLISH.len());
    });
}
#[bench]
fn utf8_extend_mostly_ascii_custom_str(b: &mut Bencher) {
    b.iter(|| {
        let vec: String = black_box(&*UTF8CHARS).iter().cloned().collect();
        assert_eq!(black_box(vec).len(), ENGLISH.len());
    });
}

#[bench]
fn utf16_extend_all_single_multiiterator(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u16> = black_box(&*UTF16CHARS).iter().to_units().collect();
        assert!(black_box(vec).len() < ENGLISH.len());
    });
}
#[bench]
fn utf16_extend_all_single_custom(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u16> = black_box(&*UTF16CHARS).iter().collect();
        assert!(black_box(vec).len() < ENGLISH.len());
    });
}
<commit_msg>Skip multiiterators benchmarks if wordlist file doesn't exist<commit_after>/* Copyright 2018 Torbjørn Birch Moltu
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://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.
 */

// uses /usr/share/dict/ for text to convert to Vec<Utf*Char> and iterate over
#![cfg(all(unix, feature="std"))]
#![feature(test)]
extern crate test;
use test::{Bencher, black_box};
#[macro_use] extern crate lazy_static;
extern crate encode_unicode;
use encode_unicode::{CharExt, Utf8Char, Utf16Char, IterExt};

fn read_or_exit(file: &str) -> String {
    let mut fd = std::fs::File::open(file).unwrap_or_else(|err| {
        if err.kind() == std::io::ErrorKind::NotFound {
            eprintln!("{} not found, skipping benchmarks.", file);
            std::process::exit(0);
        } else {
            eprintln!("Failed to open {}: {}.", file, err);
            std::process::exit(1);
        }
    });
    let mut content = String::new();
    std::io::Read::read_to_string(&mut fd, &mut content).unwrap_or_else(|err| {
        eprintln!("Failed to read {}: {}.", file, err);
        std::process::exit(1);
    });
    content
}

lazy_static!{
    // TODO find a big chinese file; `aptitude search '?provides(wordlist)'` didn't have one
    static ref ENGLISH: String = read_or_exit("/usr/share/dict/american-english");
    static ref UTF8CHARS: Vec<Utf8Char> = ENGLISH.chars().map(|c| c.to_utf8() ).collect();
    static ref UTF16CHARS: Vec<Utf16Char> = ENGLISH.chars().map(|c| c.to_utf16() ).collect();
}

#[bench]
fn utf16_split_all_single_mulititerator(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF16CHARS).iter().to_units().for_each(|u| assert!(u != 0) );
    });
}
#[bench]
fn utf16_split_all_single_flatmap(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF16CHARS).iter().cloned().flatten().for_each(|u| assert!(u != 0) );
    });
}
#[bench]
fn utf16_split_all_single_cloned_flatten(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF16CHARS).iter().cloned().flatten().for_each(|u| assert!(u != 0) );
    });
}

#[bench]
fn utf8_split_mostly_ascii_multiiterator(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF8CHARS).iter().to_bytes().for_each(|b| assert!(b != 0) );
    });
}
#[bench]
fn utf8_split_mostly_ascii_flatmap(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF8CHARS).iter().cloned().flatten().for_each(|b| assert!(b != 0) );
    });
}
#[bench]
fn utf8_split_mostly_ascii_cloned_flatten(b: &mut Bencher) {
    b.iter(|| {
        black_box(&*UTF8CHARS).iter().cloned().flatten().for_each(|b| assert!(b != 0) );
    });
}

#[bench]
fn utf8_extend_mostly_ascii_multiiterator(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u8> = black_box(&*UTF8CHARS).iter().to_bytes().collect();
        assert_eq!(black_box(vec).len(), ENGLISH.len());
    });
}
#[bench]
fn utf8_extend_mostly_ascii_custom(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u8> = black_box(&*UTF8CHARS).iter().collect();
        assert_eq!(black_box(vec).len(), ENGLISH.len());
    });
}
#[bench]
fn utf8_extend_mostly_ascii_custom_str(b: &mut Bencher) {
    b.iter(|| {
        let vec: String = black_box(&*UTF8CHARS).iter().cloned().collect();
        assert_eq!(black_box(vec).len(), ENGLISH.len());
    });
}

#[bench]
fn utf16_extend_all_single_multiiterator(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u16> = black_box(&*UTF16CHARS).iter().to_units().collect();
        assert!(black_box(vec).len() < ENGLISH.len());
    });
}
#[bench]
fn utf16_extend_all_single_custom(b: &mut Bencher) {
    b.iter(|| {
        let vec: Vec<u16> = black_box(&*UTF16CHARS).iter().collect();
        assert!(black_box(vec).len() < ENGLISH.len());
    });
}
<|endoftext|>


<commit_before>#![deny(unsafe_code)]

#[cfg(feature = "open")]
pub mod open;

#[cfg(feature = "plugins")]
pub mod plugins;

#[cfg(feature = "upgrade")]
pub mod upgrade;

#[cfg(feature = "config")]
pub mod config;

#[cfg(feature = "inspect")]
pub mod inspect;

#[cfg(feature = "request")]
pub mod request;

#[cfg(feature = "serve")]
pub mod serve;

#[cfg(any(feature = "request", feature = "serve"))]
pub mod delegate;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod jwt;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod methods;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod protocols;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod rpc;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod urls;

// Methods

pub mod read;
pub mod write;

pub mod decode;
pub mod encode;

pub mod export;
pub mod import;

pub mod convert;

pub mod validate;

pub mod execute;

// Utilities

pub mod util {
    pub mod dirs;
    pub mod params;
}
pub mod logging;
pub mod nodes;

// Re-export packages (mainly for use by stencila-* language packages in this workspace)

pub use anyhow;
pub use regex;
pub use serde;
pub use serde_json;
pub use strum;
pub use tokio;
pub use tracing;
<commit_msg>chore(Rust): Re-export once_cell<commit_after>#![deny(unsafe_code)]

#[cfg(feature = "open")]
pub mod open;

#[cfg(feature = "plugins")]
pub mod plugins;

#[cfg(feature = "upgrade")]
pub mod upgrade;

#[cfg(feature = "config")]
pub mod config;

#[cfg(feature = "inspect")]
pub mod inspect;

#[cfg(feature = "request")]
pub mod request;

#[cfg(feature = "serve")]
pub mod serve;

#[cfg(any(feature = "request", feature = "serve"))]
pub mod delegate;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod jwt;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod methods;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod protocols;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod rpc;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod urls;

// Methods

pub mod read;
pub mod write;

pub mod decode;
pub mod encode;

pub mod export;
pub mod import;

pub mod convert;

pub mod validate;

pub mod execute;

// Utilities

pub mod util {
    pub mod dirs;
    pub mod params;
}
pub mod logging;
pub mod nodes;

// Re-export packages (mainly for use by stencila-* language packages in this workspace)

pub use anyhow;
pub use once_cell;
pub use regex;
pub use serde;
pub use serde_json;
pub use strum;
pub use tokio;
pub use tracing;
<|endoftext|>


<commit_before>use std::io::{self, Read, Write};
use std::sync::Arc;

use futures::{Future, Wake, Tokens, ALL_TOKENS};
use futures::stream::{Stream, StreamResult, Fuse};
use futuremio::*;

pub trait Parse: Sized + Send + 'static {
    type Parser: Default + Send + 'static;
    type Error: Send + 'static + From<io::Error>;

    fn parse(parser: &mut Self::Parser,
             buf: &Arc<Vec<u8>>,
             offset: usize)
             -> Option<Result<(Self, usize), Self::Error>>;
}

/// A stream for parsing from an underlying reader, using an unbounded internal
/// buffer.
pub struct ParseStream<R, P: Parse> {
    source: R,
    source_ready: ReadinessStream,
    parser: P::Parser,
    buf: Arc<Vec<u8>>,

    // how far into the buffer have we parsed? note: we drain lazily
    pos: usize,

    // is there new data that we need to try to parse?
    need_parse: bool,

    // has `source` yielded an EOF?
    eof: bool,
}

impl<R, P> ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    pub fn new(source: R, source_ready: ReadinessStream) -> ParseStream<R, P> {
        ParseStream {
            source: source,
            source_ready: source_ready,
            parser: Default::default(),
            buf: Arc::new(Vec::with_capacity(2048)),
            pos: 0,
            need_parse: false,
            eof: false,
        }
    }
}

// TODO: move this into method
fn read<R: Read>(socket: &mut R, input: &mut Vec<u8>) -> io::Result<(usize, bool)> {
    loop {
        match socket.read(unsafe { slice_to_end(input) }) {
            Ok(0) => {
                trace!("socket EOF");
                return Ok((0, true))
            }
            Ok(n) => {
                trace!("socket read {} bytes", n);
                unsafe {
                    let len = input.len();
                    input.set_len(len + n);
                }
                return Ok((n, false));
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok((0, false)),
            Err(e) => return Err(e),
        }
    }

    unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
        use std::slice;
        if v.capacity() == 0 {
            v.reserve(16);
        }
        if v.capacity() == v.len() {
            v.reserve(1);
        }
        slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
                                  v.capacity() - v.len())
    }
}

impl<R, P> Stream for ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    type Item = P;
    type Error = P::Error;

    fn poll(&mut self, tokens: &Tokens) -> Option<StreamResult<P, P::Error>> {
        loop {
            if self.need_parse {
                debug!("attempting to parse");
                match P::parse(&mut self.parser, &self.buf, self.pos) {
                    Some(Ok((i, n))) => {
                        self.pos += n;
                        return Some(Ok(Some(i)))
                    }
                    Some(Err(e)) => return Some(Err(e)),
                    None => {
                        self.need_parse = false;
                    }
                }

                // Fast path if we can get mutable access to our own current
                // buffer.
                let mut drained = false;
                if let Some(buf) = Arc::get_mut(&mut self.buf) {
                    buf.drain(..self.pos);
                    drained = true;
                }

                // If we couldn't get access above then we give ourself a new
                // buffer here.
                if !drained {
                    let mut v = Vec::with_capacity(2048);
                    v.extend_from_slice(&self.buf[self.pos..]);
                    self.buf = Arc::new(v);
                }
                self.pos = 0;
            }

            if self.eof {
                return Some(Ok(None))
            }

            match self.source_ready.poll(tokens) {
                // TODO: consider refactoring `poll` API to make this more
                //       readable...
                None => return None,
                Some(Err(e)) => return Some(Err(e.into())),
                Some(Ok(Some(()))) => {
                    let buf = Arc::get_mut(&mut self.buf).unwrap();
                    match read(&mut self.source, buf) {
                        Ok((n, eof)) => {
                            self.eof = eof;
                            self.need_parse = self.need_parse || n > 0;
                        }
                        Err(e) => return Some(Err(e.into())),
                    }
                }
                _ => unreachable!(),
            }
        }
    }

    fn schedule(&mut self, wake: Arc<Wake>) {
        // TODO: think through this carefully...
        if self.need_parse {
            // Empty tokens because in a `need_parse` situation, we'll attempt
            // to parse regardless of tokens
            wake.wake(&Tokens::empty())
        } else {
            self.source_ready.schedule(wake)
        }
    }
}

// TODO: make this a method
fn write<W: Write>(sink: &mut W, buf: &mut Vec<u8>) -> io::Result<()> {
    loop {
        match sink.write(&buf) {
            Ok(0) => {
                // TODO: copied from mio example, clean up
                return Err(io::Error::new(io::ErrorKind::Other, "early eof2"));
            }
            Ok(n) => {
                // TODO: consider draining more lazily, i.e. only just before
                //       returning
                buf.drain(..n);
                if buf.len() == 0 {
                    return Ok(());
                }
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok(()),
            Err(e) => return Err(e),
        }
    }
}

pub trait Serialize: Send + 'static {
    fn serialize(&self, buf: &mut Vec<u8>);
}

/// Serialize a stream of items into a writer, using an unbounded internal
/// buffer.
///
/// Represented as a future which yields () on successfully writing the entire
/// stream (which requires the stream to terminate), or an error if there is any
/// error along the way.
pub struct StreamWriter<W, S> {
    sink: W,
    sink_ready: ReadinessStream,
    items: Fuse<S>,
    buf: Vec<u8>,
}

impl<W, S> StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    pub fn new(sink: W, sink_ready: ReadinessStream, items: S) -> StreamWriter<W, S> {
        StreamWriter {
            sink: sink,
            sink_ready: sink_ready,
            items: items.fuse(),
            buf: Vec::with_capacity(2048),
        }
    }
}

impl<W, S> Future for StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    type Item = ();
    type Error = S::Error;

    fn poll(&mut self, tokens: &Tokens) -> Option<Result<(), S::Error>> {
        // make sure to pass down `tokens` only on the *first* poll for items
        let mut tokens_for_items = tokens;
        loop {
            match self.items.poll(tokens_for_items) {
                Some(Err(e)) => return Some(Err(e)),
                Some(Ok(Some(item))) => {
                    debug!("got an item to serialize!");
                    item.serialize(&mut self.buf);
                    tokens_for_items = &ALL_TOKENS;
                }
                Some(Ok(None)) |
                None => break,
            }
        }

        // TODO: optimization for case where we just transitioned from no bytes
        // to write to having bytes to write; in that case, we should try to
        // write regardless of sink_ready.poll, because we haven't asked for a
        // readiness notifcation. Saves a trip around the event loop.

        if self.buf.len() > 0 {
            match self.sink_ready.poll(tokens) {
                Some(Err(e)) => Some(Err(e.into())),
                Some(Ok(Some(()))) => {
                    debug!("trying to write some data");
                    if let Err(e) = write(&mut self.sink, &mut self.buf) {
                        Some(Err(e.into()))
                    } else {
                        None
                    }
                }
                Some(Ok(None)) | // TODO: this should translate to an error
                None => None,
            }
        } else if self.items.is_done() {
            // Nothing more to write to sink, and no more incoming items; we're done!
            Some(Ok(()))
        } else {
            None
        }
    }

    fn schedule(&mut self, wake: Arc<Wake>) {
        // wake up on writability only if we have something to write
        if self.buf.len() > 0 {
            self.sink_ready.schedule(wake.clone());
        }

        // for now, we are always happy to write more items into our unbounded buffer
        self.items.schedule(wake);
    }
}
<commit_msg>Fixup tokens in http<commit_after>use std::io::{self, Read, Write};
use std::sync::Arc;

use futures::{Future, Wake, Tokens, TOKENS_ALL};
use futures::stream::{Stream, StreamResult, Fuse};
use futuremio::*;

pub trait Parse: Sized + Send + 'static {
    type Parser: Default + Send + 'static;
    type Error: Send + 'static + From<io::Error>;

    fn parse(parser: &mut Self::Parser,
             buf: &Arc<Vec<u8>>,
             offset: usize)
             -> Option<Result<(Self, usize), Self::Error>>;
}

/// A stream for parsing from an underlying reader, using an unbounded internal
/// buffer.
pub struct ParseStream<R, P: Parse> {
    source: R,
    source_ready: ReadinessStream,
    parser: P::Parser,
    buf: Arc<Vec<u8>>,

    // how far into the buffer have we parsed? note: we drain lazily
    pos: usize,

    // is there new data that we need to try to parse?
    need_parse: bool,

    // has `source` yielded an EOF?
    eof: bool,
}

impl<R, P> ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    pub fn new(source: R, source_ready: ReadinessStream) -> ParseStream<R, P> {
        ParseStream {
            source: source,
            source_ready: source_ready,
            parser: Default::default(),
            buf: Arc::new(Vec::with_capacity(2048)),
            pos: 0,
            need_parse: false,
            eof: false,
        }
    }
}

// TODO: move this into method
fn read<R: Read>(socket: &mut R, input: &mut Vec<u8>) -> io::Result<(usize, bool)> {
    loop {
        match socket.read(unsafe { slice_to_end(input) }) {
            Ok(0) => {
                trace!("socket EOF");
                return Ok((0, true))
            }
            Ok(n) => {
                trace!("socket read {} bytes", n);
                unsafe {
                    let len = input.len();
                    input.set_len(len + n);
                }
                return Ok((n, false));
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok((0, false)),
            Err(e) => return Err(e),
        }
    }

    unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
        use std::slice;
        if v.capacity() == 0 {
            v.reserve(16);
        }
        if v.capacity() == v.len() {
            v.reserve(1);
        }
        slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
                                  v.capacity() - v.len())
    }
}

impl<R, P> Stream for ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    type Item = P;
    type Error = P::Error;

    fn poll(&mut self, tokens: &Tokens) -> Option<StreamResult<P, P::Error>> {
        loop {
            if self.need_parse {
                debug!("attempting to parse");
                match P::parse(&mut self.parser, &self.buf, self.pos) {
                    Some(Ok((i, n))) => {
                        self.pos += n;
                        return Some(Ok(Some(i)))
                    }
                    Some(Err(e)) => return Some(Err(e)),
                    None => {
                        self.need_parse = false;
                    }
                }

                // Fast path if we can get mutable access to our own current
                // buffer.
                let mut drained = false;
                if let Some(buf) = Arc::get_mut(&mut self.buf) {
                    buf.drain(..self.pos);
                    drained = true;
                }

                // If we couldn't get access above then we give ourself a new
                // buffer here.
                if !drained {
                    let mut v = Vec::with_capacity(2048);
                    v.extend_from_slice(&self.buf[self.pos..]);
                    self.buf = Arc::new(v);
                }
                self.pos = 0;
            }

            if self.eof {
                return Some(Ok(None))
            }

            match self.source_ready.poll(tokens) {
                // TODO: consider refactoring `poll` API to make this more
                //       readable...
                None => return None,
                Some(Err(e)) => return Some(Err(e.into())),
                Some(Ok(Some(()))) => {
                    let buf = Arc::get_mut(&mut self.buf).unwrap();
                    match read(&mut self.source, buf) {
                        Ok((n, eof)) => {
                            self.eof = eof;
                            self.need_parse = self.need_parse || n > 0;
                        }
                        Err(e) => return Some(Err(e.into())),
                    }
                }
                _ => unreachable!(),
            }
        }
    }

    fn schedule(&mut self, wake: Arc<Wake>) {
        // TODO: think through this carefully...
        if self.need_parse {
            // Empty tokens because in a `need_parse` situation, we'll attempt
            // to parse regardless of tokens
            wake.wake(&Tokens::empty())
        } else {
            self.source_ready.schedule(wake)
        }
    }
}

// TODO: make this a method
fn write<W: Write>(sink: &mut W, buf: &mut Vec<u8>) -> io::Result<()> {
    loop {
        match sink.write(&buf) {
            Ok(0) => {
                // TODO: copied from mio example, clean up
                return Err(io::Error::new(io::ErrorKind::Other, "early eof2"));
            }
            Ok(n) => {
                // TODO: consider draining more lazily, i.e. only just before
                //       returning
                buf.drain(..n);
                if buf.len() == 0 {
                    return Ok(());
                }
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok(()),
            Err(e) => return Err(e),
        }
    }
}

pub trait Serialize: Send + 'static {
    fn serialize(&self, buf: &mut Vec<u8>);
}

/// Serialize a stream of items into a writer, using an unbounded internal
/// buffer.
///
/// Represented as a future which yields () on successfully writing the entire
/// stream (which requires the stream to terminate), or an error if there is any
/// error along the way.
pub struct StreamWriter<W, S> {
    sink: W,
    sink_ready: ReadinessStream,
    items: Fuse<S>,
    buf: Vec<u8>,
}

impl<W, S> StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    pub fn new(sink: W, sink_ready: ReadinessStream, items: S) -> StreamWriter<W, S> {
        StreamWriter {
            sink: sink,
            sink_ready: sink_ready,
            items: items.fuse(),
            buf: Vec::with_capacity(2048),
        }
    }
}

impl<W, S> Future for StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    type Item = ();
    type Error = S::Error;

    fn poll(&mut self, tokens: &Tokens) -> Option<Result<(), S::Error>> {
        // make sure to pass down `tokens` only on the *first* poll for items
        let mut tokens_for_items = tokens;
        loop {
            match self.items.poll(tokens_for_items) {
                Some(Err(e)) => return Some(Err(e)),
                Some(Ok(Some(item))) => {
                    debug!("got an item to serialize!");
                    item.serialize(&mut self.buf);
                    tokens_for_items = &TOKENS_ALL;
                }
                Some(Ok(None)) |
                None => break,
            }
        }

        // TODO: optimization for case where we just transitioned from no bytes
        // to write to having bytes to write; in that case, we should try to
        // write regardless of sink_ready.poll, because we haven't asked for a
        // readiness notifcation. Saves a trip around the event loop.

        if self.buf.len() > 0 {
            match self.sink_ready.poll(tokens) {
                Some(Err(e)) => Some(Err(e.into())),
                Some(Ok(Some(()))) => {
                    debug!("trying to write some data");
                    if let Err(e) = write(&mut self.sink, &mut self.buf) {
                        Some(Err(e.into()))
                    } else {
                        None
                    }
                }
                Some(Ok(None)) | // TODO: this should translate to an error
                None => None,
            }
        } else if self.items.is_done() {
            // Nothing more to write to sink, and no more incoming items; we're done!
            Some(Ok(()))
        } else {
            None
        }
    }

    fn schedule(&mut self, wake: Arc<Wake>) {
        // wake up on writability only if we have something to write
        if self.buf.len() > 0 {
            self.sink_ready.schedule(wake.clone());
        }

        // for now, we are always happy to write more items into our unbounded buffer
        self.items.schedule(wake);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

/*!
A mini version of ast::Ty, which is easier to use, and features an
explicit `Self` type to use when specifying impls to be derived.
*/

use ast;
use ast::{P,Expr,Generics,Ident};
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use codemap::{Span,respan};
use owned_slice::OwnedSlice;
use parse::token::special_idents;

use std::gc::Gc;

/// The types of pointers
pub enum PtrTy<'a> {
    /// ~
    Send,
    /// &'lifetime mut
    Borrowed(Option<&'a str>, ast::Mutability),
}

/// A path, e.g. `::std::option::Option::<int>` (global). Has support
/// for type parameters and a lifetime.
pub struct Path<'a> {
    pub path: Vec<&'a str> ,
    pub lifetime: Option<&'a str>,
    pub params: Vec<Box<Ty<'a>>>,
    pub global: bool,
}

impl<'a> Path<'a> {
    pub fn new<'r>(path: Vec<&'r str> ) -> Path<'r> {
        Path::new_(path, None, Vec::new(), true)
    }
    pub fn new_local<'r>(path: &'r str) -> Path<'r> {
        Path::new_(vec!( path ), None, Vec::new(), false)
    }
    pub fn new_<'r>(path: Vec<&'r str> ,
                    lifetime: Option<&'r str>,
                    params: Vec<Box<Ty<'r>>>,
                    global: bool)
                    -> Path<'r> {
        Path {
            path: path,
            lifetime: lifetime,
            params: params,
            global: global
        }
    }

    pub fn to_ty(&self,
                 cx: &ExtCtxt,
                 span: Span,
                 self_ty: Ident,
                 self_generics: &Generics)
                 -> P<ast::Ty> {
        cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
    }
    pub fn to_path(&self,
                   cx: &ExtCtxt,
                   span: Span,
                   self_ty: Ident,
                   self_generics: &Generics)
                   -> ast::Path {
        let idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
        let lt = mk_lifetimes(cx, span, &self.lifetime);
        let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();

        cx.path_all(span, self.global, idents, lt, tys)
    }
}

/// A type. Supports pointers (except for *), Self, and literals
pub enum Ty<'a> {
    Self,
    /// &/Box/ Ty
    Ptr(Box<Ty<'a>>, PtrTy<'a>),
    /// mod::mod::Type<[lifetime], [Params...]>, including a plain type
    /// parameter, and things like `int`
    Literal(Path<'a>),
    /// includes unit
    Tuple(Vec<Ty<'a>> )
}

pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
    Borrowed(None, ast::MutImmutable)
}
pub fn borrowed<'r>(ty: Box<Ty<'r>>) -> Ty<'r> {
    Ptr(ty, borrowed_ptrty())
}

pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
    Some(Some(borrowed_ptrty()))
}

pub fn borrowed_self<'r>() -> Ty<'r> {
    borrowed(box Self)
}

pub fn nil_ty() -> Ty<'static> {
    Tuple(Vec::new())
}

fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
    match *lt {
        Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
        None => None
    }
}

fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
    match *lt {
        Some(ref s) => vec!(cx.lifetime(span, cx.ident_of(*s).name)),
        None => vec!()
    }
}

impl<'a> Ty<'a> {
    pub fn to_ty(&self,
                 cx: &ExtCtxt,
                 span: Span,
                 self_ty: Ident,
                 self_generics: &Generics)
                 -> P<ast::Ty> {
        match *self {
            Ptr(ref ty, ref ptr) => {
                let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
                match *ptr {
                    Send => {
                        cx.ty_uniq(span, raw_ty)
                    }
                    Borrowed(ref lt, mutbl) => {
                        let lt = mk_lifetime(cx, span, lt);
                        cx.ty_rptr(span, raw_ty, lt, mutbl)
                    }
                }
            }
            Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
            Self  => {
                cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
            }
            Tuple(ref fields) => {
                let ty = if fields.is_empty() {
                    ast::TyNil
                } else {
                    ast::TyTup(fields.iter()
                                     .map(|f| f.to_ty(cx, span, self_ty, self_generics))
                                     .collect())
                };

                cx.ty(span, ty)
            }
        }
    }

    pub fn to_path(&self,
                   cx: &ExtCtxt,
                   span: Span,
                   self_ty: Ident,
                   self_generics: &Generics)
                   -> ast::Path {
        match *self {
            Self => {
                let self_params = self_generics.ty_params.map(|ty_param| {
                    cx.ty_ident(span, ty_param.ident)
                });
                let lifetimes = self_generics.lifetimes.clone();

                cx.path_all(span, false, vec!(self_ty), lifetimes,
                            self_params.into_vec())
            }
            Literal(ref p) => {
                p.to_path(cx, span, self_ty, self_generics)
            }
            Ptr(..) => { cx.span_bug(span, "pointer in a path in generic `deriving`") }
            Tuple(..) => { cx.span_bug(span, "tuple in a path in generic `deriving`") }
        }
    }
}

fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
               bounds: &[Path], unbound: Option<ast::TyParamBound>,
               self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
    let bounds =
        bounds.iter().map(|b| {
            let path = b.to_path(cx, span, self_ident, self_generics);
            cx.typarambound(path)
        }).collect();
    cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
}

fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics {
    Generics {
        lifetimes: lifetimes,
        ty_params: OwnedSlice::from_vec(ty_params)
    }
}

/// Lifetimes and bounds on type parameters
pub struct LifetimeBounds<'a> {
    pub lifetimes: Vec<&'a str>,
    pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>,
}

impl<'a> LifetimeBounds<'a> {
    pub fn empty() -> LifetimeBounds<'static> {
        LifetimeBounds {
            lifetimes: Vec::new(), bounds: Vec::new()
        }
    }
    pub fn to_generics(&self,
                       cx: &ExtCtxt,
                       span: Span,
                       self_ty: Ident,
                       self_generics: &Generics)
                       -> Generics {
        let lifetimes = self.lifetimes.iter().map(|lt| {
            cx.lifetime(span, cx.ident_of(*lt).name)
        }).collect();
        let ty_params = self.bounds.iter().map(|t| {
            match t {
                &(ref name, ref unbound, ref bounds) => {
                    mk_ty_param(cx,
                                span,
                                *name,
                                bounds.as_slice(),
                                unbound.clone(),
                                self_ty,
                                self_generics)
                }
            }
        }).collect();
        mk_generics(lifetimes, ty_params)
    }
}

pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
    -> (Gc<Expr>, ast::ExplicitSelf) {
    // this constructs a fresh `self` path, which will match the fresh `self` binding
    // created below.
    let self_path = cx.expr_self(span);
    match *self_ptr {
        None => {
            (self_path, respan(span, ast::SelfValue(special_idents::self_)))
        }
        Some(ref ptr) => {
            let self_ty = respan(
                span,
                match *ptr {
                    Send => ast::SelfUniq(special_idents::self_),
                    Borrowed(ref lt, mutbl) => {
                        let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
                        ast::SelfRegion(lt, mutbl, special_idents::self_)
                    }
                });
            let self_expr = cx.expr_deref(span, self_path);
            (self_expr, self_ty)
        }
    }
}
<commit_msg>libsyntax: Remove `Send` from `PtrTy` in `deriving`.<commit_after>// Copyright 2013 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.

/*!
A mini version of ast::Ty, which is easier to use, and features an
explicit `Self` type to use when specifying impls to be derived.
*/

use ast;
use ast::{P,Expr,Generics,Ident};
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use codemap::{Span,respan};
use owned_slice::OwnedSlice;
use parse::token::special_idents;

use std::gc::Gc;

/// The types of pointers
pub enum PtrTy<'a> {
    /// &'lifetime mut
    Borrowed(Option<&'a str>, ast::Mutability),
}

/// A path, e.g. `::std::option::Option::<int>` (global). Has support
/// for type parameters and a lifetime.
pub struct Path<'a> {
    pub path: Vec<&'a str> ,
    pub lifetime: Option<&'a str>,
    pub params: Vec<Box<Ty<'a>>>,
    pub global: bool,
}

impl<'a> Path<'a> {
    pub fn new<'r>(path: Vec<&'r str> ) -> Path<'r> {
        Path::new_(path, None, Vec::new(), true)
    }
    pub fn new_local<'r>(path: &'r str) -> Path<'r> {
        Path::new_(vec!( path ), None, Vec::new(), false)
    }
    pub fn new_<'r>(path: Vec<&'r str> ,
                    lifetime: Option<&'r str>,
                    params: Vec<Box<Ty<'r>>>,
                    global: bool)
                    -> Path<'r> {
        Path {
            path: path,
            lifetime: lifetime,
            params: params,
            global: global
        }
    }

    pub fn to_ty(&self,
                 cx: &ExtCtxt,
                 span: Span,
                 self_ty: Ident,
                 self_generics: &Generics)
                 -> P<ast::Ty> {
        cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
    }
    pub fn to_path(&self,
                   cx: &ExtCtxt,
                   span: Span,
                   self_ty: Ident,
                   self_generics: &Generics)
                   -> ast::Path {
        let idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
        let lt = mk_lifetimes(cx, span, &self.lifetime);
        let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();

        cx.path_all(span, self.global, idents, lt, tys)
    }
}

/// A type. Supports pointers (except for *), Self, and literals
pub enum Ty<'a> {
    Self,
    /// &/Box/ Ty
    Ptr(Box<Ty<'a>>, PtrTy<'a>),
    /// mod::mod::Type<[lifetime], [Params...]>, including a plain type
    /// parameter, and things like `int`
    Literal(Path<'a>),
    /// includes unit
    Tuple(Vec<Ty<'a>> )
}

pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
    Borrowed(None, ast::MutImmutable)
}
pub fn borrowed<'r>(ty: Box<Ty<'r>>) -> Ty<'r> {
    Ptr(ty, borrowed_ptrty())
}

pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
    Some(Some(borrowed_ptrty()))
}

pub fn borrowed_self<'r>() -> Ty<'r> {
    borrowed(box Self)
}

pub fn nil_ty() -> Ty<'static> {
    Tuple(Vec::new())
}

fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
    match *lt {
        Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
        None => None
    }
}

fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
    match *lt {
        Some(ref s) => vec!(cx.lifetime(span, cx.ident_of(*s).name)),
        None => vec!()
    }
}

impl<'a> Ty<'a> {
    pub fn to_ty(&self,
                 cx: &ExtCtxt,
                 span: Span,
                 self_ty: Ident,
                 self_generics: &Generics)
                 -> P<ast::Ty> {
        match *self {
            Ptr(ref ty, ref ptr) => {
                let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
                match *ptr {
                    Borrowed(ref lt, mutbl) => {
                        let lt = mk_lifetime(cx, span, lt);
                        cx.ty_rptr(span, raw_ty, lt, mutbl)
                    }
                }
            }
            Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
            Self  => {
                cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
            }
            Tuple(ref fields) => {
                let ty = if fields.is_empty() {
                    ast::TyNil
                } else {
                    ast::TyTup(fields.iter()
                                     .map(|f| f.to_ty(cx, span, self_ty, self_generics))
                                     .collect())
                };

                cx.ty(span, ty)
            }
        }
    }

    pub fn to_path(&self,
                   cx: &ExtCtxt,
                   span: Span,
                   self_ty: Ident,
                   self_generics: &Generics)
                   -> ast::Path {
        match *self {
            Self => {
                let self_params = self_generics.ty_params.map(|ty_param| {
                    cx.ty_ident(span, ty_param.ident)
                });
                let lifetimes = self_generics.lifetimes.clone();

                cx.path_all(span, false, vec!(self_ty), lifetimes,
                            self_params.into_vec())
            }
            Literal(ref p) => {
                p.to_path(cx, span, self_ty, self_generics)
            }
            Ptr(..) => { cx.span_bug(span, "pointer in a path in generic `deriving`") }
            Tuple(..) => { cx.span_bug(span, "tuple in a path in generic `deriving`") }
        }
    }
}

fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
               bounds: &[Path], unbound: Option<ast::TyParamBound>,
               self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
    let bounds =
        bounds.iter().map(|b| {
            let path = b.to_path(cx, span, self_ident, self_generics);
            cx.typarambound(path)
        }).collect();
    cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
}

fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics {
    Generics {
        lifetimes: lifetimes,
        ty_params: OwnedSlice::from_vec(ty_params)
    }
}

/// Lifetimes and bounds on type parameters
pub struct LifetimeBounds<'a> {
    pub lifetimes: Vec<&'a str>,
    pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>,
}

impl<'a> LifetimeBounds<'a> {
    pub fn empty() -> LifetimeBounds<'static> {
        LifetimeBounds {
            lifetimes: Vec::new(), bounds: Vec::new()
        }
    }
    pub fn to_generics(&self,
                       cx: &ExtCtxt,
                       span: Span,
                       self_ty: Ident,
                       self_generics: &Generics)
                       -> Generics {
        let lifetimes = self.lifetimes.iter().map(|lt| {
            cx.lifetime(span, cx.ident_of(*lt).name)
        }).collect();
        let ty_params = self.bounds.iter().map(|t| {
            match t {
                &(ref name, ref unbound, ref bounds) => {
                    mk_ty_param(cx,
                                span,
                                *name,
                                bounds.as_slice(),
                                unbound.clone(),
                                self_ty,
                                self_generics)
                }
            }
        }).collect();
        mk_generics(lifetimes, ty_params)
    }
}

pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
    -> (Gc<Expr>, ast::ExplicitSelf) {
    // this constructs a fresh `self` path, which will match the fresh `self` binding
    // created below.
    let self_path = cx.expr_self(span);
    match *self_ptr {
        None => {
            (self_path, respan(span, ast::SelfValue(special_idents::self_)))
        }
        Some(ref ptr) => {
            let self_ty = respan(
                span,
                match *ptr {
                    Borrowed(ref lt, mutbl) => {
                        let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
                        ast::SelfRegion(lt, mutbl, special_idents::self_)
                    }
                });
            let self_expr = cx.expr_deref(span, self_path);
            (self_expr, self_ty)
        }
    }
}
<|endoftext|>


<commit_before>//! View bits in memory with turtles
//!
//! This example uses [@myrrlyn]'s [`bitvec`] crate to turn data into strings of
//! bits, and then draws them on the screen.
//!
//! You are encouraged to change both the data used to seed the turtle, and the
//! `bitvec` calls that control how the turtle acts, to see what changes.
//!
//! [@myrrlyn]: //github.com/myrrlyn
//! [`bitvec`]: //crates.io/crates/bitvec

// This imports the things we need from `bitvec`, including the `Bits` trait for
// the `.view_bits::<_>()` method we use to view memory.
use bitvec::prelude::*;
use turtle::Turtle;

// Modify these constants to change the behavior of the example.

/// This text will be inspected as individual bytes, and drawn on the screen.
/// You can change it to see what different text looks like when viewed as bits.
///
/// The example program will print more information about the parts of the text
/// to the console while the turtle draws, so that you can see how each glyph
/// corresponds to parts of the rendered memory.
static TEXT: &str = "¡Hola, mundo! 🌍🌏🌎";

/// This number will have its bit pattern printed on screen. Rust provides some
/// interesting numbers in its standard library; you can replace this with other
/// numbers to see what they look like. Pi is provided as the default solely
/// because it is well-known, and has an interesting pattern.
const NUMBER: f32 = std::f32::consts::PI;

/// This controls the width of the drawn line for each bit.
const BIT_WIDTH: f64 = 20.0;

/// This controls the vertical spacing between rows of bit lines.
const BIT_HEIGHT: f64 = 10.0;

/// Set the horizontal spacing between successive bits in a row
const BIT_MARGIN: f64 = BIT_WIDTH / 2.0;

/// Compute the total width of a bit plus its spacing
const BIT_BOX: f64 = BIT_WIDTH + BIT_MARGIN;

fn main() {
    // This block sets up the turtle to draw bits more or less centered in the
    // screen. The turtle works by walking horizontally for each bit in a byte,
    // then backtracking and walking vertically to the next byte.
    let mut turtle = Turtle::new();
    // The turtle starts in the center of the screen, but we want to move it
    // around before drawing.
    turtle.pen_up();

    // Compute the boundaries of the part of the screen where the turtle will
    // draw. We expect to be drawing eight bits, with half to the right of
    // center and half to the left.
    let right_edge = BIT_BOX * 8.0 / 2.0;
    // We also expect to be drawing a row for each byte in the text, with an
    // additional separator row for each *character*, half above and half below
    // the center of the screen. This computes how many rows of text we will
    // draw, then moves the turtle appropriately.
    let byte_rows = TEXT.len();
    let char_gaps = TEXT.chars().count();
    let top_edge = BIT_HEIGHT * ((byte_rows + char_gaps) as f64 / 2.0);
    // The turtle starts from the top right of the region,
    turtle.forward(top_edge);
    turtle.right(90.0);
    turtle.forward(right_edge);
    // and walks left
    turtle.left(180.0);

    draw_text(&mut turtle, TEXT);

    // The `draw_number` function reads bits from left to right, so the turtle
    // should also walk from left to right. The `draw_number` function expects
    // that it will be drawing rows sixteen bits long, so it needs to move
    // forward another four bits' worth of space in order to be in the correct
    // spot.
    turtle.forward(8.0 * BIT_BOX / 2.0);
    turtle.forward(16.0 * BIT_BOX / 2.0);
    // Then, it needs to turn around, to walk in the other direction.
    turtle.right(180.0);

    draw_number(&mut turtle, NUMBER);
}

/// Draws the bits of a text span on the screen.
fn draw_text(turtle: &mut Turtle, text: &str) {
    // Rust strings can iterate over their individual characters. This block
    // loops over characters, collecting their start point in the text so that
    // we can grab the encoded bytes of each one.
    let mut row_num = 0;
    for (char_num, (start, codepoint)) in text.char_indices().enumerate() {
        println!("Character {}: {}", char_num, codepoint);
        // Each character has a variable width, so we need to find that.
        let byte_count = codepoint.len_utf8();
        // And then collect the bytes of the string that make up the character.
        // `start` gives us the starting position in the text sequence, and
        // `byte_count` gives us the length in bytes of the character, so we
        // need to select the range beginning at `start`, running for
        // `byte_count`. Another style of writing this that you might see in
        // Rust libraries is `[start ..][.. length]`.
        let row: &[u8] = &text.as_bytes()[start .. start + byte_count];

        // For each byte (`u8`), we use `bitvec` to make a view into its bits.
        // `bitvec` provides the `.view_bits::<_>()` method on Rust integers for
        // easy access to its view types.
        //
        // The `Lsb0` means that the view moves from least significant bit to
        // most significant. Since we want to display on screen the most
        // significant bit on the left, and the least on the right, the turtle
        // will have to move from right to left to match.
        //
        // The `Lsb0` and `Msb0` types describe different ways to view the same
        // data. You can read more about them in the `bitvec` docs, and at
        // Wikipedia:
        // https://docs.rs/bitvec/0.16.1/bitvec/cursor/index.html
        // https://en.wikipedia.org/wiki/Endianness#Bit_endianness
        for byte in row {
            println!("  Byte {:02}:\n    Value: 0x{:02X}\n    Bits: {:08b}", row_num, byte, byte);

            let bits: &BitSlice<_, _> = byte.view_bits::<Lsb0>();

            // Then we draw the byte's bits as a row
            draw_row(turtle, bits);
            //  And go to the next row
            next_row(turtle, 90.0);

            row_num += 1;
        }
        // This puts a dividing line between each *character* in the text.
        // Some characters may have more than one byte, and those bytes will be
        // grouped together.
        delimit(turtle, 8.0 * BIT_BOX - BIT_MARGIN);
    }
}

/// Draws the bits of a number on screen.
fn draw_number(turtle: &mut Turtle, number: f32) {
    // `bitvec` can look at more than just `u8`. Let's try looking at the bits
    // that represent a number!
    //
    // Some numbers, like `f32`, have special rules for their representation in
    // bits. `bitvec` only knows about raw bits, so it does not provide direct
    // support for `f32`. Rust lets us get the bit representation from an `f32`
    // with the method `to_bits(f32) -> u32`, which forgets about the `f32`
    // rules and uses the number's storage as ordinary bits.
    //
    // You can read more about the rules for `f32`'s storage in memory, and
    // behavior in programs, here:
    // https://en.wikipedia.org/wiki/Double-precision_floating-point_format
    let raw_number: u32 = number.to_bits();

    // `bitvec` can also view bits from left to right, with `Msb0`.
    let bits: &BitSlice<_, _> = raw_number.view_bits::<Msb0>();

    // The `&BitSlice` type acts just like `&[bool]`, so it comes with a
    // `.chunks` method which divides it into smaller pieces. `bitvec` can take
    // any number, not just multiples of 8, but 16 is a convenient number to
    // look at. Try changing it to a different number, like 10, to see what
    // happens!
    for (num, row) in bits.chunks(16).enumerate() {
        println!("Row {} bits: {:b}", num, row);
        // Each chunk produced is a smaller `&BitSlice`, just like
        // `&[bool].chunks` produces smaller `&[bool]`s, so we can draw it.
        draw_row(turtle, row);

        next_row(turtle, -90.0);
    }

    // Reader exercise:
    //
    // The IEEE-754 format for `f32` numbers separates them into three parts:
    //
    // 1. The sign marks whether the number is positive or negative: 1 bit
    // 2. The exponent marks how far from zero the number is: 8 bits
    // 3. The fraction describes the number: 23 bits.
    //
    // Using these widths (1 bit, 8 bits, 23 bits), the knowledge that
    // `&BitSlice` is a normal Rust slice, and the API documentation for
    // `std::iter::Iterator`, see if you can display each portion of an `f32`
    // as its own row.
    //
    // Hints:
    //
    // - The variable `bits` is set up to view the entire number, from most
    // significant bit to least.
    // - You can get access to a structure that performs iteration by calling
    //   `bits.iter()`.
    // - You can use the `Iterator::by_ref` method to prevent `Iterator` adapter
    //   functions from destroying the source iterator.
    // - `&BitSlice` is an ordinary Rust slice, so you can use `[start .. end]`
    //   range indexing to get smaller pieces of it.
}

/// Draw a row of bits on the screen.
///
/// This takes a reference to a turtle, which draws, and a reference to a slice
/// of bits, which provides the data to draw.
///
/// Note that this works whether we're going through the bits left to right
/// (`Msb0`) or right to left (`Lsb0`), because we assume that the turtle is
/// going to start on the correct side and be facing the correct way for this
/// drawing to work.
fn draw_row<O, T>(turtle: &mut Turtle, row: &BitSlice<O, T>)
where O: BitOrder, T: BitStore {
    // `&BitSlice` can iterate over bits. It is just like `&[bool]`, and so it
    // produces `&bool` for each loop.
    for &bit in row {
        // This checks if the bit produced by the row is `1` or `0`, and sets
        // the pen color to black (`1`) or light grey (`0`)
        if bit {
            turtle.set_pen_color("black");
        }
        else {
            turtle.set_pen_color("light grey");
        }

        // For each bit, the loop puts down the pen to draw a line of the bit's
        // color, then picks up the pen to add some horizontal spacing between
        // them.
        turtle.pen_down();
        turtle.forward(BIT_WIDTH);
        turtle.pen_up();
        turtle.forward(BIT_MARGIN);
    }
    //  Rewind the turtle
    for _ in 0 .. row.len() {
        turtle.backward(BIT_BOX);
    }
}

/// Produces a separator line to demark different sections of memory.
fn delimit(turtle: &mut Turtle, width: f64) {
    turtle.set_pen_color("grey");
    turtle.pen_down();
    turtle.forward(width);
    turtle.backward(width);

    next_row(turtle, 90.0);
}

/// Moves the turtle down a row
fn next_row(turtle: &mut Turtle, angle: f64) {
    turtle.pen_up();
    turtle.left(angle);
    turtle.forward(BIT_HEIGHT);
    turtle.right(angle);
}
<commit_msg>Update bits.rs to bitvec 0.20 API<commit_after>//! View bits in memory with turtles
//!
//! This example uses [@myrrlyn]'s [`bitvec`] crate to turn data into strings of
//! bits, and then draws them on the screen.
//!
//! You are encouraged to change both the data used to seed the turtle, and the
//! `bitvec` calls that control how the turtle acts, to see what changes.
//!
//! [@myrrlyn]: //github.com/myrrlyn
//! [`bitvec`]: //crates.io/crates/bitvec

// This imports the things we need from `bitvec`, including the `Bits` trait for
// the `.view_bits::<_>()` method we use to view memory.
use bitvec::prelude::*;
use turtle::Turtle;

// Modify these constants to change the behavior of the example.

/// This text will be inspected as individual bytes, and drawn on the screen.
/// You can change it to see what different text looks like when viewed as bits.
///
/// The example program will print more information about the parts of the text
/// to the console while the turtle draws, so that you can see how each glyph
/// corresponds to parts of the rendered memory.
static TEXT: &str = "¡Hola, mundo! 🌍🌏🌎";

/// This number will have its bit pattern printed on screen. Rust provides some
/// interesting numbers in its standard library; you can replace this with other
/// numbers to see what they look like. Pi is provided as the default solely
/// because it is well-known, and has an interesting pattern.
const NUMBER: f32 = std::f32::consts::PI;

/// This controls the width of the drawn line for each bit.
const BIT_WIDTH: f64 = 20.0;

/// This controls the vertical spacing between rows of bit lines.
const BIT_HEIGHT: f64 = 10.0;

/// Set the horizontal spacing between successive bits in a row
const BIT_MARGIN: f64 = BIT_WIDTH / 2.0;

/// Compute the total width of a bit plus its spacing
const BIT_BOX: f64 = BIT_WIDTH + BIT_MARGIN;

fn main() {
    // This block sets up the turtle to draw bits more or less centered in the
    // screen. The turtle works by walking horizontally for each bit in a byte,
    // then backtracking and walking vertically to the next byte.
    let mut turtle = Turtle::new();
    // The turtle starts in the center of the screen, but we want to move it
    // around before drawing.
    turtle.pen_up();

    // Compute the boundaries of the part of the screen where the turtle will
    // draw. We expect to be drawing eight bits, with half to the right of
    // center and half to the left.
    let right_edge = BIT_BOX * 8.0 / 2.0;
    // We also expect to be drawing a row for each byte in the text, with an
    // additional separator row for each *character*, half above and half below
    // the center of the screen. This computes how many rows of text we will
    // draw, then moves the turtle appropriately.
    let byte_rows = TEXT.len();
    let char_gaps = TEXT.chars().count();
    let top_edge = BIT_HEIGHT * ((byte_rows + char_gaps) as f64 / 2.0);
    // The turtle starts from the top right of the region,
    turtle.forward(top_edge);
    turtle.right(90.0);
    turtle.forward(right_edge);
    // and walks left
    turtle.left(180.0);

    draw_text(&mut turtle, TEXT);

    // The `draw_number` function reads bits from left to right, so the turtle
    // should also walk from left to right. The `draw_number` function expects
    // that it will be drawing rows sixteen bits long, so it needs to move
    // forward another four bits' worth of space in order to be in the correct
    // spot.
    turtle.forward(8.0 * BIT_BOX / 2.0);
    turtle.forward(16.0 * BIT_BOX / 2.0);
    // Then, it needs to turn around, to walk in the other direction.
    turtle.right(180.0);

    draw_number(&mut turtle, NUMBER);
}

/// Draws the bits of a text span on the screen.
fn draw_text(turtle: &mut Turtle, text: &str) {
    // Rust strings can iterate over their individual characters. This block
    // loops over characters, collecting their start point in the text so that
    // we can grab the encoded bytes of each one.
    let mut row_num = 0;
    for (char_num, (start, codepoint)) in text.char_indices().enumerate() {
        println!("Character {}: {}", char_num, codepoint);
        // Each character has a variable width, so we need to find that.
        let byte_count = codepoint.len_utf8();
        // And then collect the bytes of the string that make up the character.
        // `start` gives us the starting position in the text sequence, and
        // `byte_count` gives us the length in bytes of the character, so we
        // need to select the range beginning at `start`, running for
        // `byte_count`. Another style of writing this that you might see in
        // Rust libraries is `[start ..][.. length]`.
        let row: &[u8] = &text.as_bytes()[start .. start + byte_count];

        // For each byte (`u8`), we use `bitvec` to make a view into its bits.
        // `bitvec` provides the `.view_bits::<_>()` method on Rust integers for
        // easy access to its view types.
        //
        // The `Lsb0` means that the view moves from least significant bit to
        // most significant. Since we want to display on screen the most
        // significant bit on the left, and the least on the right, the turtle
        // will have to move from right to left to match.
        //
        // The `Lsb0` and `Msb0` types describe different ways to view the same
        // data. You can read more about them in the `bitvec` docs, and at
        // Wikipedia:
        // https://docs.rs/bitvec/0.16.1/bitvec/cursor/index.html
        // https://en.wikipedia.org/wiki/Endianness#Bit_endianness
        for byte in row {
            println!("  Byte {:02}:\n    Value: 0x{:02X}\n    Bits: {:08b}", row_num, byte, byte);

            let bits: &BitSlice<_, _> = byte.view_bits::<Lsb0>();

            // Then we draw the byte's bits as a row
            draw_row(turtle, bits);
            //  And go to the next row
            next_row(turtle, 90.0);

            row_num += 1;
        }
        // This puts a dividing line between each *character* in the text.
        // Some characters may have more than one byte, and those bytes will be
        // grouped together.
        delimit(turtle, 8.0 * BIT_BOX - BIT_MARGIN);
    }
}

/// Draws the bits of a number on screen.
fn draw_number(turtle: &mut Turtle, number: f32) {
    // `bitvec` can look at more than just `u8`. Let's try looking at the bits
    // that represent a number!
    //
    // Some numbers, like `f32`, have special rules for their representation in
    // bits. `bitvec` only knows about raw bits, so it does not provide direct
    // support for `f32`. Rust lets us get the bit representation from an `f32`
    // with the method `to_bits(f32) -> u32`, which forgets about the `f32`
    // rules and uses the number's storage as ordinary bits.
    //
    // You can read more about the rules for `f32`'s storage in memory, and
    // behavior in programs, here:
    // https://en.wikipedia.org/wiki/Double-precision_floating-point_format
    let raw_number: u32 = number.to_bits();

    // `bitvec` can also view bits from left to right, with `Msb0`.
    let bits: &BitSlice<_, _> = raw_number.view_bits::<Msb0>();

    // The `&BitSlice` type acts just like `&[bool]`, so it comes with a
    // `.chunks` method which divides it into smaller pieces. `bitvec` can take
    // any number, not just multiples of 8, but 16 is a convenient number to
    // look at. Try changing it to a different number, like 10, to see what
    // happens!
    for (num, row) in bits.chunks(16).enumerate() {
        println!("Row {} bits: {:b}", num, row);
        // Each chunk produced is a smaller `&BitSlice`, just like
        // `&[bool].chunks` produces smaller `&[bool]`s, so we can draw it.
        draw_row(turtle, row);

        next_row(turtle, -90.0);
    }

    // Reader exercise:
    //
    // The IEEE-754 format for `f32` numbers separates them into three parts:
    //
    // 1. The sign marks whether the number is positive or negative: 1 bit
    // 2. The exponent marks how far from zero the number is: 8 bits
    // 3. The fraction describes the number: 23 bits.
    //
    // Using these widths (1 bit, 8 bits, 23 bits), the knowledge that
    // `&BitSlice` is a normal Rust slice, and the API documentation for
    // `std::iter::Iterator`, see if you can display each portion of an `f32`
    // as its own row.
    //
    // Hints:
    //
    // - The variable `bits` is set up to view the entire number, from most
    // significant bit to least.
    // - You can get access to a structure that performs iteration by calling
    //   `bits.iter()`.
    // - You can use the `Iterator::by_ref` method to prevent `Iterator` adapter
    //   functions from destroying the source iterator.
    // - `&BitSlice` is an ordinary Rust slice, so you can use `[start .. end]`
    //   range indexing to get smaller pieces of it.
}

/// Draw a row of bits on the screen.
///
/// This takes a reference to a turtle, which draws, and a reference to a slice
/// of bits, which provides the data to draw.
///
/// Note that this works whether we're going through the bits left to right
/// (`Msb0`) or right to left (`Lsb0`), because we assume that the turtle is
/// going to start on the correct side and be facing the correct way for this
/// drawing to work.
fn draw_row<O, T>(turtle: &mut Turtle, row: &BitSlice<O, T>)
where O: BitOrder, T: BitStore {
    // `&BitSlice` can iterate over bits. It is just like `&[bool]`, and so it
    // produces `&bool` for each loop.
    for bit in row.iter().by_val() {
        // This checks if the bit produced by the row is `1` or `0`, and sets
        // the pen color to black (`1`) or light grey (`0`)
        if bit {
            turtle.set_pen_color("black");
        }
        else {
            turtle.set_pen_color("light grey");
        }

        // For each bit, the loop puts down the pen to draw a line of the bit's
        // color, then picks up the pen to add some horizontal spacing between
        // them.
        turtle.pen_down();
        turtle.forward(BIT_WIDTH);
        turtle.pen_up();
        turtle.forward(BIT_MARGIN);
    }
    //  Rewind the turtle
    for _ in 0 .. row.len() {
        turtle.backward(BIT_BOX);
    }
}

/// Produces a separator line to demark different sections of memory.
fn delimit(turtle: &mut Turtle, width: f64) {
    turtle.set_pen_color("grey");
    turtle.pen_down();
    turtle.forward(width);
    turtle.backward(width);

    next_row(turtle, 90.0);
}

/// Moves the turtle down a row
fn next_row(turtle: &mut Turtle, angle: f64) {
    turtle.pen_up();
    turtle.left(angle);
    turtle.forward(BIT_HEIGHT);
    turtle.right(angle);
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use std::fmt;

use serde::{json, Deserialize};

use response::{self, RawPagedResponse, NamedResponse};
use request::{BaseRequest, DoRequest};
use request::PagedRequest;

pub struct RequestBuilder<'t, T> {
    pub auth: &'t str,
    pub url: Option<String>,
    pub resp_t: PhantomData<*const T>
}

impl<'t, T> RequestBuilder<'t, T> {
    pub fn with_auth(t: &'t str) -> RequestBuilder<'t, T> {
        RequestBuilder {
            auth: t,
            url: None,
            resp_t: PhantomData
        }
    }
}

impl<'t, T> fmt::Display for RequestBuilder<'t, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "method: GET\n\
                content-type: application/json\n\
                authorization: Bearer {}\n\
                url: {}", self.auth, if self.url.is_some() { self.url.clone().unwrap() } else { "None".to_owned() })
    }
}

impl<'t, T> BaseRequest for RequestBuilder<'t, T> {
    fn auth(&self) -> &str {
        self.auth
    }
    fn url(&self) -> String {
        if let Some(url) = self.url.clone() {
            url
        } else {
            "".to_owned()
        }
    }
}

impl<'t, I> PagedRequest for RequestBuilder<'t, Vec<I>>
                                              // where T: Deserialize + NewIter<Item=I> + NamedResponse,
                                                    where I: Deserialize + NamedResponse {
    type Item = I;
    fn retrieve_single_page(&self, url: String) -> Result<RawPagedResponse<I>, String> {
        let mut rb: RequestBuilder<'t, Vec<I>> = RequestBuilder::with_auth(self.auth);
        rb.url = Some(url);
        match rb.retrieve_json() {
            Ok(ref s) => {
                 // FIXME \/ \/
                let mut name = <I as NamedResponse>::name().into_owned();
                name.push('s');
                let re = regex!(&format!("\"{}\"", name));
                match json::from_str::<response::RawPagedResponse<I>>(&re.replace(&s[..], "\"collection\"")) {
                // FIXME ^^
                    Ok(val) => {
                        Ok(val)
                    },
                    Err(e) => Err(e.to_string())
                }
            },
            Err(e) => Err(e.to_string())
        }
    }
}

impl<'t, I> DoRequest<Vec<I>> for RequestBuilder<'t, Vec<I>>
                                where I: Deserialize + NamedResponse {
    fn retrieve(&self) -> Result<Vec<I>, String> {
        match self.retrieve_json() {
            Ok(ref s) => {
                 // FIXME \/ \/
                let mut name = <I as NamedResponse>::name().into_owned();
                name.push('s');
                let re = regex!(&format!("\"{}\"", name));
                let res = &re.replace(&s[..], "\"collection\"");
                match json::from_str::<response::RawPagedResponse<I>>(res) {
                // FIXME ^^
                    Ok(mut val) => {
                        let mut regs = vec![];
                        regs.append(&mut val.collection);
                        while let Some(mut val) = val.links.pages.clone() {
                            if let Ok(mut val) = self.retrieve_single_page(val.next) {
                                regs.append(&mut val.collection);
                            }
                        }
                        Ok(regs)
                    },
                    Err(e) => Err(e.to_string())
                }
            },
            Err(e) => Err(e.to_string())
        }
    }
}<commit_msg>fix(Account Actions): fixes a bug where not all actions are displayed<commit_after>use std::marker::PhantomData;
use std::fmt;

use serde::{json, Deserialize};

use response::{self, RawPagedResponse, Pages, NamedResponse};
use request::{BaseRequest, DoRequest};
use request::PagedRequest;

pub struct RequestBuilder<'t, T> {
    pub auth: &'t str,
    pub url: Option<String>,
    pub resp_t: PhantomData<*const T>
}

impl<'t, T> RequestBuilder<'t, T> {
    pub fn with_auth(t: &'t str) -> RequestBuilder<'t, T> {
        RequestBuilder {
            auth: t,
            url: None,
            resp_t: PhantomData
        }
    }
}

impl<'t, T> fmt::Display for RequestBuilder<'t, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "method: GET\n\
                content-type: application/json\n\
                authorization: Bearer {}\n\
                url: {}", self.auth, if self.url.is_some() { self.url.clone().unwrap() } else { "None".to_owned() })
    }
}

impl<'t, T> BaseRequest for RequestBuilder<'t, T> {
    fn auth(&self) -> &str {
        self.auth
    }
    fn url(&self) -> String {
        if let Some(url) = self.url.clone() {
            url
        } else {
            "".to_owned()
        }
    }
}

impl<'t, I> PagedRequest for RequestBuilder<'t, Vec<I>>
                                              // where T: Deserialize + NewIter<Item=I> + NamedResponse,
                                                    where I: Deserialize + NamedResponse {
    type Item = I;
    fn retrieve_single_page(&self, url: String) -> Result<RawPagedResponse<I>, String> {
        let mut rb: RequestBuilder<'t, Vec<I>> = RequestBuilder::with_auth(self.auth);
        rb.url = Some(url);
        match rb.retrieve_json() {
            Ok(ref s) => {
                 // FIXME \/ \/
                let mut name = <I as NamedResponse>::name().into_owned();
                name.push('s');
                let re = regex!(&format!("\"{}\"", name));
                match json::from_str::<response::RawPagedResponse<I>>(&re.replace(&s[..], "\"collection\"")) {
                // FIXME ^^
                    Ok(val) => {
                        Ok(val)
                    },
                    Err(e) => Err(e.to_string())
                }
            },
            Err(e) => Err(e.to_string())
        }
    }
}

impl<'t, I> DoRequest<Vec<I>> for RequestBuilder<'t, Vec<I>>
                                where I: Deserialize + NamedResponse {
    fn retrieve(&self) -> Result<Vec<I>, String> {
        match self.retrieve_json() {
            Ok(ref s) => {
                 // FIXME \/ \/
                let mut name = <I as NamedResponse>::name().into_owned();
                name.push('s');
                let re = regex!(&format!("\"{}\"", name));
                let res = &re.replace(&s[..], "\"collection\"");
                match json::from_str::<response::RawPagedResponse<I>>(res) {
                // FIXME ^^
                    Ok(mut val) => {
                        let mut regs = vec![];
                        regs.append(&mut val.collection);
                        while let Ok(mut val) = self.retrieve_single_page(val.links.pages.clone().unwrap_or(Pages{
                            next: String::new(),
                            last: String::new()
                        }).next.clone()) {
                            regs.append(&mut val.collection);
                        }
                        Ok(regs)
                    },
                    Err(e) => Err(e.to_string())
                }
            },
            Err(e) => Err(e.to_string())
        }
    }
}<|endoftext|>


<commit_before>// Copyright 2012 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.

use attr;
use ast;
use codemap::respan;
use parse::common::SeqSep;
use parse::PResult;
use parse::token::{self, Nonterminal};
use parse::parser::{Parser, TokenType, PathStyle};
use tokenstream::TokenStream;

#[derive(PartialEq, Eq, Debug)]
enum InnerAttributeParsePolicy<'a> {
    Permitted,
    NotPermitted { reason: &'a str },
}

const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &'static str = "an inner attribute is not \
                                                             permitted in this context";

impl<'a> Parser<'a> {
    /// Parse attributes that appear before an item
    pub fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
        let mut attrs: Vec<ast::Attribute> = Vec::new();
        let mut just_parsed_doc_comment = false;
        loop {
            debug!("parse_outer_attributes: self.token={:?}", self.token);
            match self.token {
                token::Pound => {
                    let inner_error_reason = if just_parsed_doc_comment {
                        "an inner attribute is not permitted following an outer doc comment"
                    } else if !attrs.is_empty() {
                        "an inner attribute is not permitted following an outer attribute"
                    } else {
                        DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
                    };
                    let inner_parse_policy =
                        InnerAttributeParsePolicy::NotPermitted { reason: inner_error_reason };
                    attrs.push(self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?);
                    just_parsed_doc_comment = false;
                }
                token::DocComment(s) => {
                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
                    if attr.style != ast::AttrStyle::Outer {
                        let mut err = self.fatal("expected outer doc comment");
                        err.note("inner doc comments like this (starting with \
                                  `//!` or `/*!`) can only appear before items");
                        return Err(err);
                    }
                    attrs.push(attr);
                    self.bump();
                    just_parsed_doc_comment = true;
                }
                _ => break,
            }
        }
        Ok(attrs)
    }

    /// Matches `attribute = # ! [ meta_item ]`
    ///
    /// If permit_inner is true, then a leading `!` indicates an inner
    /// attribute
    pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> {
        debug!("parse_attribute: permit_inner={:?} self.token={:?}",
               permit_inner,
               self.token);
        let inner_parse_policy = if permit_inner {
            InnerAttributeParsePolicy::Permitted
        } else {
            InnerAttributeParsePolicy::NotPermitted
                { reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG }
        };
        self.parse_attribute_with_inner_parse_policy(inner_parse_policy)
    }

    /// The same as `parse_attribute`, except it takes in an `InnerAttributeParsePolicy`
    /// that prescribes how to handle inner attributes.
    fn parse_attribute_with_inner_parse_policy(&mut self,
                                               inner_parse_policy: InnerAttributeParsePolicy)
                                               -> PResult<'a, ast::Attribute> {
        debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
               inner_parse_policy,
               self.token);
        let (span, path, tokens, mut style) = match self.token {
            token::Pound => {
                let lo = self.span;
                self.bump();

                if inner_parse_policy == InnerAttributeParsePolicy::Permitted {
                    self.expected_tokens.push(TokenType::Token(token::Not));
                }
                let style = if self.token == token::Not {
                    self.bump();
                    if let InnerAttributeParsePolicy::NotPermitted { reason } = inner_parse_policy
                    {
                        let span = self.span;
                        self.diagnostic()
                            .struct_span_err(span, reason)
                            .note("inner attributes and doc comments, like `#![no_std]` or \
                                   `//! My crate`, annotate the item enclosing them, and are \
                                   usually found at the beginning of source files. Outer \
                                   attributes and doc comments, like `#[test]` and
                                   `/// My function`, annotate the item following them.")
                            .emit()
                    }
                    ast::AttrStyle::Inner
                } else {
                    ast::AttrStyle::Outer
                };

                self.expect(&token::OpenDelim(token::Bracket))?;
                let (path, tokens) = self.parse_path_and_tokens()?;
                self.expect(&token::CloseDelim(token::Bracket))?;
                let hi = self.prev_span;

                (lo.to(hi), path, tokens, style)
            }
            _ => {
                let token_str = self.this_token_to_string();
                return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
            }
        };

        if inner_parse_policy == InnerAttributeParsePolicy::Permitted &&
           self.token == token::Semi {
            self.bump();
            self.span_warn(span,
                           "this inner attribute syntax is deprecated. The new syntax is \
                            `#![foo]`, with a bang and no semicolon");
            style = ast::AttrStyle::Inner;
        }

        Ok(ast::Attribute {
            id: attr::mk_attr_id(),
            style,
            path,
            tokens,
            is_sugared_doc: false,
            span,
        })
    }

    pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
        let meta = match self.token {
            token::Interpolated(ref nt) => match nt.0 {
                Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
                _ => None,
            },
            _ => None,
        };
        Ok(if let Some(meta) = meta {
            self.bump();
            (ast::Path::from_ident(meta.span, ast::Ident::with_empty_ctxt(meta.name)),
             meta.node.tokens(meta.span))
        } else {
            (self.parse_path(PathStyle::Mod)?, self.parse_tokens())
        })
    }

    /// Parse attributes that appear after the opening of an item. These should
    /// be preceded by an exclamation mark, but we accept and warn about one
    /// terminated by a semicolon.

    /// matches inner_attrs*
    pub fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
        let mut attrs: Vec<ast::Attribute> = vec![];
        loop {
            match self.token {
                token::Pound => {
                    // Don't even try to parse if it's not an inner attribute.
                    if !self.look_ahead(1, |t| t == &token::Not) {
                        break;
                    }

                    let attr = self.parse_attribute(true)?;
                    assert_eq!(attr.style, ast::AttrStyle::Inner);
                    attrs.push(attr);
                }
                token::DocComment(s) => {
                    // we need to get the position of this token before we bump.
                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
                    if attr.style == ast::AttrStyle::Inner {
                        attrs.push(attr);
                        self.bump();
                    } else {
                        break;
                    }
                }
                _ => break,
            }
        }
        Ok(attrs)
    }

    fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> {
        let lit = self.parse_lit()?;
        debug!("Checking if {:?} is unusuffixed.", lit);

        if !lit.node.is_unsuffixed() {
            let msg = "suffixed literals are not allowed in attributes";
            self.diagnostic().struct_span_err(lit.span, msg)
                             .help("instead of using a suffixed literal \
                                    (1u8, 1.0f32, etc.), use an unsuffixed version \
                                    (1, 1.0, etc.).")
                             .emit()
        }

        Ok(lit)
    }

    /// Per RFC#1559, matches the following grammar:
    ///
    /// meta_item : IDENT ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
    /// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
    pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
        let nt_meta = match self.token {
            token::Interpolated(ref nt) => match nt.0 {
                token::NtMeta(ref e) => Some(e.clone()),
                _ => None,
            },
            _ => None,
        };

        if let Some(meta) = nt_meta {
            self.bump();
            return Ok(meta);
        }

        let lo = self.span;
        let ident = self.parse_ident()?;
        let node = self.parse_meta_item_kind()?;
        Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) })
    }

    pub fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
        Ok(if self.eat(&token::Eq) {
            ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
        } else if self.token == token::OpenDelim(token::Paren) {
            ast::MetaItemKind::List(self.parse_meta_seq()?)
        } else {
            self.eat(&token::OpenDelim(token::Paren));
            ast::MetaItemKind::Word
        })
    }

    /// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;
    fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
        let lo = self.span;

        match self.parse_unsuffixed_lit() {
            Ok(lit) => {
                return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::Literal(lit)))
            }
            Err(ref mut err) => self.diagnostic().cancel(err)
        }

        match self.parse_meta_item() {
            Ok(mi) => {
                return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::MetaItem(mi)))
            }
            Err(ref mut err) => self.diagnostic().cancel(err)
        }

        let found = self.this_token_to_string();
        let msg = format!("expected unsuffixed literal or identifier, found {}", found);
        Err(self.diagnostic().struct_span_err(lo, &msg))
    }

    /// matches meta_seq = ( COMMASEP(meta_item_inner) )
    fn parse_meta_seq(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
        self.parse_unspanned_seq(&token::OpenDelim(token::Paren),
                                 &token::CloseDelim(token::Paren),
                                 SeqSep::trailing_allowed(token::Comma),
                                 |p: &mut Parser<'a>| p.parse_meta_item_inner())
    }
}
<commit_msg>Auto merge of #43904 - topecongiro:libsyntax/parse-attr, r=petrochenkov<commit_after>// Copyright 2012 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.

use attr;
use ast;
use codemap::respan;
use parse::common::SeqSep;
use parse::PResult;
use parse::token::{self, Nonterminal};
use parse::parser::{Parser, TokenType, PathStyle};
use tokenstream::TokenStream;

#[derive(PartialEq, Eq, Debug)]
enum InnerAttributeParsePolicy<'a> {
    Permitted,
    NotPermitted { reason: &'a str },
}

const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &'static str = "an inner attribute is not \
                                                             permitted in this context";

impl<'a> Parser<'a> {
    /// Parse attributes that appear before an item
    pub fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
        let mut attrs: Vec<ast::Attribute> = Vec::new();
        let mut just_parsed_doc_comment = false;
        loop {
            debug!("parse_outer_attributes: self.token={:?}", self.token);
            match self.token {
                token::Pound => {
                    let inner_error_reason = if just_parsed_doc_comment {
                        "an inner attribute is not permitted following an outer doc comment"
                    } else if !attrs.is_empty() {
                        "an inner attribute is not permitted following an outer attribute"
                    } else {
                        DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
                    };
                    let inner_parse_policy =
                        InnerAttributeParsePolicy::NotPermitted { reason: inner_error_reason };
                    attrs.push(self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?);
                    just_parsed_doc_comment = false;
                }
                token::DocComment(s) => {
                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
                    if attr.style != ast::AttrStyle::Outer {
                        let mut err = self.fatal("expected outer doc comment");
                        err.note("inner doc comments like this (starting with \
                                  `//!` or `/*!`) can only appear before items");
                        return Err(err);
                    }
                    attrs.push(attr);
                    self.bump();
                    just_parsed_doc_comment = true;
                }
                _ => break,
            }
        }
        Ok(attrs)
    }

    /// Matches `attribute = # ! [ meta_item ]`
    ///
    /// If permit_inner is true, then a leading `!` indicates an inner
    /// attribute
    pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> {
        debug!("parse_attribute: permit_inner={:?} self.token={:?}",
               permit_inner,
               self.token);
        let inner_parse_policy = if permit_inner {
            InnerAttributeParsePolicy::Permitted
        } else {
            InnerAttributeParsePolicy::NotPermitted
                { reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG }
        };
        self.parse_attribute_with_inner_parse_policy(inner_parse_policy)
    }

    /// The same as `parse_attribute`, except it takes in an `InnerAttributeParsePolicy`
    /// that prescribes how to handle inner attributes.
    fn parse_attribute_with_inner_parse_policy(&mut self,
                                               inner_parse_policy: InnerAttributeParsePolicy)
                                               -> PResult<'a, ast::Attribute> {
        debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
               inner_parse_policy,
               self.token);
        let (span, path, tokens, mut style) = match self.token {
            token::Pound => {
                let lo = self.span;
                self.bump();

                if inner_parse_policy == InnerAttributeParsePolicy::Permitted {
                    self.expected_tokens.push(TokenType::Token(token::Not));
                }
                let style = if self.token == token::Not {
                    self.bump();
                    if let InnerAttributeParsePolicy::NotPermitted { reason } = inner_parse_policy
                    {
                        let span = self.span;
                        self.diagnostic()
                            .struct_span_err(span, reason)
                            .note("inner attributes and doc comments, like `#![no_std]` or \
                                   `//! My crate`, annotate the item enclosing them, and are \
                                   usually found at the beginning of source files. Outer \
                                   attributes and doc comments, like `#[test]` and
                                   `/// My function`, annotate the item following them.")
                            .emit()
                    }
                    ast::AttrStyle::Inner
                } else {
                    ast::AttrStyle::Outer
                };

                self.expect(&token::OpenDelim(token::Bracket))?;
                let (path, tokens) = self.parse_path_and_tokens()?;
                self.expect(&token::CloseDelim(token::Bracket))?;
                let hi = self.prev_span;

                (lo.to(hi), path, tokens, style)
            }
            _ => {
                let token_str = self.this_token_to_string();
                return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
            }
        };

        if inner_parse_policy == InnerAttributeParsePolicy::Permitted &&
           self.token == token::Semi {
            self.bump();
            self.span_warn(span,
                           "this inner attribute syntax is deprecated. The new syntax is \
                            `#![foo]`, with a bang and no semicolon");
            style = ast::AttrStyle::Inner;
        }

        Ok(ast::Attribute {
            id: attr::mk_attr_id(),
            style,
            path,
            tokens,
            is_sugared_doc: false,
            span,
        })
    }

    pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
        let meta = match self.token {
            token::Interpolated(ref nt) => match nt.0 {
                Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
                _ => None,
            },
            _ => None,
        };
        Ok(if let Some(meta) = meta {
            self.bump();
            (ast::Path::from_ident(meta.span, ast::Ident::with_empty_ctxt(meta.name)),
             meta.node.tokens(meta.span))
        } else {
            (self.parse_path(PathStyle::Mod)?, self.parse_tokens())
        })
    }

    /// Parse attributes that appear after the opening of an item. These should
    /// be preceded by an exclamation mark, but we accept and warn about one
    /// terminated by a semicolon.

    /// matches inner_attrs*
    pub fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
        let mut attrs: Vec<ast::Attribute> = vec![];
        loop {
            match self.token {
                token::Pound => {
                    // Don't even try to parse if it's not an inner attribute.
                    if !self.look_ahead(1, |t| t == &token::Not) {
                        break;
                    }

                    let attr = self.parse_attribute(true)?;
                    assert_eq!(attr.style, ast::AttrStyle::Inner);
                    attrs.push(attr);
                }
                token::DocComment(s) => {
                    // we need to get the position of this token before we bump.
                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
                    if attr.style == ast::AttrStyle::Inner {
                        attrs.push(attr);
                        self.bump();
                    } else {
                        break;
                    }
                }
                _ => break,
            }
        }
        Ok(attrs)
    }

    fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> {
        let lit = self.parse_lit()?;
        debug!("Checking if {:?} is unusuffixed.", lit);

        if !lit.node.is_unsuffixed() {
            let msg = "suffixed literals are not allowed in attributes";
            self.diagnostic().struct_span_err(lit.span, msg)
                             .help("instead of using a suffixed literal \
                                    (1u8, 1.0f32, etc.), use an unsuffixed version \
                                    (1, 1.0, etc.).")
                             .emit()
        }

        Ok(lit)
    }

    /// Per RFC#1559, matches the following grammar:
    ///
    /// meta_item : IDENT ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
    /// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
    pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
        let nt_meta = match self.token {
            token::Interpolated(ref nt) => match nt.0 {
                token::NtMeta(ref e) => Some(e.clone()),
                _ => None,
            },
            _ => None,
        };

        if let Some(meta) = nt_meta {
            self.bump();
            return Ok(meta);
        }

        let lo = self.span;
        let ident = self.parse_ident()?;
        let node = self.parse_meta_item_kind()?;
        Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) })
    }

    pub fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
        Ok(if self.eat(&token::Eq) {
            ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
        } else if self.eat(&token::OpenDelim(token::Paren)) {
            ast::MetaItemKind::List(self.parse_meta_seq()?)
        } else {
            ast::MetaItemKind::Word
        })
    }

    /// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;
    fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
        let lo = self.span;

        match self.parse_unsuffixed_lit() {
            Ok(lit) => {
                return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::Literal(lit)))
            }
            Err(ref mut err) => self.diagnostic().cancel(err)
        }

        match self.parse_meta_item() {
            Ok(mi) => {
                return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::MetaItem(mi)))
            }
            Err(ref mut err) => self.diagnostic().cancel(err)
        }

        let found = self.this_token_to_string();
        let msg = format!("expected unsuffixed literal or identifier, found {}", found);
        Err(self.diagnostic().struct_span_err(lo, &msg))
    }

    /// matches meta_seq = ( COMMASEP(meta_item_inner) )
    fn parse_meta_seq(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
        self.parse_seq_to_end(&token::CloseDelim(token::Paren),
                              SeqSep::trailing_allowed(token::Comma),
                              |p: &mut Parser<'a>| p.parse_meta_item_inner())
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::BufWriter;
use std::io::BufReader;
use std::env;

extern crate modfile;
use modfile::ptmf;

fn main() {
	let args : Vec<String> = env::args().collect();

	for i in 1..args.len() {
		let ref filename = args[i];
		println!("***** {} *****", filename);

		let file = match File::open(filename) {
			Ok(file) => file,
			Err(..) => panic!("Failed to open file"),
		};

		let mut reader = BufReader::new(&file);
		let mut module = ptmf::read_mod(&mut reader).unwrap();

		println!("Songname: '{}'",module.name);
		for si in &module.sample_info {
			if si.length > 0 {
				println!("Sample name: '{}' length: '{}' repeat start: '{}' repeat length: '{}'", si.name, si.length*2, si.repeat_start*2, si.repeat_length*2);
			}
		}

		let mut filename = filename.clone();
		filename.push_str(".copy");

		let file = match File::create(filename) {
			Ok(file) => file,
			Err(..) => panic!("Failed to open file"),
		};

		let mut writer = BufWriter::new(&file);
		ptmf::write_mod(&mut writer, &mut module).unwrap();

		println!("***** *****")
	}
}
<commit_msg>call with 2 arguments<commit_after>use std::fs::File;
use std::io::BufWriter;
use std::io::BufReader;
use std::env;

extern crate modfile;
use modfile::ptmf;

fn main() {
	let args : Vec<String> = env::args().collect();

	for i in 1..args.len() {
		let ref filename = args[i];
		println!("***** {} *****", filename);

		let file = match File::open(filename) {
			Ok(file) => file,
			Err(..) => panic!("Failed to open file"),
		};

		let mut reader = BufReader::new(&file);
		let mut module = ptmf::read_mod(&mut reader, true).unwrap();

		println!("Songname: '{}'",module.name);
		for si in &module.sample_info {
			if si.length > 0 {
				println!("Sample name: '{}' length: '{}' repeat start: '{}' repeat length: '{}'", si.name, si.length*2, si.repeat_start*2, si.repeat_length*2);
			}
		}

		let mut filename = filename.clone();
		filename.push_str(".copy");

		let file = match File::create(filename) {
			Ok(file) => file,
			Err(..) => panic!("Failed to open file"),
		};

		let mut writer = BufWriter::new(&file);
		ptmf::write_mod(&mut writer, &mut module).unwrap();

		println!("***** *****")
	}
}
<|endoftext|>