<commit_before>#![allow(unused_imports)]
use rustc_serialize::json;

#[test]
fn reply_keyboard_markup() {
    use ReplyKeyboardMarkup as RKM;

    // Test default values
    assert_eq!(RKM::default(), RKM {
        keyboard: Vec::new(),
        resize_keyboard: None,
        one_time_keyboard: None,
        selective: None,
    });

    // Test encoding
    let x = RKM::default();
    assert_eq!(json::encode(&x).unwrap(), "{\"keyboard\":[]}".to_string());

    let x = RKM { resize_keyboard: Some(true), ..Default::default() };
    assert_eq!(json::encode(&x).unwrap(),
        "{\"keyboard\":[],\"resize_keyboard\":true}".to_string());

    let x = RKM {
        keyboard: vec![vec!["ABC".into()], vec!["X".into(), "Y".into()]],
        resize_keyboard: Some(false),
        ..Default::default()
    };
    assert_eq!(json::encode(&x).unwrap(),
        "{\"keyboard\":[[\"ABC\"],[\"X\",\"Y\"]],\"resize_keyboard\":false}".to_string());
}

#[test]
fn keyboard_markup() {
    use ReplyKeyboardMarkup as RKM;
    use ReplyMarkup as RM;

    // Test encoding
    let x = RM::Keyboard(RKM::default());
    assert_eq!(json::encode(&x).unwrap(), "{\"keyboard\":[]}".to_string());

    let x = RM::KeyboardHide(false);
    assert_eq!(json::encode(&x).unwrap(),
        "{\"hide_keyboard\":true,\"selective\":false}".to_string());

    let x = RM::ForceReply(true);
    assert_eq!(json::encode(&x).unwrap(),
        "{\"force_reply\":true,\"selective\":true}".to_string());
}
<commit_msg>types/test: Test decoding of `Chat`<commit_after>#![allow(unused_imports)]
use rustc_serialize::json;

#[test]
fn reply_keyboard_markup() {
    use ReplyKeyboardMarkup as RKM;

    // Test default values
    assert_eq!(RKM::default(), RKM {
        keyboard: Vec::new(),
        resize_keyboard: None,
        one_time_keyboard: None,
        selective: None,
    });

    // Test encoding
    let x = RKM::default();
    assert_eq!(json::encode(&x).unwrap(), "{\"keyboard\":[]}".to_string());

    let x = RKM { resize_keyboard: Some(true), ..Default::default() };
    assert_eq!(json::encode(&x).unwrap(),
        "{\"keyboard\":[],\"resize_keyboard\":true}".to_string());

    let x = RKM {
        keyboard: vec![vec!["ABC".into()], vec!["X".into(), "Y".into()]],
        resize_keyboard: Some(false),
        ..Default::default()
    };
    assert_eq!(json::encode(&x).unwrap(),
        "{\"keyboard\":[[\"ABC\"],[\"X\",\"Y\"]],\"resize_keyboard\":false}".to_string());
}

#[test]
fn keyboard_markup() {
    use ReplyKeyboardMarkup as RKM;
    use ReplyMarkup as RM;

    // Test encoding
    let x = RM::Keyboard(RKM::default());
    assert_eq!(json::encode(&x).unwrap(), "{\"keyboard\":[]}".to_string());

    let x = RM::KeyboardHide(false);
    assert_eq!(json::encode(&x).unwrap(),
        "{\"hide_keyboard\":true,\"selective\":false}".to_string());

    let x = RM::ForceReply(true);
    assert_eq!(json::encode(&x).unwrap(),
        "{\"force_reply\":true,\"selective\":true}".to_string());
}

#[test]
fn decode_group_chat() {
    use Chat;
    use GroupChat;

    let blob = r#"{"title":"This is a group chat","id":-12345678}"#;
    let groupchat: GroupChat = json::decode(&blob).unwrap();
    let chat: Chat = json::decode(&blob).unwrap();

    assert!(chat.is_group());
    assert_eq!(Chat::Group(groupchat), chat);
}

#[test]
fn decode_user_chat() {
    use Chat;
    use User;

    let blob = r#"{"first_name":"test","id":123456789,"username":"test"}"#;
    let chat: Chat = json::decode(&blob).unwrap();
    let user: User = json::decode(&blob).unwrap();

    assert!(chat.is_user());
    assert_eq!(Chat::User(user), chat);
}
<|endoftext|>


<commit_before>//! Helpers for mounting and unmounting.

use crate::errors::*;
use crate::retry;
use nix::mount;
use slog_scope::{debug, warn};
use std::path::Path;
use std::process::Command;

/// Try to unmount an existing target mountpoint.
///
/// This can internally retry in case of transient errors.
pub(crate) fn unmount(target: &Path, retries: u8) -> Result<()> {
    let driver = retry::Retry::new().max_retries(retries);
    driver.retry(|attempt| {
        debug!(
            "Unmounting '{}': attempt #{}",
            target.display(),
            attempt + 1
        );
        mount::umount(target).chain_err(|| format!("failed to unmount '{}'", target.display()))
    })
}

/// Try to mount a filesystem.
///
/// This can internally wait for udev events settling and retry in case of transient errors.
pub(crate) fn mount_ro(source: &Path, target: &Path, fstype: &str, retries: u8) -> Result<()> {
    let driver = retry::Retry::new().max_retries(retries);
    driver.retry(|attempt| {
        debug!("Mounting '{}': attempt #{}", source.display(), attempt + 1);
        let res = mount::mount(
            Some(source),
            target,
            Some(fstype),
            mount::MsFlags::MS_RDONLY,
            None::<&str>,
        )
        .chain_err(|| {
            format!(
                "failed to mount (read-only) source '{}' to target '{}', with type '{}'",
                source.display(),
                target.display(),
                fstype
            )
        });

        // If mounting failed, yield back and give a chance to any
        // pending udev events to be processed.
        if res.is_err() {
            settle_udev(None)
        };

        res
    })
}

/// Wait for udev queue to settle, ignoring any errors.
fn settle_udev(timeout: Option<u8>) {
    let mut cmd = Command::new("udevadm");
    cmd.arg("settle");
    // If none, udevadm default is 120s.
    if let Some(t) = timeout {
        cmd.arg(format!("--timeout={}", t));
    }

    match cmd.output() {
        Err(e) => warn!("failed to run udevadm settle: {}", e),
        Ok(out) => {
            if !out.status.success() {
                warn!(
                    "udevadm settle failed: {}",
                    String::from_utf8_lossy(&out.stderr)
                );
            }
        }
    };
}
<commit_msg>util/mount: log intermediate errors<commit_after>//! Helpers for mounting and unmounting.

use crate::errors::*;
use crate::retry;
use error_chain::ChainedError;
use nix::mount;
use slog_scope::{debug, warn};
use std::path::Path;
use std::process::Command;

/// Try to unmount an existing target mountpoint.
///
/// This can internally retry in case of transient errors.
pub(crate) fn unmount(target: &Path, retries: u8) -> Result<()> {
    let driver = retry::Retry::new().max_retries(retries);
    driver.retry(|attempt| {
        debug!(
            "unmounting '{}': attempt #{}",
            target.display(),
            attempt + 1
        );
        let res =
            mount::umount(target).chain_err(|| format!("failed to unmount '{}'", target.display()));

        if let Err(ref e) = res {
            debug!("{}", e.display_chain());
        };
        res
    })
}

/// Try to mount a filesystem.
///
/// This can internally wait for udev events settling and retry in case of transient errors.
pub(crate) fn mount_ro(source: &Path, target: &Path, fstype: &str, retries: u8) -> Result<()> {
    let driver = retry::Retry::new().max_retries(retries);
    driver.retry(|attempt| {
        debug!("mounting '{}': attempt #{}", source.display(), attempt + 1);
        let res = mount::mount(
            Some(source),
            target,
            Some(fstype),
            mount::MsFlags::MS_RDONLY,
            None::<&str>,
        )
        .chain_err(|| {
            format!(
                "failed to mount (read-only) source '{}' to target '{}', with type '{}'",
                source.display(),
                target.display(),
                fstype
            )
        });

        // If mounting failed, yield back and give a chance to any
        // pending udev events to be processed.
        if let Err(ref e) = res {
            debug!("{}", e.display_chain());
            settle_udev(None)
        };
        res
    })
}

/// Wait for udev queue to settle, ignoring any errors.
fn settle_udev(timeout: Option<u8>) {
    let mut cmd = Command::new("udevadm");
    cmd.arg("settle");
    // If none, udevadm default is 120s.
    if let Some(t) = timeout {
        cmd.arg(format!("--timeout={}", t));
    }

    match cmd.output() {
        Err(e) => warn!("failed to run udevadm settle: {}", e),
        Ok(out) => {
            if !out.status.success() {
                warn!(
                    "udevadm settle failed: {}",
                    String::from_utf8_lossy(&out.stderr)
                );
            }
        }
    };
}
<|endoftext|>


<commit_before>use iron::middleware::Handler;
use router::Router;
use std::collections::HashSet;
use web::{MENU_JS, INDEX_JS};
use iron::Request;

const DOC_RUST_LANG_ORG_REDIRECTS: &[&str] = &["alloc", "core", "proc_macro", "std", "test"];

pub(super) fn build_routes() -> Routes {
    let mut routes = Routes::new();

    routes.static_resource("/style.css", super::style_css_handler);
    routes.static_resource("/index.js", |_: &mut Request| super::load_js(MENU_JS));
    routes.static_resource("/menu.js", |_: &mut Request| super::load_js(INDEX_JS));
    routes.static_resource("/robots.txt", super::sitemap::robots_txt_handler);
    routes.static_resource("/sitemap.xml", super::sitemap::sitemap_handler);
    routes.static_resource("/opensearch.xml", super::opensearch_xml_handler);

    routes.internal_page("/", super::releases::home_page);

    routes.internal_page("/about", super::sitemap::about_handler);
    routes.internal_page("/about/metrics", super::metrics::metrics_handler);

    routes.internal_page("/releases", super::releases::recent_releases_handler);
    routes.static_resource("/releases/feed", super::releases::releases_feed_handler);
    routes.internal_page("/releases/:author", super::releases::author_handler);
    routes.internal_page("/releases/:author/:page", super::releases::author_handler);
    routes.internal_page("/releases/activity", super::releases::activity_handler);
    routes.internal_page("/releases/search", super::releases::search_handler);
    routes.internal_page("/releases/queue", super::releases::build_queue_handler);
    routes.internal_page(
        "/releases/recent/:page",
        super::releases::recent_releases_handler,
    );
    routes.internal_page(
        "/releases/stars",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/stars/:page",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/recent-failures",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/recent-failures/:page",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/failures",
        super::releases::releases_failures_by_stars_handler,
    );
    routes.internal_page(
        "/releases/failures/:page",
        super::releases::releases_failures_by_stars_handler,
    );

    routes.internal_page("/crate/:name", super::crate_details::crate_details_handler);
    routes.internal_page(
        "/crate/:name/:version",
        super::crate_details::crate_details_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds",
        super::builds::build_list_handler,
    );
    routes.static_resource(
        "/crate/:name/:version/builds.json",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds/:id",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source",
        SimpleRedirect::new(|url| url.set_path(&format!("{}/", url.path()))),
    );
    routes.internal_page(
        "/crate/:name/:version/source/",
        super::source::source_browser_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source/*",
        super::source::source_browser_handler,
    );

    routes.rustdoc_page("/:crate", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/badge.svg", super::rustdoc::badge_handler);
    routes.rustdoc_page(
        "/:crate/:version",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/settings.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/all.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/*.html",
        super::rustdoc::rustdoc_html_server_handler,
    );

    for redirect in DOC_RUST_LANG_ORG_REDIRECTS {
        routes.internal_page(
            &format!("/{}", redirect),
            super::rustdoc::RustLangRedirector::new(redirect),
        );
    }

    routes
}

/// This wrapper class aids the construction of iron's Router, with docs.rs-specific additions to
/// it. Routes are supposed to be added by the build_routes function, which calls methods in this
/// struct depending on the type of route being added.
pub(super) struct Routes {
    /// Normal GET routes.
    get: Vec<(String, Box<dyn Handler>)>,
    /// GET routes serving rustdoc content. The BlockBlacklistedPrefixes middleware is added
    /// automatically to all of them.
    rustdoc_get: Vec<(String, Box<dyn Handler>)>,
    /// Prefixes of all the internal routes. This data is used to power the
    /// BlockBlacklistedPrefixes middleware.
    page_prefixes: HashSet<String>,
}

impl Routes {
    fn new() -> Self {
        Self {
            get: Vec::new(),
            rustdoc_get: Vec::new(),
            page_prefixes: HashSet::new(),
        }
    }

    pub(super) fn page_prefixes(&self) -> HashSet<String> {
        self.page_prefixes.clone()
    }

    pub(super) fn iron_router(mut self) -> Router {
        let mut router = Router::new();
        for (pattern, handler) in self.get.drain(..) {
            router.get(&pattern, handler, calculate_id(&pattern));
        }

        // All rustdoc pages have the prefixes of other docs.rs pages blacklisted. This prevents,
        // for example, a crate named "about" from hijacking /about/0.1.0/index.html.
        let blacklist = self.page_prefixes();
        for (pattern, handler) in self.rustdoc_get.drain(..) {
            router.get(
                &pattern,
                BlockBlacklistedPrefixes::new(blacklist.clone(), handler),
                calculate_id(&pattern),
            );
        }

        router
    }

    /// A static resource is a normal page without any special behavior on the router side.
    fn static_resource(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));
    }

    /// Internal pages are docs.rs's own pages, instead of the documentation of a crate uploaded by
    /// an user. The router adds these extra things when adding a new internal page:
    ///
    /// - The first component of the page's URL will be registered as a "page prefix". Page
    /// prefixes are blacklisted by rustdoc pages, to prevent a crate named the same as a prefix
    /// from hijacking docs.rs's own URLs.
    ///
    /// - If the page URL doesn't end with a slash, a redirect from the URL with the trailing slash
    /// to the one without is automatically added.
    fn internal_page(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));

        // Automatically add another route ending with / that redirects to the slash-less route.
        if !pattern.ends_with('/') {
            let pattern = format!("{}/", pattern);
            self.get.push((
                pattern.to_string(),
                Box::new(SimpleRedirect::new(|url| {
                    url.set_path(&url.path().trim_end_matches('/').to_string())
                })),
            ));
        }

        // Register the prefix if it's not the home page and the first path component is not a
        // pattern or a wildcard.
        if pattern != "/" {
            if let Some(first_component) = pattern.trim_matches('/').split('/').next() {
                if !first_component.contains('*') && !first_component.starts_with(':') {
                    self.page_prefixes.insert(first_component.to_string());
                }
            }
        }
    }

    /// A rustdoc page is a page serving generated documentation. It's similar to a static
    /// resource, but path prefixes are automatically blacklisted (see internal pages to learn more
    /// about page prefixes).
    fn rustdoc_page(&mut self, pattern: &str, handler: impl Handler) {
        self.rustdoc_get
            .push((pattern.to_string(), Box::new(handler)));
    }
}

#[derive(Copy, Clone)]
struct SimpleRedirect {
    url_mangler: fn(&mut iron::url::Url),
}

impl SimpleRedirect {
    fn new(url_mangler: fn(&mut iron::url::Url)) -> Self {
        Self { url_mangler }
    }
}

impl Handler for SimpleRedirect {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        let mut url: iron::url::Url = req.url.clone().into();
        (self.url_mangler)(&mut url);
        Ok(iron::Response::with((
            iron::status::Found,
            iron::modifiers::Redirect(iron::Url::parse(&url.to_string()).unwrap()),
        )))
    }
}

/// Iron Middleware that prevents requests to blacklisted prefixes.
///
/// In our application, a prefix is blacklisted if a docs.rs page exists below it. For example,
/// since /releases/queue is a docs.rs page, /releases is a blacklisted prefix.
///
/// The middleware must be used for all the pages serving crates at the top level, to prevent a
/// crate from putting their own content in an URL that's supposed to be used by docs.rs.
pub(super) struct BlockBlacklistedPrefixes {
    blacklist: HashSet<String>,
    handler: Box<dyn Handler>,
}

impl BlockBlacklistedPrefixes {
    pub(super) fn new(blacklist: HashSet<String>, handler: Box<dyn Handler>) -> Self {
        Self { blacklist, handler }
    }
}

impl Handler for BlockBlacklistedPrefixes {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        if let Some(prefix) = req.url.path().get(0) {
            if self.blacklist.contains(*prefix) {
                return Err(iron::IronError::new(
                    super::error::Nope::CrateNotFound,
                    iron::status::NotFound,
                ));
            }
        }
        self.handler.handle(req)
    }
}

/// Automatically generate a Route ID from a pattern. Every non-alphanumeric character is replaced
/// with `_`.
fn calculate_id(pattern: &str) -> String {
    pattern
        .chars()
        .map(|c| if c.is_alphanumeric() { c } else { '_' })
        .collect()
}
<commit_msg>Fix swapped loading lines<commit_after>use iron::middleware::Handler;
use router::Router;
use std::collections::HashSet;
use web::{MENU_JS, INDEX_JS};
use iron::Request;

const DOC_RUST_LANG_ORG_REDIRECTS: &[&str] = &["alloc", "core", "proc_macro", "std", "test"];

pub(super) fn build_routes() -> Routes {
    let mut routes = Routes::new();

    routes.static_resource("/style.css", super::style_css_handler);
    routes.static_resource("/index.js", |_: &mut Request| super::load_js(IDEX_JS));
    routes.static_resource("/menu.js", |_: &mut Request| super::load_js(MENU_JS));
    routes.static_resource("/robots.txt", super::sitemap::robots_txt_handler);
    routes.static_resource("/sitemap.xml", super::sitemap::sitemap_handler);
    routes.static_resource("/opensearch.xml", super::opensearch_xml_handler);

    routes.internal_page("/", super::releases::home_page);

    routes.internal_page("/about", super::sitemap::about_handler);
    routes.internal_page("/about/metrics", super::metrics::metrics_handler);

    routes.internal_page("/releases", super::releases::recent_releases_handler);
    routes.static_resource("/releases/feed", super::releases::releases_feed_handler);
    routes.internal_page("/releases/:author", super::releases::author_handler);
    routes.internal_page("/releases/:author/:page", super::releases::author_handler);
    routes.internal_page("/releases/activity", super::releases::activity_handler);
    routes.internal_page("/releases/search", super::releases::search_handler);
    routes.internal_page("/releases/queue", super::releases::build_queue_handler);
    routes.internal_page(
        "/releases/recent/:page",
        super::releases::recent_releases_handler,
    );
    routes.internal_page(
        "/releases/stars",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/stars/:page",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/recent-failures",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/recent-failures/:page",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/failures",
        super::releases::releases_failures_by_stars_handler,
    );
    routes.internal_page(
        "/releases/failures/:page",
        super::releases::releases_failures_by_stars_handler,
    );

    routes.internal_page("/crate/:name", super::crate_details::crate_details_handler);
    routes.internal_page(
        "/crate/:name/:version",
        super::crate_details::crate_details_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds",
        super::builds::build_list_handler,
    );
    routes.static_resource(
        "/crate/:name/:version/builds.json",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds/:id",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source",
        SimpleRedirect::new(|url| url.set_path(&format!("{}/", url.path()))),
    );
    routes.internal_page(
        "/crate/:name/:version/source/",
        super::source::source_browser_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source/*",
        super::source::source_browser_handler,
    );

    routes.rustdoc_page("/:crate", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/badge.svg", super::rustdoc::badge_handler);
    routes.rustdoc_page(
        "/:crate/:version",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/settings.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/all.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/*.html",
        super::rustdoc::rustdoc_html_server_handler,
    );

    for redirect in DOC_RUST_LANG_ORG_REDIRECTS {
        routes.internal_page(
            &format!("/{}", redirect),
            super::rustdoc::RustLangRedirector::new(redirect),
        );
    }

    routes
}

/// This wrapper class aids the construction of iron's Router, with docs.rs-specific additions to
/// it. Routes are supposed to be added by the build_routes function, which calls methods in this
/// struct depending on the type of route being added.
pub(super) struct Routes {
    /// Normal GET routes.
    get: Vec<(String, Box<dyn Handler>)>,
    /// GET routes serving rustdoc content. The BlockBlacklistedPrefixes middleware is added
    /// automatically to all of them.
    rustdoc_get: Vec<(String, Box<dyn Handler>)>,
    /// Prefixes of all the internal routes. This data is used to power the
    /// BlockBlacklistedPrefixes middleware.
    page_prefixes: HashSet<String>,
}

impl Routes {
    fn new() -> Self {
        Self {
            get: Vec::new(),
            rustdoc_get: Vec::new(),
            page_prefixes: HashSet::new(),
        }
    }

    pub(super) fn page_prefixes(&self) -> HashSet<String> {
        self.page_prefixes.clone()
    }

    pub(super) fn iron_router(mut self) -> Router {
        let mut router = Router::new();
        for (pattern, handler) in self.get.drain(..) {
            router.get(&pattern, handler, calculate_id(&pattern));
        }

        // All rustdoc pages have the prefixes of other docs.rs pages blacklisted. This prevents,
        // for example, a crate named "about" from hijacking /about/0.1.0/index.html.
        let blacklist = self.page_prefixes();
        for (pattern, handler) in self.rustdoc_get.drain(..) {
            router.get(
                &pattern,
                BlockBlacklistedPrefixes::new(blacklist.clone(), handler),
                calculate_id(&pattern),
            );
        }

        router
    }

    /// A static resource is a normal page without any special behavior on the router side.
    fn static_resource(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));
    }

    /// Internal pages are docs.rs's own pages, instead of the documentation of a crate uploaded by
    /// an user. The router adds these extra things when adding a new internal page:
    ///
    /// - The first component of the page's URL will be registered as a "page prefix". Page
    /// prefixes are blacklisted by rustdoc pages, to prevent a crate named the same as a prefix
    /// from hijacking docs.rs's own URLs.
    ///
    /// - If the page URL doesn't end with a slash, a redirect from the URL with the trailing slash
    /// to the one without is automatically added.
    fn internal_page(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));

        // Automatically add another route ending with / that redirects to the slash-less route.
        if !pattern.ends_with('/') {
            let pattern = format!("{}/", pattern);
            self.get.push((
                pattern.to_string(),
                Box::new(SimpleRedirect::new(|url| {
                    url.set_path(&url.path().trim_end_matches('/').to_string())
                })),
            ));
        }

        // Register the prefix if it's not the home page and the first path component is not a
        // pattern or a wildcard.
        if pattern != "/" {
            if let Some(first_component) = pattern.trim_matches('/').split('/').next() {
                if !first_component.contains('*') && !first_component.starts_with(':') {
                    self.page_prefixes.insert(first_component.to_string());
                }
            }
        }
    }

    /// A rustdoc page is a page serving generated documentation. It's similar to a static
    /// resource, but path prefixes are automatically blacklisted (see internal pages to learn more
    /// about page prefixes).
    fn rustdoc_page(&mut self, pattern: &str, handler: impl Handler) {
        self.rustdoc_get
            .push((pattern.to_string(), Box::new(handler)));
    }
}

#[derive(Copy, Clone)]
struct SimpleRedirect {
    url_mangler: fn(&mut iron::url::Url),
}

impl SimpleRedirect {
    fn new(url_mangler: fn(&mut iron::url::Url)) -> Self {
        Self { url_mangler }
    }
}

impl Handler for SimpleRedirect {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        let mut url: iron::url::Url = req.url.clone().into();
        (self.url_mangler)(&mut url);
        Ok(iron::Response::with((
            iron::status::Found,
            iron::modifiers::Redirect(iron::Url::parse(&url.to_string()).unwrap()),
        )))
    }
}

/// Iron Middleware that prevents requests to blacklisted prefixes.
///
/// In our application, a prefix is blacklisted if a docs.rs page exists below it. For example,
/// since /releases/queue is a docs.rs page, /releases is a blacklisted prefix.
///
/// The middleware must be used for all the pages serving crates at the top level, to prevent a
/// crate from putting their own content in an URL that's supposed to be used by docs.rs.
pub(super) struct BlockBlacklistedPrefixes {
    blacklist: HashSet<String>,
    handler: Box<dyn Handler>,
}

impl BlockBlacklistedPrefixes {
    pub(super) fn new(blacklist: HashSet<String>, handler: Box<dyn Handler>) -> Self {
        Self { blacklist, handler }
    }
}

impl Handler for BlockBlacklistedPrefixes {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        if let Some(prefix) = req.url.path().get(0) {
            if self.blacklist.contains(*prefix) {
                return Err(iron::IronError::new(
                    super::error::Nope::CrateNotFound,
                    iron::status::NotFound,
                ));
            }
        }
        self.handler.handle(req)
    }
}

/// Automatically generate a Route ID from a pattern. Every non-alphanumeric character is replaced
/// with `_`.
fn calculate_id(pattern: &str) -> String {
    pattern
        .chars()
        .map(|c| if c.is_alphanumeric() { c } else { '_' })
        .collect()
}
<|endoftext|>


<commit_before>fn complex_number_multiply<'a>(x: &'a str, y: &'a str) -> String {}

fn main() {}
<commit_msg>a bit<commit_after>fn complex_number_multiply<'a>(x: &'a str, y: &'a str) -> String {
    let mut x_temp: Vec<&str> = x.split('+').collect();
    let mut y_temp: Vec<&str> = y.split('+').collect();

    println!("{:?}", x_temp);
    println!("{:?}", y_temp);
    println!("{:?}", y_temp[1].as_bytes()[1]);

    let ins = x_temp[0].parse::<u32>().unwrap() * y_temp[0].parse::<u32>().unwrap();
    //let com = y_temp
    println!("{:?}", ins);

    return String::from("aa");
}

fn main() {
    complex_number_multiply("2+1i", "3+1i");
}
<|endoftext|>


<commit_before>//! Generated code support for enum descriptors.

use std::any::TypeId;

use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::FileDescriptorProto;
use crate::reflect::enums::index::EnumIndex;
use crate::reflect::find_message_or_enum::find_message_or_enum;
use crate::reflect::find_message_or_enum::MessageOrEnum;
use crate::reflect::name::compute_full_name;
use crate::EnumFull;
use crate::EnumOrUnknown;

#[doc(hidden)]
pub struct GeneratedEnumDescriptorData {
    name_in_file: &'static str,
    type_id: TypeId,
    enum_or_unknown_type_id: TypeId,
    index_in_file: usize,
}

impl GeneratedEnumDescriptorData {
    #[doc(hidden)]
    pub fn new_2<E>(name_in_file: &'static str, index_in_file: usize) -> GeneratedEnumDescriptorData
    where
        E: EnumFull,
    {
        GeneratedEnumDescriptorData {
            index_in_file,
            name_in_file,
            type_id: TypeId::of::<E>(),
            enum_or_unknown_type_id: TypeId::of::<EnumOrUnknown<E>>(),
        }
    }
}

#[derive(Debug)]
pub(crate) struct GeneratedEnumDescriptor {
    pub(crate) full_name: String,
    pub(crate) proto: &'static EnumDescriptorProto,
    /// Type id of `<E>`
    pub(crate) type_id: TypeId,
    /// Type id of `<ProtobufEnumOrUnknown<E>>`
    pub(crate) _enum_or_unknown_type_id: TypeId,

    pub indices: EnumIndex<&'static str>,
}

impl GeneratedEnumDescriptor {
    pub fn new(
        data: GeneratedEnumDescriptorData,
        expected_index: usize,
        file_descriptor_proto: &'static FileDescriptorProto,
    ) -> GeneratedEnumDescriptor {
        let GeneratedEnumDescriptorData {
            name_in_file,
            type_id,
            enum_or_unknown_type_id,
            index_in_file,
        } = data;

        assert!(expected_index == index_in_file);

        let (path_to_package, proto) =
            match find_message_or_enum(file_descriptor_proto, name_in_file).unwrap() {
                (path_to_package, MessageOrEnum::Enum(e)) => (path_to_package, e),
                (_, MessageOrEnum::Message(_)) => panic!("not an enum"),
            };

        let indices = EnumIndex::<&'static str>::index::<&'static str>(proto);

        GeneratedEnumDescriptor {
            full_name: compute_full_name(
                file_descriptor_proto.package(),
                &path_to_package,
                proto.name(),
            ),
            proto,
            type_id,
            _enum_or_unknown_type_id: enum_or_unknown_type_id,
            indices,
        }
    }
}
<commit_msg>Code cleanup<commit_after>//! Generated code support for enum descriptors.

use std::any::TypeId;

use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::FileDescriptorProto;
use crate::reflect::enums::index::EnumIndex;
use crate::reflect::find_message_or_enum::find_message_or_enum;
use crate::reflect::find_message_or_enum::MessageOrEnum;
use crate::reflect::name::compute_full_name;
use crate::EnumFull;
use crate::EnumOrUnknown;

#[doc(hidden)]
pub struct GeneratedEnumDescriptorData {
    name_in_file: &'static str,
    type_id: TypeId,
    enum_or_unknown_type_id: TypeId,
    index_in_file: usize,
}

impl GeneratedEnumDescriptorData {
    #[doc(hidden)]
    pub fn new_2<E>(name_in_file: &'static str, index_in_file: usize) -> GeneratedEnumDescriptorData
    where
        E: EnumFull,
    {
        GeneratedEnumDescriptorData {
            index_in_file,
            name_in_file,
            type_id: TypeId::of::<E>(),
            enum_or_unknown_type_id: TypeId::of::<EnumOrUnknown<E>>(),
        }
    }
}

#[derive(Debug)]
pub(crate) struct GeneratedEnumDescriptor {
    pub(crate) full_name: String,
    pub(crate) proto: &'static EnumDescriptorProto,
    /// Type id of `<E>`
    pub(crate) type_id: TypeId,
    /// Type id of `<ProtobufEnumOrUnknown<E>>`
    pub(crate) _enum_or_unknown_type_id: TypeId,

    pub(crate) indices: EnumIndex<&'static str>,
}

impl GeneratedEnumDescriptor {
    pub fn new(
        data: GeneratedEnumDescriptorData,
        expected_index: usize,
        file_descriptor_proto: &'static FileDescriptorProto,
    ) -> GeneratedEnumDescriptor {
        let GeneratedEnumDescriptorData {
            name_in_file,
            type_id,
            enum_or_unknown_type_id,
            index_in_file,
        } = data;

        assert!(expected_index == index_in_file);

        let (path_to_package, proto) =
            match find_message_or_enum(file_descriptor_proto, name_in_file).unwrap() {
                (path_to_package, MessageOrEnum::Enum(e)) => (path_to_package, e),
                (_, MessageOrEnum::Message(_)) => panic!("not an enum"),
            };

        let indices = EnumIndex::<&'static str>::index::<&'static str>(proto);

        GeneratedEnumDescriptor {
            full_name: compute_full_name(
                file_descriptor_proto.package(),
                &path_to_package,
                proto.name(),
            ),
            proto,
            type_id,
            _enum_or_unknown_type_id: enum_or_unknown_type_id,
            indices,
        }
    }
}
<|endoftext|>


<commit_before>//! Helper module to enable serializing bytes more efficiently

use core::{ops, fmt, char, iter, slice};
use core::fmt::Write;

use ser;

#[cfg(any(feature = "std", feature = "collections"))]
pub use self::bytebuf::{ByteBuf, ByteBufVisitor};

#[cfg(feature = "collections")]
use collections::Vec;

///////////////////////////////////////////////////////////////////////////////

/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
    bytes: &'a [u8],
}

impl<'a> Bytes<'a> {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &'a [u8]) -> Self {
        Bytes {
            bytes: bytes,
        }
    }
}

impl<'a> fmt::Debug for Bytes<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(f.write_str("b\""));
        for c in escape_bytestring(self.bytes) {
            try!(f.write_char(c));
        }
        f.write_char('"')
    }
}

impl<'a> From<&'a [u8]> for Bytes<'a> {
    fn from(bytes: &'a [u8]) -> Self {
        Bytes::new(bytes)
    }
}

#[cfg(any(feature = "std", feature = "collections"))]
impl<'a> From<&'a Vec<u8>> for Bytes<'a> {
    fn from(bytes: &'a Vec<u8>) -> Self {
        Bytes::new(bytes)
    }
}

impl<'a> Into<&'a [u8]> for Bytes<'a> {
    fn into(self) -> &'a [u8] {
        self.bytes
    }
}

impl<'a> ops::Deref for Bytes<'a> {
    type Target = [u8];

    fn deref(&self) -> &[u8] { self.bytes }
}

impl<'a> ser::Serialize for Bytes<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: ser::Serializer
    {
        serializer.serialize_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "collections"))]
mod bytebuf {
    use core::ops;
    use core::fmt;
    use core::fmt::Write;

    use ser;
    use de;

    #[cfg(feature = "collections")]
    use collections::Vec;

    /// `ByteBuf` wraps a `Vec<u8>` and serializes as a byte array.
    #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
    pub struct ByteBuf {
        bytes: Vec<u8>,
    }

    impl ByteBuf {
        /// Construct a new, empty `ByteBuf`.
        pub fn new() -> Self {
            ByteBuf::from(Vec::new())
        }

        /// Construct a new, empty `ByteBuf` with the specified capacity.
        pub fn with_capacity(cap: usize) -> Self {
            ByteBuf::from(Vec::with_capacity(cap))
        }

        /// Wrap existing bytes in a `ByteBuf`.
        pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
            ByteBuf {
                bytes: bytes.into(),
            }
        }
    }

    impl fmt::Debug for ByteBuf {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            try!(f.write_str("b\""));
            for c in super::escape_bytestring(self.bytes.as_ref()) {
                try!(f.write_char(c));
            }
            f.write_char('"')
        }
    }

    impl Into<Vec<u8>> for ByteBuf {
        fn into(self) -> Vec<u8> {
            self.bytes
        }
    }

    impl From<Vec<u8>> for ByteBuf {
        fn from(bytes: Vec<u8>) -> Self {
            ByteBuf::from(bytes)
        }
    }

    impl AsRef<Vec<u8>> for ByteBuf {
        fn as_ref(&self) -> &Vec<u8> {
            &self.bytes
        }
    }

    impl AsRef<[u8]> for ByteBuf {
        fn as_ref(&self) -> &[u8] {
            &self.bytes
        }
    }

    impl AsMut<Vec<u8>> for ByteBuf {
        fn as_mut(&mut self) -> &mut Vec<u8> {
            &mut self.bytes
        }
    }

    impl AsMut<[u8]> for ByteBuf {
        fn as_mut(&mut self) -> &mut [u8] {
            &mut self.bytes
        }
    }

    impl ops::Deref for ByteBuf {
        type Target = [u8];

        fn deref(&self) -> &[u8] { &self.bytes[..] }
    }

    impl ops::DerefMut for ByteBuf {
        fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes[..] }
    }

    impl ser::Serialize for ByteBuf {
        fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
            where S: ser::Serializer
        {
            serializer.serialize_bytes(self)
        }
    }

    /// This type implements the `serde::de::Visitor` trait for a `ByteBuf`.
    pub struct ByteBufVisitor;

    impl de::Visitor for ByteBufVisitor {
        type Value = ByteBuf;

        #[inline]
        fn visit_unit<E>(&mut self) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::new())
        }

        #[inline]
        fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ByteBuf, V::Error>
            where V: de::SeqVisitor,
        {
            let (len, _) = visitor.size_hint();
            let mut values = Vec::with_capacity(len);

            while let Some(value) = try!(visitor.visit()) {
                values.push(value);
            }

            try!(visitor.end());

            Ok(ByteBuf::from(values))
        }

        #[inline]
        fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }

        fn visit_str<E>(&mut self, v: &str) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }

        fn visit_string<E>(&mut self, v: String) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }
    }

    impl de::Deserialize for ByteBuf {
        #[inline]
        fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error>
            where D: de::Deserializer
        {
            deserializer.deserialize_bytes(ByteBufVisitor)
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

#[inline]
fn escape_bytestring<'a>(bytes: &'a [u8]) -> iter::FlatMap<slice::Iter<'a, u8>, char::EscapeDefault, fn(&u8) -> char::EscapeDefault> {
    fn f(b: &u8) -> char::EscapeDefault {
        char::from_u32(*b as u32).unwrap().escape_default()
    }
    bytes.iter().flat_map(f as fn(&u8) -> char::EscapeDefault)
}
<commit_msg>Support nostd for ByteBuf from String<commit_after>//! Helper module to enable serializing bytes more efficiently

use core::{ops, fmt, char, iter, slice};
use core::fmt::Write;

use ser;

#[cfg(any(feature = "std", feature = "collections"))]
pub use self::bytebuf::{ByteBuf, ByteBufVisitor};

#[cfg(feature = "collections")]
use collections::Vec;

///////////////////////////////////////////////////////////////////////////////

/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
    bytes: &'a [u8],
}

impl<'a> Bytes<'a> {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &'a [u8]) -> Self {
        Bytes {
            bytes: bytes,
        }
    }
}

impl<'a> fmt::Debug for Bytes<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(f.write_str("b\""));
        for c in escape_bytestring(self.bytes) {
            try!(f.write_char(c));
        }
        f.write_char('"')
    }
}

impl<'a> From<&'a [u8]> for Bytes<'a> {
    fn from(bytes: &'a [u8]) -> Self {
        Bytes::new(bytes)
    }
}

#[cfg(any(feature = "std", feature = "collections"))]
impl<'a> From<&'a Vec<u8>> for Bytes<'a> {
    fn from(bytes: &'a Vec<u8>) -> Self {
        Bytes::new(bytes)
    }
}

impl<'a> Into<&'a [u8]> for Bytes<'a> {
    fn into(self) -> &'a [u8] {
        self.bytes
    }
}

impl<'a> ops::Deref for Bytes<'a> {
    type Target = [u8];

    fn deref(&self) -> &[u8] { self.bytes }
}

impl<'a> ser::Serialize for Bytes<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: ser::Serializer
    {
        serializer.serialize_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "collections"))]
mod bytebuf {
    use core::ops;
    use core::fmt;
    use core::fmt::Write;

    use ser;
    use de;

    #[cfg(feature = "collections")]
    use collections::{String, Vec};

    /// `ByteBuf` wraps a `Vec<u8>` and serializes as a byte array.
    #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
    pub struct ByteBuf {
        bytes: Vec<u8>,
    }

    impl ByteBuf {
        /// Construct a new, empty `ByteBuf`.
        pub fn new() -> Self {
            ByteBuf::from(Vec::new())
        }

        /// Construct a new, empty `ByteBuf` with the specified capacity.
        pub fn with_capacity(cap: usize) -> Self {
            ByteBuf::from(Vec::with_capacity(cap))
        }

        /// Wrap existing bytes in a `ByteBuf`.
        pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
            ByteBuf {
                bytes: bytes.into(),
            }
        }
    }

    impl fmt::Debug for ByteBuf {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            try!(f.write_str("b\""));
            for c in super::escape_bytestring(self.bytes.as_ref()) {
                try!(f.write_char(c));
            }
            f.write_char('"')
        }
    }

    impl Into<Vec<u8>> for ByteBuf {
        fn into(self) -> Vec<u8> {
            self.bytes
        }
    }

    impl From<Vec<u8>> for ByteBuf {
        fn from(bytes: Vec<u8>) -> Self {
            ByteBuf::from(bytes)
        }
    }

    impl AsRef<Vec<u8>> for ByteBuf {
        fn as_ref(&self) -> &Vec<u8> {
            &self.bytes
        }
    }

    impl AsRef<[u8]> for ByteBuf {
        fn as_ref(&self) -> &[u8] {
            &self.bytes
        }
    }

    impl AsMut<Vec<u8>> for ByteBuf {
        fn as_mut(&mut self) -> &mut Vec<u8> {
            &mut self.bytes
        }
    }

    impl AsMut<[u8]> for ByteBuf {
        fn as_mut(&mut self) -> &mut [u8] {
            &mut self.bytes
        }
    }

    impl ops::Deref for ByteBuf {
        type Target = [u8];

        fn deref(&self) -> &[u8] { &self.bytes[..] }
    }

    impl ops::DerefMut for ByteBuf {
        fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes[..] }
    }

    impl ser::Serialize for ByteBuf {
        fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
            where S: ser::Serializer
        {
            serializer.serialize_bytes(self)
        }
    }

    /// This type implements the `serde::de::Visitor` trait for a `ByteBuf`.
    pub struct ByteBufVisitor;

    impl de::Visitor for ByteBufVisitor {
        type Value = ByteBuf;

        #[inline]
        fn visit_unit<E>(&mut self) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::new())
        }

        #[inline]
        fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ByteBuf, V::Error>
            where V: de::SeqVisitor,
        {
            let (len, _) = visitor.size_hint();
            let mut values = Vec::with_capacity(len);

            while let Some(value) = try!(visitor.visit()) {
                values.push(value);
            }

            try!(visitor.end());

            Ok(ByteBuf::from(values))
        }

        #[inline]
        fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }

        fn visit_str<E>(&mut self, v: &str) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }

        fn visit_string<E>(&mut self, v: String) -> Result<ByteBuf, E>
            where E: de::Error,
        {
            Ok(ByteBuf::from(v))
        }
    }

    impl de::Deserialize for ByteBuf {
        #[inline]
        fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error>
            where D: de::Deserializer
        {
            deserializer.deserialize_bytes(ByteBufVisitor)
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

#[inline]
fn escape_bytestring<'a>(bytes: &'a [u8]) -> iter::FlatMap<slice::Iter<'a, u8>, char::EscapeDefault, fn(&u8) -> char::EscapeDefault> {
    fn f(b: &u8) -> char::EscapeDefault {
        char::from_u32(*b as u32).unwrap().escape_default()
    }
    bytes.iter().flat_map(f as fn(&u8) -> char::EscapeDefault)
}
<|endoftext|>


<commit_before>use std::fs;
use std::str;

use libc::consts::os::posix88;

use nix::sys::stat::{stat, fstat, lstat};

use nix::fcntl::open;
use nix::unistd::{close, unlink};
use nix::fcntl::{O_CREAT, O_RDONLY};
use nix::sys::stat::{FileStat, S_IWUSR, S_IRUSR};
use nix::Result;

fn assert_stat_results(stat_result: Result<FileStat>) {
    match stat_result {
        Ok(stats) => {
            assert!(stats.st_dev > 0);      // must be positive integer, exact number machine dependent
            assert!(stats.st_ino > 0);      // inode is positive integer, exact number machine dependent
            assert!(stats.st_mode > 0);     // must be positive integer
            assert!(stats.st_nlink == 1);   // there links created, must be 1
            assert!(stats.st_uid > 0);      // must be positive integer
            assert!(stats.st_gid > 0);      // must be positive integer
            assert!(stats.st_rdev == 0);    // no special device
            assert!(stats.st_size == 0);    // size is 0 because we did not write anything to the file
            assert!(stats.st_blksize > 0);  // must be positive integer, exact number machine dependent
            assert!(stats.st_blocks >= 16);  // Up to 16 blocks can be allocated for a blank file
        }
        Err(_) => panic!("stat call failed") // if stats system call fails, something is seriously wrong on that machine
    }
}

fn assert_lstat_results(stat_result: Result<FileStat>) {
    match stat_result {
        Ok(stats) => {
            assert!(stats.st_dev > 0);      // must be positive integer, exact number machine dependent
            assert!(stats.st_ino > 0);      // inode is positive integer, exact number machine dependent
            assert!(stats.st_mode > 0);     // must be positive integer
            assert!(stats.st_mode & posix88::S_IFMT
                    == posix88::S_IFLNK); // should be a link
            assert!(stats.st_nlink == 1);   // there links created, must be 1
            assert!(stats.st_uid > 0);      // must be positive integer
            assert!(stats.st_gid > 0);      // must be positive integer
            assert!(stats.st_rdev == 0);    // no special device
            assert!(stats.st_size > 0);    // size is > 0 because it points to another file
            assert!(stats.st_blksize > 0);  // must be positive integer, exact number machine dependent

            // st_blocks depends on whether the machine's file system uses fast
            // or slow symlinks, so just make sure it's not negative
            assert!(stats.st_blocks >= 0);
        }
        Err(_) => panic!("stat call failed") // if stats system call fails, something is seriously wrong on that machine
    }
}

#[test]
fn test_stat_and_fstat() {
    let filename = b"target/foo.txt".as_ref();
    let fd = open(filename, O_CREAT, S_IWUSR).unwrap();  // create empty file

    let stat_result = stat(filename);
    assert_stat_results(stat_result);

    let fstat_result = fstat(fd);
    assert_stat_results(fstat_result);

    close(fd).unwrap();
    unlink(filename).unwrap();
}

#[test]
fn test_stat_fstat_lstat() {
    let filename = b"target/bar.txt".as_ref();
    let linkname = b"target/barlink".as_ref();

    open(filename, O_CREAT, S_IWUSR | S_IRUSR).unwrap();  // create empty file
    fs::soft_link("bar.txt", str::from_utf8(linkname).unwrap()).unwrap();
    let fd = open(linkname, O_RDONLY, S_IRUSR).unwrap();

    // should be the same result as calling stat,
    // since it's a regular file
    let stat_result = lstat(filename);
    assert_stat_results(stat_result);

    let lstat_result = lstat(linkname);
    assert_lstat_results(lstat_result);

    let fstat_result = fstat(fd);
    assert_stat_results(fstat_result);

    close(fd).unwrap();
    unlink(linkname).unwrap();
    unlink(filename).unwrap();
}
<commit_msg>Fix comparison<commit_after>use std::fs;
use std::str;

use libc::consts::os::posix88;

use nix::sys::stat::{stat, fstat, lstat};

use nix::fcntl::open;
use nix::unistd::{close, unlink};
use nix::fcntl::{O_CREAT, O_RDONLY};
use nix::sys::stat::{FileStat, S_IWUSR, S_IRUSR};
use nix::Result;

fn assert_stat_results(stat_result: Result<FileStat>) {
    match stat_result {
        Ok(stats) => {
            assert!(stats.st_dev > 0);      // must be positive integer, exact number machine dependent
            assert!(stats.st_ino > 0);      // inode is positive integer, exact number machine dependent
            assert!(stats.st_mode > 0);     // must be positive integer
            assert!(stats.st_nlink == 1);   // there links created, must be 1
            assert!(stats.st_uid > 0);      // must be positive integer
            assert!(stats.st_gid > 0);      // must be positive integer
            assert!(stats.st_rdev == 0);    // no special device
            assert!(stats.st_size == 0);    // size is 0 because we did not write anything to the file
            assert!(stats.st_blksize > 0);  // must be positive integer, exact number machine dependent
            assert!(stats.st_blocks <= 16);  // Up to 16 blocks can be allocated for a blank file
        }
        Err(_) => panic!("stat call failed") // if stats system call fails, something is seriously wrong on that machine
    }
}

fn assert_lstat_results(stat_result: Result<FileStat>) {
    match stat_result {
        Ok(stats) => {
            assert!(stats.st_dev > 0);      // must be positive integer, exact number machine dependent
            assert!(stats.st_ino > 0);      // inode is positive integer, exact number machine dependent
            assert!(stats.st_mode > 0);     // must be positive integer
            assert!(stats.st_mode & posix88::S_IFMT
                    == posix88::S_IFLNK); // should be a link
            assert!(stats.st_nlink == 1);   // there links created, must be 1
            assert!(stats.st_uid > 0);      // must be positive integer
            assert!(stats.st_gid > 0);      // must be positive integer
            assert!(stats.st_rdev == 0);    // no special device
            assert!(stats.st_size > 0);    // size is > 0 because it points to another file
            assert!(stats.st_blksize > 0);  // must be positive integer, exact number machine dependent

            // st_blocks depends on whether the machine's file system uses fast
            // or slow symlinks, so just make sure it's not negative
            assert!(stats.st_blocks >= 0);
        }
        Err(_) => panic!("stat call failed") // if stats system call fails, something is seriously wrong on that machine
    }
}

#[test]
fn test_stat_and_fstat() {
    let filename = b"target/foo.txt".as_ref();
    let fd = open(filename, O_CREAT, S_IWUSR).unwrap();  // create empty file

    let stat_result = stat(filename);
    assert_stat_results(stat_result);

    let fstat_result = fstat(fd);
    assert_stat_results(fstat_result);

    close(fd).unwrap();
    unlink(filename).unwrap();
}

#[test]
fn test_stat_fstat_lstat() {
    let filename = b"target/bar.txt".as_ref();
    let linkname = b"target/barlink".as_ref();

    open(filename, O_CREAT, S_IWUSR | S_IRUSR).unwrap();  // create empty file
    fs::soft_link("bar.txt", str::from_utf8(linkname).unwrap()).unwrap();
    let fd = open(linkname, O_RDONLY, S_IRUSR).unwrap();

    // should be the same result as calling stat,
    // since it's a regular file
    let stat_result = lstat(filename);
    assert_stat_results(stat_result);

    let lstat_result = lstat(linkname);
    assert_lstat_results(lstat_result);

    let fstat_result = fstat(fd);
    assert_stat_results(fstat_result);

    close(fd).unwrap();
    unlink(linkname).unwrap();
    unlink(filename).unwrap();
}
<|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.

use std::fmt;
use std::io;
use std::path::PathBuf;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub css_class: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str,
    pub resource_suffix: &'a str,
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
    css_file_extension: bool, themes: &[PathBuf])
    -> io::Result<()>
{
    write!(dst,
"<!DOCTYPE html>\
\
\
    <meta charset=\"utf-8\">\
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\
    <meta name=\"generator\" content=\"rustdoc\">\
    <meta name=\"description\" content=\"{description}\">\
    <meta name=\"keywords\" content=\"{keywords}\">\
    <title>{title}</title>\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \
          id=\"mainThemeStyle\">\
    {themes}\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
          id=\"themeStyle\">\
    \
    {css_extension}\
    {favicon}\
    {in_header}\
\
\
    \
    {before_content}\
    \

☰
\
        {logo}\
        {sidebar}\
    \

\
        <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
            \
        </button>\

\

\
    \
    \
        <form class=\"search-form js-only\">\

\
                <input class=\"search-input\" name=\"search\" \
                       autocomplete=\"off\" \
                       placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                       type=\"search\">\

\
        </form>\
    \

{content}
\

\

\
    \

\

Help
\

\

Keyboard Shortcuts
\

\

?
\

Show this help dialog
\

S
\

Focus the search field
\

↑
\

Move up in search results
\

↓
\

Move down in search results
\

↹
\

Switch tab
\

⏎
\

Go to active search result
\

+
\

Expand all sections
\

-
\

Collapse all sections
\

\

\

\

Search Tricks
\

\
                    Prefix searches with a type followed by a colon (e.g. \
                    fn:) to restrict the search to a given type.\

\

\
                    Accepted types are: fn, mod, \
                    struct, enum, \
                    trait, type, macro, \
                    and const.\

\

\
                    Search functions by type signature (e.g. \
                    vec -> usize or * -> vec)\

\

\

\
    \
    {after_content}\
    \
    \
    \
\
",
    css_extension = if css_file_extension {
        format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
                root_path = page.root_path,
                suffix=page.resource_suffix)
    } else {
        "".to_owned()
    },
    content   = *t,
    root_path = page.root_path,
    css_class = page.css_class,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    themes = themes.iter()
                   .filter_map(|t| t.file_stem())
                   .filter_map(|t| t.to_str())
                   .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}">"#,
                                    page.root_path,
                                    t.replace(".css", &format!("{}.css", page.resource_suffix))))
                   .collect::<String>(),
    suffix=page.resource_suffix,
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<commit_msg>Add doc<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.

use std::fmt;
use std::io;
use std::path::PathBuf;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub css_class: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str,
    pub resource_suffix: &'a str,
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
    css_file_extension: bool, themes: &[PathBuf])
    -> io::Result<()>
{
    write!(dst,
"<!DOCTYPE html>\
\
\
    <meta charset=\"utf-8\">\
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\
    <meta name=\"generator\" content=\"rustdoc\">\
    <meta name=\"description\" content=\"{description}\">\
    <meta name=\"keywords\" content=\"{keywords}\">\
    <title>{title}</title>\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \
          id=\"mainThemeStyle\">\
    {themes}\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
          id=\"themeStyle\">\
    \
    {css_extension}\
    {favicon}\
    {in_header}\
\
\
    \
    {before_content}\
    \

☰
\
        {logo}\
        {sidebar}\
    \

\
        <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
            \
        </button>\

\

\
    \
    \
        <form class=\"search-form js-only\">\

\
                <input class=\"search-input\" name=\"search\" \
                       autocomplete=\"off\" \
                       placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                       type=\"search\">\

\
        </form>\
    \

{content}
\

\

\
    \

\

Help
\

\

Keyboard Shortcuts
\

\

?
\

Show this help dialog
\

S
\

Focus the search field
\

↑
\

Move up in search results
\

↓
\

Move down in search results
\

↹
\

Switch tab
\

⏎
\

Go to active search result
\

+
\

Expand all sections
\

-
\

Collapse all sections
\

\

\

\

Search Tricks
\

\
                    Prefix searches with a type followed by a colon (e.g. \
                    fn:) to restrict the search to a given type.\

\

\
                    Accepted types are: fn, mod, \
                    struct, enum, \
                    trait, type, macro, \
                    and const.\

\

\
                    Search functions by type signature (e.g. \
                    vec -> usize or * -> vec)\

\

\
                    Search multiple things at once by splitting your query with comma (e.g. \
                    str,u8 or String,struct:Vec,test)\

\

\

\
    \
    {after_content}\
    \
    \
    \
\
",
    css_extension = if css_file_extension {
        format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
                root_path = page.root_path,
                suffix=page.resource_suffix)
    } else {
        "".to_owned()
    },
    content   = *t,
    root_path = page.root_path,
    css_class = page.css_class,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    themes = themes.iter()
                   .filter_map(|t| t.file_stem())
                   .filter_map(|t| t.to_str())
                   .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}">"#,
                                    page.root_path,
                                    t.replace(".css", &format!("{}.css", page.resource_suffix))))
                   .collect::<String>(),
    suffix=page.resource_suffix,
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<|endoftext|>


<commit_before>extern crate rsh;

use rsh::builtins::*;
use rsh::State;

#[test]
fn test_cd() {
    let mut s = State::default();
    s.argv = ["cd", "/"];

    let i = cd(&mut s);

    assert_eq!(i, 0);
    assert_eq!(s.cwd.to_string(), "/");
}

#[test]
#[should_panic]
fn test_cd_bad_path() {
    let mut s = State::default();
    s.argv = ["cd", "/123"];

    let i = cd(&mut s);

    assert_eq!(i, 0);
}

#[test]
fn test_set() {
    let mut s = State::default();
    s.argv = ["set", "test", "hello world"];

    let i = set(&mut s);

    assert_eq!(i, 0);
    assert_eq!(s.variables.)
}
<commit_msg>remove integration tests<commit_after><|endoftext|>


<commit_before>
extern crate ndarray;
#[macro_use]
extern crate ndarray_linalg;

use ndarray::*;
use ndarray_linalg::*;

#[test]
fn cholesky() {
    macro_rules! cholesky {
        ($elem:ty, $rtol:expr) => {
            let a_orig: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a_orig);

            let upper = a_orig.cholesky(UPLO::Upper).unwrap();
            assert_close_l2!(&upper.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);

            let lower = a_orig.cholesky(UPLO::Lower).unwrap();
            assert_close_l2!(&lower.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);

            let a: Array2<$elem> = replicate(&a_orig);
            let upper = a.cholesky_into(UPLO::Upper).unwrap();
            assert_close_l2!(&upper.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);

            let a: Array2<$elem> = replicate(&a_orig);
            let lower = a.cholesky_into(UPLO::Lower).unwrap();
            assert_close_l2!(&lower.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);

            let mut a: Array2<$elem> = replicate(&a_orig);
            {
                let upper = a.cholesky_inplace(UPLO::Upper).unwrap();
                assert_close_l2!(&upper.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);
            }
            assert_close_l2!(&a.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);

            let mut a: Array2<$elem> = replicate(&a_orig);
            {
                let lower = a.cholesky_inplace(UPLO::Lower).unwrap();
                assert_close_l2!(&lower.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);
            }
            assert_close_l2!(&a.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);
        }
    }
    cholesky!(f64, 1e-9);
    cholesky!(f32, 1e-5);
    cholesky!(c64, 1e-9);
    cholesky!(c32, 1e-5);
}

#[test]
fn cholesky_into_lower_upper() {
    macro_rules! cholesky_into_lower_upper {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a);
            let upper = a.cholesky(UPLO::Upper).unwrap();
            let fac_upper = a.factorizec(UPLO::Upper).unwrap();
            let fac_lower = a.factorizec(UPLO::Lower).unwrap();
            assert_close_l2!(&upper, &fac_lower.into_upper(), $rtol);
            assert_close_l2!(&upper, &fac_upper.into_upper(), $rtol);
            let lower = a.cholesky(UPLO::Lower).unwrap();
            let fac_upper = a.factorizec(UPLO::Upper).unwrap();
            let fac_lower = a.factorizec(UPLO::Lower).unwrap();
            assert_close_l2!(&lower, &fac_lower.into_lower(), $rtol);
            assert_close_l2!(&lower, &fac_upper.into_lower(), $rtol);
        }
    }
    cholesky_into_lower_upper!(f64, 1e-9);
    cholesky_into_lower_upper!(f32, 1e-5);
    cholesky_into_lower_upper!(c64, 1e-9);
    cholesky_into_lower_upper!(c32, 1e-5);
}

#[test]
fn cholesky_inverse() {
    macro_rules! cholesky_into_inverse {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a);
            let inv = a.invc().unwrap();
            assert_close_l2!(&a.dot(&inv), &Array2::eye(3), $rtol);
            let inv_into: Array2<$elem> = replicate(&a).invc_into().unwrap();
            assert_close_l2!(&a.dot(&inv_into), &Array2::eye(3), $rtol);
            let inv_upper = a.factorizec(UPLO::Upper).unwrap().invc().unwrap();
            assert_close_l2!(&a.dot(&inv_upper), &Array2::eye(3), $rtol);
            let inv_upper_into = a.factorizec(UPLO::Upper).unwrap().invc_into().unwrap();
            assert_close_l2!(&a.dot(&inv_upper_into), &Array2::eye(3), $rtol);
            let inv_lower = a.factorizec(UPLO::Lower).unwrap().invc().unwrap();
            assert_close_l2!(&a.dot(&inv_lower), &Array2::eye(3), $rtol);
            let inv_lower_into = a.factorizec(UPLO::Lower).unwrap().invc_into().unwrap();
            assert_close_l2!(&a.dot(&inv_lower_into), &Array2::eye(3), $rtol);
        }
    }
    cholesky_into_inverse!(f64, 1e-9);
    cholesky_into_inverse!(f32, 1e-3);
    cholesky_into_inverse!(c64, 1e-9);
    cholesky_into_inverse!(c32, 1e-3);
}

#[test]
fn cholesky_det() {
    macro_rules! cholesky_det {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a);
            let det = a.eigvalsh(UPLO::Upper).unwrap().mapv(|elem| elem.ln()).scalar_sum().exp();
            assert_rclose!(a.detc().unwrap(), det, $rtol);
            assert_rclose!(a.factorizec(UPLO::Upper).unwrap().detc(), det, $rtol);
            assert_rclose!(a.factorizec(UPLO::Lower).unwrap().detc(), det, $rtol);
        }
    }
    cholesky_det!(f64, 1e-9);
    cholesky_det!(f32, 1e-4);
    cholesky_det!(c64, 1e-9);
    cholesky_det!(c32, 1e-4);
}

#[test]
fn cholesky_solve() {
    macro_rules! cholesky_solve {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            let x: Array1<$elem> = random(3);
            let b = a.dot(&x);
            println!("a = \n{:?}", a);
            println!("x = \n{:?}", x);
            assert_close_l2!(&a.solvec(&b).unwrap(), &x, $rtol);
            assert_close_l2!(&a.solvec_into(b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.solvec_inplace(&mut b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Upper).unwrap().solvec(&b).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Lower).unwrap().solvec(&b).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Upper).unwrap().solvec_into(b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Lower).unwrap().solvec_into(b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Upper).unwrap().solvec_inplace(&mut b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Lower).unwrap().solvec_inplace(&mut b.clone()).unwrap(), &x, $rtol);
        }
    }
    cholesky_solve!(f64, 1e-9);
    cholesky_solve!(f32, 1e-3);
    cholesky_solve!(c64, 1e-9);
    cholesky_solve!(c32, 1e-3);
}
<commit_msg>Fix spurious cholesky_det test failures<commit_after>
extern crate ndarray;
#[macro_use]
extern crate ndarray_linalg;

use ndarray::*;
use ndarray_linalg::*;

#[test]
fn cholesky() {
    macro_rules! cholesky {
        ($elem:ty, $rtol:expr) => {
            let a_orig: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a_orig);

            let upper = a_orig.cholesky(UPLO::Upper).unwrap();
            assert_close_l2!(&upper.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);

            let lower = a_orig.cholesky(UPLO::Lower).unwrap();
            assert_close_l2!(&lower.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);

            let a: Array2<$elem> = replicate(&a_orig);
            let upper = a.cholesky_into(UPLO::Upper).unwrap();
            assert_close_l2!(&upper.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);

            let a: Array2<$elem> = replicate(&a_orig);
            let lower = a.cholesky_into(UPLO::Lower).unwrap();
            assert_close_l2!(&lower.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);

            let mut a: Array2<$elem> = replicate(&a_orig);
            {
                let upper = a.cholesky_inplace(UPLO::Upper).unwrap();
                assert_close_l2!(&upper.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);
            }
            assert_close_l2!(&a.t().mapv(|elem| elem.conj()).dot(&upper.view()), &a_orig, $rtol);

            let mut a: Array2<$elem> = replicate(&a_orig);
            {
                let lower = a.cholesky_inplace(UPLO::Lower).unwrap();
                assert_close_l2!(&lower.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);
            }
            assert_close_l2!(&a.dot(&lower.t().mapv(|elem| elem.conj())), &a_orig, $rtol);
        }
    }
    cholesky!(f64, 1e-9);
    cholesky!(f32, 1e-5);
    cholesky!(c64, 1e-9);
    cholesky!(c32, 1e-5);
}

#[test]
fn cholesky_into_lower_upper() {
    macro_rules! cholesky_into_lower_upper {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a);
            let upper = a.cholesky(UPLO::Upper).unwrap();
            let fac_upper = a.factorizec(UPLO::Upper).unwrap();
            let fac_lower = a.factorizec(UPLO::Lower).unwrap();
            assert_close_l2!(&upper, &fac_lower.into_upper(), $rtol);
            assert_close_l2!(&upper, &fac_upper.into_upper(), $rtol);
            let lower = a.cholesky(UPLO::Lower).unwrap();
            let fac_upper = a.factorizec(UPLO::Upper).unwrap();
            let fac_lower = a.factorizec(UPLO::Lower).unwrap();
            assert_close_l2!(&lower, &fac_lower.into_lower(), $rtol);
            assert_close_l2!(&lower, &fac_upper.into_lower(), $rtol);
        }
    }
    cholesky_into_lower_upper!(f64, 1e-9);
    cholesky_into_lower_upper!(f32, 1e-5);
    cholesky_into_lower_upper!(c64, 1e-9);
    cholesky_into_lower_upper!(c32, 1e-5);
}

#[test]
fn cholesky_inverse() {
    macro_rules! cholesky_into_inverse {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a);
            let inv = a.invc().unwrap();
            assert_close_l2!(&a.dot(&inv), &Array2::eye(3), $rtol);
            let inv_into: Array2<$elem> = replicate(&a).invc_into().unwrap();
            assert_close_l2!(&a.dot(&inv_into), &Array2::eye(3), $rtol);
            let inv_upper = a.factorizec(UPLO::Upper).unwrap().invc().unwrap();
            assert_close_l2!(&a.dot(&inv_upper), &Array2::eye(3), $rtol);
            let inv_upper_into = a.factorizec(UPLO::Upper).unwrap().invc_into().unwrap();
            assert_close_l2!(&a.dot(&inv_upper_into), &Array2::eye(3), $rtol);
            let inv_lower = a.factorizec(UPLO::Lower).unwrap().invc().unwrap();
            assert_close_l2!(&a.dot(&inv_lower), &Array2::eye(3), $rtol);
            let inv_lower_into = a.factorizec(UPLO::Lower).unwrap().invc_into().unwrap();
            assert_close_l2!(&a.dot(&inv_lower_into), &Array2::eye(3), $rtol);
        }
    }
    cholesky_into_inverse!(f64, 1e-9);
    cholesky_into_inverse!(f32, 1e-3);
    cholesky_into_inverse!(c64, 1e-9);
    cholesky_into_inverse!(c32, 1e-3);
}

#[test]
fn cholesky_det() {
    macro_rules! cholesky_det {
        ($elem:ty, $atol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            println!("a = \n{:?}", a);
            let det = a.eigvalsh(UPLO::Upper).unwrap().mapv(|elem| elem.ln()).scalar_sum().exp();
            assert_aclose!(a.detc().unwrap(), det, $atol);
            assert_aclose!(a.factorizec(UPLO::Upper).unwrap().detc(), det, $atol);
            assert_aclose!(a.factorizec(UPLO::Lower).unwrap().detc(), det, $atol);
        }
    }
    cholesky_det!(f64, 1e-9);
    cholesky_det!(f32, 1e-3);
    cholesky_det!(c64, 1e-9);
    cholesky_det!(c32, 1e-3);
}

#[test]
fn cholesky_solve() {
    macro_rules! cholesky_solve {
        ($elem:ty, $rtol:expr) => {
            let a: Array2<$elem> = random_hpd(3);
            let x: Array1<$elem> = random(3);
            let b = a.dot(&x);
            println!("a = \n{:?}", a);
            println!("x = \n{:?}", x);
            assert_close_l2!(&a.solvec(&b).unwrap(), &x, $rtol);
            assert_close_l2!(&a.solvec_into(b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.solvec_inplace(&mut b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Upper).unwrap().solvec(&b).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Lower).unwrap().solvec(&b).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Upper).unwrap().solvec_into(b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Lower).unwrap().solvec_into(b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Upper).unwrap().solvec_inplace(&mut b.clone()).unwrap(), &x, $rtol);
            assert_close_l2!(&a.factorizec(UPLO::Lower).unwrap().solvec_inplace(&mut b.clone()).unwrap(), &x, $rtol);
        }
    }
    cholesky_solve!(f64, 1e-9);
    cholesky_solve!(f32, 1e-3);
    cholesky_solve!(c64, 1e-9);
    cholesky_solve!(c32, 1e-3);
}
<|endoftext|>


<commit_before>mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "50171c310cd15e1b2d3723766ce64e2e4d6696fc";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: to be categorized
    "src/test/debuginfo/function-names.rs",
    "src/test/pretty/anonymous-types.rs",
    "src/test/ui/associated-types/associated-type-destructuring-assignment.rs",
    "src/test/ui/associated-types/associated-type-struct-construction.rs",
    "src/test/ui/let-else/let-else-run-pass.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs",
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",
    "src/test/ui/rfc-2632-const-trait-impl/tilde-const-syntax.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs",
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/attrib.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/issue-3639.rs",
    "src/tools/rustfmt/tests/source/let_else.rs",
    "src/tools/rustfmt/tests/source/match.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/attrib-block-expr.rs",
    "src/tools/rustfmt/tests/target/attrib.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/let_else.rs",
    "src/tools/rustfmt/tests/target/match.rs",
    "src/tools/rustfmt/tests/target/trait.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Rustc loses some attributes
    // https://github.com/rust-lang/rust/issues/84879
    "src/test/ui/proc-macro/issue-81555.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<commit_msg>Categorize new test suite parse failures<commit_after>mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "50171c310cd15e1b2d3723766ce64e2e4d6696fc";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: negative literal in const generic arg
    // f::<-1>()
    "src/test/debuginfo/function-names.rs",

    // TODO: unnamed fields, anonymous structs/unions
    // struct S { _: union { i: i32 } }
    "src/test/pretty/anonymous-types.rs",

    // TODO: destructuring assignment of tuple variant
    // let <E>::V {} = E::V();
    "src/test/ui/associated-types/associated-type-destructuring-assignment.rs",
    "src/test/ui/associated-types/associated-type-struct-construction.rs",

    // TODO: let else
    // let Some(1) = Some(2) else { return };
    "src/test/ui/let-else/let-else-run-pass.rs",
    "src/tools/rustfmt/tests/source/let_else.rs",
    "src/tools/rustfmt/tests/target/let_else.rs",

    // TODO: ~const
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs",
    "src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs",
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",
    "src/test/ui/rfc-2632-const-trait-impl/tilde-const-syntax.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs",

    // TODO: precedence of attribute on assignment stmt
    "src/tools/rustfmt/tests/source/attrib.rs",
    "src/tools/rustfmt/tests/target/attrib.rs",

    // TODO: losing empty where-clause
    "src/tools/rustfmt/tests/source/issue-3639.rs",

    // TODO: doc comment on match arm
    "src/tools/rustfmt/tests/source/match.rs",
    "src/tools/rustfmt/tests/target/match.rs",

    // TODO: inner attribute inside block
    "src/tools/rustfmt/tests/target/attrib-block-expr.rs",

    // Rustc loses some attributes
    // https://github.com/rust-lang/rust/issues/84879
    "src/test/ui/proc-macro/issue-81555.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<|endoftext|>


<commit_before>// use std::cell::{Cell, RefCell};

use super::{Lexer, State};
use super::Tokn;
use super::error::Error;
use ::util::*;

/*
 Lexer用の各種基本関数
*/
impl<'a> Lexer<'a> {
    pub fn new<I>(iter: &'a mut I) -> Lexer
    where I: Iterator<Item=u8> {
        let c = iter.next().unwrap();
        Lexer { iter: iter,
            current_char: c, state: State::Normal,
            token_bytes: vec![], token: Err(Error::First), eof: false, }
    }

    pub fn finish_error(&mut self, e: Error) {
        self.finish(Err(e), State::Normal);
    }

    pub fn advance(&mut self, c: u8, next: State) {
        self.token_bytes.push(c);
        self.consume_char();
        self.state = next;
    }

    pub fn delimit(&mut self, c: u8, t: Tokn) {
        self.token_bytes.push(c);
        self.consume_char();
        self.finish(Ok(t), State::Normal);
    }

    pub fn reset_token(&mut self) {
        self.token_bytes.clear();
        self.token = Err(Error::First);
    }

    pub fn finish(&mut self, tokn: Result<Tokn, Error>, next: State) {
        self.token = tokn;
        self.state = next;
    }

    pub fn consume_char(&mut self) {
        if let Some(c) = self.iter.next() {
            self.current_char = c;
        } else {
            // self.current_char = b'0';
            self.eof = true;
        }
    }

    pub fn get_token_string(&self) -> String {
        String::from_utf8(self.token_bytes.clone()).expect("Found invalid UTF-8")
    }

    pub fn is_first_otag_letter(&self, c: u8) -> bool {
        is_alphabetic_uppercase(c) || self.is_otag_sign(c)
    }

    pub fn is_dispatcher_sign(&self, c: u8) -> bool {
        c == b'|'
    }

    pub fn is_otag_sign(&self, c: u8) -> bool {
        c == b':'
        // 区切り文字ならここでNameを終わらせる必要がある
        // ただし、全ての区切り文字がここで判断されるわけではない
        // b'[' | b']' | b'(' | b')' | b'{' | b'}' | b':' | b',' => self.finish_with_state(state),
    }

    pub fn eof(&self) -> bool {
        // self.current_char == b'0'
        self.eof
    }
}
<commit_msg>add TODO: comment<commit_after>// use std::cell::{Cell, RefCell};

use super::{Lexer, State};
use super::Tokn;
use super::error::Error;
use ::util::*;

/*
 Lexer用の各種基本関数
*/
impl<'a> Lexer<'a> {
    pub fn new<I>(iter: &'a mut I) -> Lexer
    where I: Iterator<Item=u8> {
        let c = iter.next().unwrap();
        Lexer { iter: iter,
            current_char: c, state: State::Normal,
            token_bytes: vec![], token: Err(Error::First), eof: false, }
    }

    pub fn finish_error(&mut self, e: Error) {
        self.finish(Err(e), State::Normal);
    }

    pub fn advance(&mut self, c: u8, next: State) {
        self.token_bytes.push(c);
        self.consume_char();
        self.state = next;
    }

    pub fn delimit(&mut self, c: u8, t: Tokn) {
        self.token_bytes.push(c);
        self.consume_char();
        self.finish(Ok(t), State::Normal);
    }

    pub fn reset_token(&mut self) {
        self.token_bytes.clear();
        self.token = Err(Error::First);
    }

    pub fn finish(&mut self, tokn: Result<Tokn, Error>, next: State) {
        self.token = tokn;
        self.state = next;
    }

    pub fn consume_char(&mut self) {
        if let Some(c) = self.iter.next() {
            self.current_char = c;
        } else {
            // TODO: 本来であれば、eofかどうかをself.current_char == 0かどうかで判断したいが、
            // なぜかそうするとうまくループが終了しなくなるので、特別なフラグを立てたままにしている
            // この場合、EOF時にcurrent_charが更新されないままになってしまうので、current_charを判断の基準には使えず、
            // 分岐などでもEOFの場合を優先して判定しないといけなくなり、わかりづらく不便なのでできれば修正したい...

            // self.current_char = b'0';
            self.eof = true;
        }
    }

    pub fn get_token_string(&self) -> String {
        String::from_utf8(self.token_bytes.clone()).expect("Found invalid UTF-8")
    }

    pub fn is_first_otag_letter(&self, c: u8) -> bool {
        is_alphabetic_uppercase(c) || self.is_otag_sign(c)
    }

    pub fn is_dispatcher_sign(&self, c: u8) -> bool {
        c == b'|'
    }

    pub fn is_otag_sign(&self, c: u8) -> bool {
        c == b':'
        // 区切り文字ならここでNameを終わらせる必要がある
        // ただし、全ての区切り文字がここで判断されるわけではない
        // b'[' | b']' | b'(' | b')' | b'{' | b'}' | b':' | b',' => self.finish_with_state(state),
    }

    pub fn eof(&self) -> bool {
        // TODO: 本来であれば、eofかどうかをself.current_char == 0かどうかで判断したいが、
        // なぜかそうするとうまくループが終了しなくなるので、特別なフラグを立てたままにしている
        // この場合、EOF時にcurrent_charが更新されないままになってしまうので、current_charを判断の基準には使えず、
        // 分岐などでもEOFの場合を優先して判定しないといけなくなり、わかりづらく不便なのでできれば修正したい...

        // self.current_char == b'0'
        self.eof
    }
}
<|endoftext|>