<commit_before>// Copyright (c) 2016-2019 Fabian Schuiki

//! The central data structure of the compiler.
//!
//! The main piece of infrastructure provided by this module is the [`Context`]
//! trait. It exposes all queries supported by the compiler, together with many
//! other basic operations. Most compiler tasks interact only with [`Context`].
//! The complementary piece of the puzzle is the [`GlobalContext`] which caches
//! all intermediate results and implements the [`Context`] trait. The global
//! context also holds a reference to the [`GlobalArenas`] which own everything
//! that is allocated or interned during query execution.
//!
//! # Example
//!
//! ```
//! # extern crate moore_common as common;
//! # extern crate moore_svlog as svlog;
//! # use common::Session;
//! # use svlog::{GlobalContext, GlobalArenas};
//! let sess = Session::new();
//! let arena = GlobalArenas::default();
//! let gcx = GlobalContext::new(&sess, &arena);
//! ```

use crate::{
    ast,
    ast_map::{AstMap, AstNode},
    common::{arenas::Alloc, arenas::TypedArena, Session},
    crate_prelude::*,
    hir::{self, HirNode},
    ty::{Type, TypeKind},
};
use llhd;
use std::cell::RefCell;
use std::collections::HashMap;

/// The central data structure of the compiler. It stores references to various
/// arenas and tables that store the results of the various computations that
/// have been performed.
pub struct GlobalContext<'gcx> {
    /// The global compiler session.
    pub sess: &'gcx Session,
    /// The arena that owns all references.
    pub arena: &'gcx GlobalArenas<'gcx>,
    /// The underlying runtime for the query system.
    runtime: salsa::Runtime<GlobalContext<'gcx>>,
    /// The mapping of node IDs to abstract syntax tree nodes.
    ast_map: AstMap<'gcx>,
    /// The modules in the AST.
    modules: RefCell<HashMap<Name, NodeId>>,
    /// A mapping from node ids to spans for diagnostics.
    node_id_to_span: RefCell<HashMap<NodeId, Span>>,
}

impl<'gcx> GlobalContext<'gcx> {
    /// Create a new global context.
    pub fn new(sess: &'gcx Session, arena: &'gcx GlobalArenas<'gcx>) -> Self {
        GlobalContext {
            sess,
            arena,
            runtime: Default::default(),
            ast_map: Default::default(),
            modules: Default::default(),
            node_id_to_span: Default::default(),
        }
    }

    /// Add root AST nodes to the context for processing.
    ///
    /// Use the `find_global_item` function afterwards to look up the id of
    /// modules that were added.
    pub fn add_root_nodes(&self, ast: &'gcx [ast::Root]) -> Result<()> {
        for root in ast {
            for item in &root.items {
                match *item {
                    ast::Item::Module(ref m) => {
                        let id = self.map_ast(AstNode::Module(m));
                        self.modules.borrow_mut().insert(m.name, id);
                    }
                    _ => self.unimp(item)?,
                }
            }
        }
        Ok(())
    }

    /// Find a module in the AST.
    pub fn find_module(&self, name: Name) -> Option<NodeId> {
        self.modules.borrow().get(&name).cloned()
    }
}

impl DiagEmitter for GlobalContext<'_> {
    fn emit(&self, diag: DiagBuilder2) {
        self.sess.emit(diag)
    }
}

impl<'gcx> salsa::Database for GlobalContext<'gcx> {
    fn salsa_runtime(&self) -> &salsa::Runtime<Self> {
        &self.runtime
    }
}

impl<'gcx> BaseContext<'gcx> for GlobalContext<'gcx> {
    fn gcx(&self) -> &GlobalContext<'gcx> {
        self
    }
}

/// The arenas that allocate things in the global context.
///
/// Use this struct whenever you want to allocate or internalize
/// something during the compilation procedure.
pub struct GlobalArenas<'t> {
    ids: TypedArena<NodeId>,
    hir: hir::Arena<'t>,
}

impl Default for GlobalArenas<'_> {
    fn default() -> Self {
        GlobalArenas {
            ids: TypedArena::new(),
            hir: Default::default(),
        }
    }
}

impl<'t> GlobalArenas<'t> {
    /// Allocate a list of node IDs.
    pub fn alloc_ids(&'t self, ids: impl IntoIterator<Item = NodeId>) -> &'t [NodeId] {
        self.ids.alloc_extend(ids)
    }

    /// Allocate an HIR node into the global context.
    pub fn alloc_hir<T>(&'t self, hir: T) -> &'t T
    where
        hir::Arena<'t>: Alloc<'t, 't, T>,
        T: 't,
    {
        self.hir.alloc(hir)
    }
}

/// The fundamental compiler context.
///
/// This trait represents the context within which most compiler operations take
/// place. It is implemented by [`GlobalContext`] and also provides access to
/// the global context via the `gcx()` method.
pub trait BaseContext<'gcx>: salsa::Database + DiagEmitter {
    /// Get the global context.
    #[inline(always)]
    fn gcx(&self) -> &GlobalContext<'gcx>;

    /// Get the compiler session.
    #[inline(always)]
    fn sess(&self) -> &'gcx Session {
        self.gcx().sess
    }

    /// Access the arena into which values are to be allocated.
    #[inline(always)]
    fn arena(&self) -> &'gcx GlobalArenas<'gcx> {
        self.gcx().arena
    }

    /// Emit an internal compiler error that a node is not implemented.
    fn unimp<T: HasSpan + HasDesc, R>(&self, node: &T) -> Result<R> {
        self.emit(
            DiagBuilder2::bug(format!("{} not implemented", node.desc_full()))
                .span(node.human_span()),
        );
        Err(())
    }

    /// Emit an internal compiler error and message that a node is not
    /// implemented. Same as [`unimp`], but the caller can provide a message
    /// prefix.
    fn unimp_msg<T: HasSpan + HasDesc, R>(&self, msg: impl Into<String>, node: &T) -> Result<R> {
        self.emit(
            DiagBuilder2::bug(format!(
                "{} {} not implemented",
                msg.into(),
                node.desc_full()
            ))
            .span(node.human_span()),
        );
        Err(())
    }

    /// Allocate a new node id.
    ///
    /// The provided span is used primarily for diagnostic messages and is
    /// supposed to easily identify the node to the user in case of an error.
    fn alloc_id(&self, span: Span) -> NodeId {
        let id = NodeId::alloc();
        self.gcx().node_id_to_span.borrow_mut().insert(id, span);
        id
    }

    /// Associate an AST node with a node id.
    fn set_ast(&self, node_id: NodeId, ast: AstNode<'gcx>) {
        self.gcx().ast_map.set(node_id, ast)
    }

    /// Allocate a node id for an AST node and associate that id with the node.
    fn map_ast(&self, ast: AstNode<'gcx>) -> NodeId {
        let id = self.alloc_id(ast.human_span());
        self.set_ast(id, ast);
        id
    }

    /// Obtain the AST node associated with a node id.
    fn ast_of(&self, node_id: NodeId) -> Result<AstNode<'gcx>> {
        match self.gcx().ast_map.get(node_id) {
            Some(node) => Ok(node),
            None => {
                let span = self.gcx().node_id_to_span.borrow()[&node_id];
                self.emit(
                    DiagBuilder2::bug(format!("no ast node for `{}` in the map", span.extract()))
                        .span(span),
                );
                Err(())
            }
        }
    }

    /// Make a void type.
    fn mkty_void(&self) -> Type<'gcx> {
        static STATIC: TypeKind<'static> = TypeKind::Void;
        &STATIC
    }

    /// Make a bit type.
    fn mkty_bit(&self) -> Type<'gcx> {
        static STATIC: TypeKind<'static> = TypeKind::Bit;
        &STATIC
    }
}

salsa::query_group! {
    /// A collection of compiler queries.
    pub trait Context<'a>: BaseContext<'a> {
        /// Lower an AST node to HIR.
        fn hir_of(node_id: NodeId) -> Result<HirNode<'a>> {
            type HirOf;
            use fn hir::hir_of;
        }

        /// Determine the type of a node.
        fn type_of(node_id: NodeId) -> Result<Type<'a>> {
            type TypeOf;
            use fn typeck::type_of;
        }
    }
}

salsa::database_storage! {
    /// The query result storage embedded in the global context.
    pub struct GlobalStorage<'gcx> for GlobalContext<'gcx> {
        impl Context<'gcx> {
            fn hir_of() for HirOf<'gcx>;
            fn type_of() for TypeOf<'gcx>;
        }
    }
}
<commit_msg>svlog: accept iterator over ast roots<commit_after>// Copyright (c) 2016-2019 Fabian Schuiki

//! The central data structure of the compiler.
//!
//! The main piece of infrastructure provided by this module is the [`Context`]
//! trait. It exposes all queries supported by the compiler, together with many
//! other basic operations. Most compiler tasks interact only with [`Context`].
//! The complementary piece of the puzzle is the [`GlobalContext`] which caches
//! all intermediate results and implements the [`Context`] trait. The global
//! context also holds a reference to the [`GlobalArenas`] which own everything
//! that is allocated or interned during query execution.
//!
//! # Example
//!
//! ```
//! # extern crate moore_common as common;
//! # extern crate moore_svlog as svlog;
//! # use common::Session;
//! # use svlog::{GlobalContext, GlobalArenas};
//! let sess = Session::new();
//! let arena = GlobalArenas::default();
//! let gcx = GlobalContext::new(&sess, &arena);
//! ```

use crate::{
    ast,
    ast_map::{AstMap, AstNode},
    common::{arenas::Alloc, arenas::TypedArena, Session},
    crate_prelude::*,
    hir::{self, HirNode},
    ty::{Type, TypeKind},
};
use llhd;
use std::cell::RefCell;
use std::collections::HashMap;

/// The central data structure of the compiler. It stores references to various
/// arenas and tables that store the results of the various computations that
/// have been performed.
pub struct GlobalContext<'gcx> {
    /// The global compiler session.
    pub sess: &'gcx Session,
    /// The arena that owns all references.
    pub arena: &'gcx GlobalArenas<'gcx>,
    /// The underlying runtime for the query system.
    runtime: salsa::Runtime<GlobalContext<'gcx>>,
    /// The mapping of node IDs to abstract syntax tree nodes.
    ast_map: AstMap<'gcx>,
    /// The modules in the AST.
    modules: RefCell<HashMap<Name, NodeId>>,
    /// A mapping from node ids to spans for diagnostics.
    node_id_to_span: RefCell<HashMap<NodeId, Span>>,
}

impl<'gcx> GlobalContext<'gcx> {
    /// Create a new global context.
    pub fn new(sess: &'gcx Session, arena: &'gcx GlobalArenas<'gcx>) -> Self {
        GlobalContext {
            sess,
            arena,
            runtime: Default::default(),
            ast_map: Default::default(),
            modules: Default::default(),
            node_id_to_span: Default::default(),
        }
    }

    /// Add root AST nodes to the context for processing.
    ///
    /// Use the `find_global_item` function afterwards to look up the id of
    /// modules that were added.
    pub fn add_root_nodes(&self, ast: impl Iterator<Item = &'gcx ast::Root>) {
        for root in ast {
            for item in &root.items {
                match *item {
                    ast::Item::Module(ref m) => {
                        let id = self.map_ast(AstNode::Module(m));
                        self.modules.borrow_mut().insert(m.name, id);
                    }
                    _ => {
                        let _: Result<()> = self.unimp(item);
                    }
                }
            }
        }
    }

    /// Find a module in the AST.
    pub fn find_module(&self, name: Name) -> Option<NodeId> {
        self.modules.borrow().get(&name).cloned()
    }
}

impl DiagEmitter for GlobalContext<'_> {
    fn emit(&self, diag: DiagBuilder2) {
        self.sess.emit(diag)
    }
}

impl<'gcx> salsa::Database for GlobalContext<'gcx> {
    fn salsa_runtime(&self) -> &salsa::Runtime<Self> {
        &self.runtime
    }
}

impl<'gcx> BaseContext<'gcx> for GlobalContext<'gcx> {
    fn gcx(&self) -> &GlobalContext<'gcx> {
        self
    }
}

/// The arenas that allocate things in the global context.
///
/// Use this struct whenever you want to allocate or internalize
/// something during the compilation procedure.
pub struct GlobalArenas<'t> {
    ids: TypedArena<NodeId>,
    hir: hir::Arena<'t>,
}

impl Default for GlobalArenas<'_> {
    fn default() -> Self {
        GlobalArenas {
            ids: TypedArena::new(),
            hir: Default::default(),
        }
    }
}

impl<'t> GlobalArenas<'t> {
    /// Allocate a list of node IDs.
    pub fn alloc_ids(&'t self, ids: impl IntoIterator<Item = NodeId>) -> &'t [NodeId] {
        self.ids.alloc_extend(ids)
    }

    /// Allocate an HIR node into the global context.
    pub fn alloc_hir<T>(&'t self, hir: T) -> &'t T
    where
        hir::Arena<'t>: Alloc<'t, 't, T>,
        T: 't,
    {
        self.hir.alloc(hir)
    }
}

/// The fundamental compiler context.
///
/// This trait represents the context within which most compiler operations take
/// place. It is implemented by [`GlobalContext`] and also provides access to
/// the global context via the `gcx()` method.
pub trait BaseContext<'gcx>: salsa::Database + DiagEmitter {
    /// Get the global context.
    #[inline(always)]
    fn gcx(&self) -> &GlobalContext<'gcx>;

    /// Get the compiler session.
    #[inline(always)]
    fn sess(&self) -> &'gcx Session {
        self.gcx().sess
    }

    /// Access the arena into which values are to be allocated.
    #[inline(always)]
    fn arena(&self) -> &'gcx GlobalArenas<'gcx> {
        self.gcx().arena
    }

    /// Emit an internal compiler error that a node is not implemented.
    fn unimp<T: HasSpan + HasDesc, R>(&self, node: &T) -> Result<R> {
        self.emit(
            DiagBuilder2::bug(format!("{} not implemented", node.desc_full()))
                .span(node.human_span()),
        );
        Err(())
    }

    /// Emit an internal compiler error and message that a node is not
    /// implemented. Same as [`unimp`], but the caller can provide a message
    /// prefix.
    fn unimp_msg<T: HasSpan + HasDesc, R>(&self, msg: impl Into<String>, node: &T) -> Result<R> {
        self.emit(
            DiagBuilder2::bug(format!(
                "{} {} not implemented",
                msg.into(),
                node.desc_full()
            ))
            .span(node.human_span()),
        );
        Err(())
    }

    /// Allocate a new node id.
    ///
    /// The provided span is used primarily for diagnostic messages and is
    /// supposed to easily identify the node to the user in case of an error.
    fn alloc_id(&self, span: Span) -> NodeId {
        let id = NodeId::alloc();
        self.gcx().node_id_to_span.borrow_mut().insert(id, span);
        id
    }

    /// Associate an AST node with a node id.
    fn set_ast(&self, node_id: NodeId, ast: AstNode<'gcx>) {
        self.gcx().ast_map.set(node_id, ast)
    }

    /// Allocate a node id for an AST node and associate that id with the node.
    fn map_ast(&self, ast: AstNode<'gcx>) -> NodeId {
        let id = self.alloc_id(ast.human_span());
        self.set_ast(id, ast);
        id
    }

    /// Obtain the AST node associated with a node id.
    fn ast_of(&self, node_id: NodeId) -> Result<AstNode<'gcx>> {
        match self.gcx().ast_map.get(node_id) {
            Some(node) => Ok(node),
            None => {
                let span = self.gcx().node_id_to_span.borrow()[&node_id];
                self.emit(
                    DiagBuilder2::bug(format!("no ast node for `{}` in the map", span.extract()))
                        .span(span),
                );
                Err(())
            }
        }
    }

    /// Make a void type.
    fn mkty_void(&self) -> Type<'gcx> {
        static STATIC: TypeKind<'static> = TypeKind::Void;
        &STATIC
    }

    /// Make a bit type.
    fn mkty_bit(&self) -> Type<'gcx> {
        static STATIC: TypeKind<'static> = TypeKind::Bit;
        &STATIC
    }
}

salsa::query_group! {
    /// A collection of compiler queries.
    pub trait Context<'a>: BaseContext<'a> {
        /// Lower an AST node to HIR.
        fn hir_of(node_id: NodeId) -> Result<HirNode<'a>> {
            type HirOf;
            use fn hir::hir_of;
        }

        /// Determine the type of a node.
        fn type_of(node_id: NodeId) -> Result<Type<'a>> {
            type TypeOf;
            use fn typeck::type_of;
        }
    }
}

salsa::database_storage! {
    /// The query result storage embedded in the global context.
    pub struct GlobalStorage<'gcx> for GlobalContext<'gcx> {
        impl Context<'gcx> {
            fn hir_of() for HirOf<'gcx>;
            fn type_of() for TypeOf<'gcx>;
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::path::PathBuf;

use clap::{App, Arg, ArgMatches, AppSettings};

use prelude::*;
use config::Config;
use utils::ArgExt;
use api::{Api, NewRelease};
use sourcemaputils::SourceMapProcessor;

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("uploads react-native projects from within a gradle build step")
        // we intentionally hide this command because for all intents and purposes
        // the user should not know it exists.  It's invoked exclusively by the
        // gradle build step in react-native.
        .setting(AppSettings::Hidden)
        .org_project_args()
        .arg(Arg::with_name("sourcemap")
             .long("sourcemap")
             .value_name("PATH")
             .required(true)
             .help("The path to the sourcemap that should be uploaded"))
        .arg(Arg::with_name("bundle")
             .long("bundle")
             .value_name("PATH")
             .required(true)
             .help("The path to the bundle that should be uploaded"))
        .arg(Arg::with_name("release")
             .long("release")
             .value_name("RELEASE")
             .required(true)
             .help("The name of the release to publish."))
        .arg(Arg::with_name("dist")
             .long("dist")
             .value_name("DISTRIBUTION")
             .required(true)
             .multiple(true)
             .number_of_values(1)
             .help("The names of the distirbutions to publish. Can be supplied multiple times."))
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    let (org, project) = config.get_org_and_project(matches)?;
    let api = Api::new(config);
    let base = env::current_dir()?;

    let sourcemap_path = PathBuf::from(matches.value_of("sourcemap").unwrap());
    let bundle_path = PathBuf::from(matches.value_of("bundle").unwrap());
    let sourcemap_url = format!("~/{}", sourcemap_path.file_name().unwrap().to_string_lossy());
    let bundle_url = format!("~/{}", bundle_path.file_name().unwrap().to_string_lossy());

    println!("Processing react-native sourcemaps for Sentry upload.");
    info!("  bundle path: {}", bundle_path.display());
    info!("  sourcemap path: {}", sourcemap_path.display());

    let mut processor = SourceMapProcessor::new(matches.is_present("verbose"));
    processor.add(&bundle_url, &bundle_path)?;
    processor.add(&sourcemap_url, &sourcemap_path)?;
    processor.rewrite(&vec![base.parent().unwrap().to_str().unwrap()])?;
    processor.add_sourcemap_references()?;

    let release = api.new_release(&org, &NewRelease {
        version: matches.value_of("release").unwrap().to_string(),
        projects: vec![project.to_string()],
        ..Default::default()
    })?;

    for dist in matches.values_of("dist").unwrap() {
        println!("Uploading sourcemaps for release {} distribution {}",
                 &release.version, dist);
        processor.upload(&api, &org, Some(&project), &release.version, Some(dist))?;
    }

    Ok(())
}
<commit_msg>Correctly strip the path on android<commit_after>use std::env;
use std::path::PathBuf;

use clap::{App, Arg, ArgMatches, AppSettings};

use prelude::*;
use config::Config;
use utils::ArgExt;
use api::{Api, NewRelease};
use sourcemaputils::SourceMapProcessor;

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("uploads react-native projects from within a gradle build step")
        // we intentionally hide this command because for all intents and purposes
        // the user should not know it exists.  It's invoked exclusively by the
        // gradle build step in react-native.
        .setting(AppSettings::Hidden)
        .org_project_args()
        .arg(Arg::with_name("sourcemap")
             .long("sourcemap")
             .value_name("PATH")
             .required(true)
             .help("The path to the sourcemap that should be uploaded"))
        .arg(Arg::with_name("bundle")
             .long("bundle")
             .value_name("PATH")
             .required(true)
             .help("The path to the bundle that should be uploaded"))
        .arg(Arg::with_name("release")
             .long("release")
             .value_name("RELEASE")
             .required(true)
             .help("The name of the release to publish."))
        .arg(Arg::with_name("dist")
             .long("dist")
             .value_name("DISTRIBUTION")
             .required(true)
             .multiple(true)
             .number_of_values(1)
             .help("The names of the distirbutions to publish. Can be supplied multiple times."))
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    let (org, project) = config.get_org_and_project(matches)?;
    let api = Api::new(config);
    let base = env::current_dir()?;

    let sourcemap_path = PathBuf::from(matches.value_of("sourcemap").unwrap());
    let bundle_path = PathBuf::from(matches.value_of("bundle").unwrap());
    let sourcemap_url = format!("~/{}", sourcemap_path.file_name().unwrap().to_string_lossy());
    let bundle_url = format!("~/{}", bundle_path.file_name().unwrap().to_string_lossy());

    println!("Processing react-native sourcemaps for Sentry upload.");
    info!("  bundle path: {}", bundle_path.display());
    info!("  sourcemap path: {}", sourcemap_path.display());

    let mut processor = SourceMapProcessor::new(matches.is_present("verbose"));
    processor.add(&bundle_url, &bundle_path)?;
    processor.add(&sourcemap_url, &sourcemap_path)?;
    processor.rewrite(&vec![base.to_str().unwrap()])?;
    processor.add_sourcemap_references()?;

    let release = api.new_release(&org, &NewRelease {
        version: matches.value_of("release").unwrap().to_string(),
        projects: vec![project.to_string()],
        ..Default::default()
    })?;

    for dist in matches.values_of("dist").unwrap() {
        println!("Uploading sourcemaps for release {} distribution {}",
                 &release.version, dist);
        processor.upload(&api, &org, Some(&project), &release.version, Some(dist))?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>use average::Histogram;
use rand::{Rng, SeedableRng};
use rand_distr::Normal;

average::define_histogram!(hist, 100);
use hist::Histogram as Histogram100;

mod sparkline;

#[test]
fn normal() {
    const N_SAMPLES: u64 = 1_000_000;
    const MEAN: f64 = 2.;
    const STD_DEV: f64 = 0.5;
    const MIN_X: f64 = -1.;
    const MAX_X: f64 = 5.;

    let dist = Normal::new(MEAN, STD_DEV).unwrap();
    let mut hist = Histogram100::with_const_width(MIN_X,MAX_X);
    let mut rng = rand::rngs::SmallRng::seed_from_u64(1);

    for _ in 0..N_SAMPLES {
        let _ = hist.add(rng.sample(dist));  // Ignore out-of-range values
    }

    println!("Sampled normal distribution:\n{}",
        sparkline::render_u64_as_string(hist.bins()));

    fn pdf(x: f64) -> f64 {
        (-0.5 * ((x - MEAN) / STD_DEV).powi(2)).exp() /
            (STD_DEV * (2. * core::f64::consts::PI).sqrt())
    }

    let mut bin_centers = hist.centers();
    let mut expected = [0.; 100];
    for e in &mut expected {
        *e = pdf(bin_centers.next().unwrap());
    }

    println!("Expected normal distribution:\n{}",
        sparkline::render_u64_as_string(hist.bins()));

    let mut normalized_bins= hist.normalized_bins();
    let mut diff = [0.; 100];
    for i in 0..100 {
        let bin = (normalized_bins.next().unwrap() as f64) / (N_SAMPLES as f64) ;
        diff[i] = (bin - expected[i]).abs();
    }

    println!("Difference:\n{}",
        sparkline::render_f64_as_string(&diff[..]));
    println!("max diff: {:?}", diff.iter().fold(
        core::f64::NEG_INFINITY, |a, &b| a.max(b)));

    // Check that the differences are significantly smaller than the expected error.
    let mut expected_error = [0.; 100];
    // Calculate error from histogram
    for (err, var) in expected_error.iter_mut().zip(hist.variances()) {
        *err = var.sqrt() / (N_SAMPLES as f64);
    }
    // Normalize error by bin width
    for (err, width) in expected_error.iter_mut().zip(hist.widths()) {
        *err /= width;
    }
    // TODO: Calculate error from distribution cutoff / normalization

    println!("max expected_error: {:?}", expected_error.iter().fold(
        core::f64::NEG_INFINITY, |a, &b| a.max(b)));
    for (&d, &e) in diff.iter().zip(expected_error.iter()) {
        // Difference larger than 3 standard deviations or cutoff
        let tol = (3. * e).max(1e-4);
        if d > tol {
            panic!("Difference = {} * tol", d / tol);
        }
    }
}<commit_msg>Another fix for old Rust<commit_after>use average::Histogram;
use rand::{Rng, SeedableRng};
use rand_distr::Normal;

average::define_histogram!(hist, 100);
use hist::Histogram as Histogram100;

mod sparkline;

#[test]
fn normal() {
    const N_SAMPLES: u64 = 1_000_000;
    const MEAN: f64 = 2.;
    const STD_DEV: f64 = 0.5;
    const MIN_X: f64 = -1.;
    const MAX_X: f64 = 5.;

    let dist = Normal::new(MEAN, STD_DEV).unwrap();
    let mut hist = Histogram100::with_const_width(MIN_X,MAX_X);
    let mut rng = rand::rngs::SmallRng::seed_from_u64(1);

    for _ in 0..N_SAMPLES {
        let _ = hist.add(rng.sample(dist));  // Ignore out-of-range values
    }

    println!("Sampled normal distribution:\n{}",
        sparkline::render_u64_as_string(hist.bins()));

    fn pdf(x: f64) -> f64 {
        (-0.5 * ((x - MEAN) / STD_DEV).powi(2)).exp() /
            (STD_DEV * (2. * core::f64::consts::PI).sqrt())
    }

    let mut bin_centers = hist.centers();
    let mut expected = [0.; 100];
    for e in &mut expected[..] {
        *e = pdf(bin_centers.next().unwrap());
    }

    println!("Expected normal distribution:\n{}",
        sparkline::render_u64_as_string(hist.bins()));

    let mut normalized_bins= hist.normalized_bins();
    let mut diff = [0.; 100];
    for i in 0..100 {
        let bin = (normalized_bins.next().unwrap() as f64) / (N_SAMPLES as f64) ;
        diff[i] = (bin - expected[i]).abs();
    }

    println!("Difference:\n{}",
        sparkline::render_f64_as_string(&diff[..]));
    println!("max diff: {:?}", diff.iter().fold(
        core::f64::NEG_INFINITY, |a, &b| a.max(b)));

    // Check that the differences are significantly smaller than the expected error.
    let mut expected_error = [0.; 100];
    // Calculate error from histogram
    for (err, var) in expected_error.iter_mut().zip(hist.variances()) {
        *err = var.sqrt() / (N_SAMPLES as f64);
    }
    // Normalize error by bin width
    for (err, width) in expected_error.iter_mut().zip(hist.widths()) {
        *err /= width;
    }
    // TODO: Calculate error from distribution cutoff / normalization

    println!("max expected_error: {:?}", expected_error.iter().fold(
        core::f64::NEG_INFINITY, |a, &b| a.max(b)));
    for (&d, &e) in diff.iter().zip(expected_error.iter()) {
        // Difference larger than 3 standard deviations or cutoff
        let tol = (3. * e).max(1e-4);
        if d > tol {
            panic!("Difference = {} * tol", d / tol);
        }
    }
}<|endoftext|>


<commit_before>use super::event_manager::*;
use glium::glutin::{ElementState, Event, VirtualKeyCode};

#[derive(Debug)]
pub struct DayTime {
    time_year: u32,
    time_day: u32,
    time_on_day: f32,
    speed: f32,
}

// `DEFAULT_TIME_SPEED` is 1.0 so the time goes at normal speed
// `PLUS_TIME_SPEED` is the factor with which the time is sped up, when the
// speed-up key is pressed
const DEFAULT_TIME_SPEED: f32 = 1.0;
const PLUS_TIME_SPEED: f32 = 1000.0;

impl Default for DayTime {
    fn default() -> DayTime {
        DayTime {
            time_year: 0,
            time_day: 0,
            time_on_day: 0.0,
            speed: 1.0,
        }
    }
}

impl DayTime {
    pub fn set_time(&mut self, time_year: u32, time_day: u32, time_on_day: f32) {
        self.time_year = time_year;
        self.time_day = time_day;
        self.time_on_day = time_on_day;
        self.speed = DEFAULT_TIME_SPEED;
    }

    pub fn get_time_year(&self) -> u32 {
        self.time_year
    }

    pub fn get_time_day(&self) -> u32 {
        self.time_day
    }

    pub fn get_time_on_day(&self) -> f32 {
        self.time_on_day
    }

    // Updates time with the use of `delta` as additionally passed time
    // `DAY_LENGTH` defines the length of a day in real-life seconds
    // `YEAR_LENGTH` defines the length of a year in `DAY_LENGTH`s
    pub fn update(&mut self, delta: f32) {
        const DAY_LENGTH: f32 = 720.0;
        const YEAR_LENGTH: u32 = 12;

        // Output of Time
        info!("Year: {} Day: {} Time: {}",
              self.time_year,
              self.time_day,
              self.time_on_day);

        // Checks if one day has passed
        self.time_on_day += delta * self.speed;
        if (self.time_on_day) >= DAY_LENGTH {
            self.time_on_day -= DAY_LENGTH; // Removes one day from time_on_day
            self.time_day += 1;
            if (self.time_day) >= YEAR_LENGTH {
                self.time_day = 0;
                self.time_year += 1;
            }
        }

    }
}

// Handler to speed up time with use of key
impl EventHandler for DayTime {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Add)) => {
                self.speed = PLUS_TIME_SPEED;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Add)) => {
                self.speed = DEFAULT_TIME_SPEED;
                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }

    }
}
<commit_msg>add theta and phi calculation in daytime based on current time<commit_after>use super::event_manager::*;
use glium::glutin::{ElementState, Event, VirtualKeyCode};
use std::f32::consts;

#[derive(Debug)]
pub struct DayTime {
    time_year: u32,
    time_day: u32,
    time_on_day: f32,
    speed: f32,
}

// `DEFAULT_TIME_SPEED` is 1.0 so the time goes at normal speed
// `PLUS_TIME_SPEED` is the factor with which the time is sped up, when the
// speed-up key is pressed
const DEFAULT_TIME_SPEED: f32 = 1.0;
const PLUS_TIME_SPEED: f32 = 1000.0;

impl Default for DayTime {
    fn default() -> DayTime {
        DayTime {
            time_year: 0,
            time_day: 0,
            time_on_day: 0.0,
            speed: 1.0,
        }
    }
}

const DAY_LENGTH: f32 = 720.0;
const YEAR_LENGTH: u32 = 12;

const MONTH_DIFFERENCE: f32 = 3.1415 / 18.0;

impl DayTime {
    pub fn set_time(&mut self, time_year: u32, time_day: u32, time_on_day: f32) {
        self.time_year = time_year;
        self.time_day = time_day;
        self.time_on_day = time_on_day;
        self.speed = DEFAULT_TIME_SPEED;
    }

    pub fn get_time_year(&self) -> u32 {
        self.time_year
    }

    pub fn get_time_day(&self) -> u32 {
        self.time_day
    }

    pub fn get_time_on_day(&self) -> f32 {
        self.time_on_day
    }

    // Updates time with the use of `delta` as additionally passed time
    // `DAY_LENGTH` defines the length of a day in real-life seconds
    // `YEAR_LENGTH` defines the length of a year in `DAY_LENGTH`s
    pub fn update(&mut self, delta: f32) {
        // Output of Time
        info!("Year: {} Day: {} Time: {}",
              self.time_year,
              self.time_day,
              self.time_on_day);

        // Checks if one day has passed
        self.time_on_day += delta * self.speed;
        if (self.time_on_day) >= DAY_LENGTH {
            self.time_on_day -= DAY_LENGTH; // Removes one day from time_on_day
            self.time_day += 1;
            if (self.time_day) >= YEAR_LENGTH {
                self.time_day = 0;
                self.time_year += 1;
            }
        }

    }

    pub fn get_sun_light_vector(&self) {
        // 0 degrees for mid summer
        // 60 degrees for hard winter
        let mut half_year = YEAR_LENGTH as f32 / 2.0;
        let mut half_day = DAY_LENGTH as f32 / 2.0;

        let mut theta = self.time_day as f32 - half_year;
        if theta < 0.0 {
            theta *= -1.0;
        }
        // theta now is the day difference from the highest day, sunposition-wise
        theta *= MONTH_DIFFERENCE;

        if self.time_on_day < half_day {
            // pre noon
            // sun rising
            theta += consts::PI - consts::PI * (self.time_on_day / half_day)
        } else {
            // after noon
            // sun going down
            theta += consts::PI * ((self.time_on_day - half_day) / half_day)
        }

        let mut phi = self.time_on_day / DAY_LENGTH as f32 * 2.0 * consts::PI;

        info!("THETA: {} PHI: {}", theta, phi);
    }
}

// Handler to speed up time with use of key
impl EventHandler for DayTime {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Add)) => {
                self.speed = PLUS_TIME_SPEED;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Add)) => {
                self.speed = DEFAULT_TIME_SPEED;
                EventResponse::Continue
            }
            _ => EventResponse::NotHandled,
        }

    }
}

// position in theta phi

// lichtvektor
<|endoftext|>


<commit_before>use cxx::{CxxString, UniquePtr};
use std::fmt::{self, Display};

#[cxx::bridge(namespace = tests)]
pub mod ffi {
    struct Shared {
        z: usize,
    }

    extern "C" {
        include!("tests/ffi/tests.h");

        type C;

        fn c_return_primitive() -> usize;
        fn c_return_shared() -> Shared;
        fn c_return_box() -> Box<R>;
        fn c_return_unique_ptr() -> UniquePtr<C>;
        fn c_return_ref(shared: &Shared) -> &usize;
        fn c_return_str(shared: &Shared) -> &str;
        fn c_return_rust_string() -> String;
        fn c_return_unique_ptr_string() -> UniquePtr<CxxString>;

        fn c_take_primitive(n: usize);
        fn c_take_shared(shared: Shared);
        fn c_take_box(r: Box<R>);
        fn c_take_unique_ptr(c: UniquePtr<C>);
        fn c_take_ref_r(r: &R);
        fn c_take_ref_c(c: &C);
        fn c_take_str(s: &str);
        fn c_take_rust_string(s: String);
        fn c_take_unique_ptr_string(s: UniquePtr<CxxString>);

        fn c_try_return_void() -> Result<()>;
        fn c_try_return_primitive() -> Result<usize>;
        fn c_fail_return_primitive() -> Result<usize>;
    }

    extern "Rust" {
        type R;

        fn r_return_primitive() -> usize;
        fn r_return_shared() -> Shared;
        fn r_return_box() -> Box<R>;
        fn r_return_unique_ptr() -> UniquePtr<C>;
        fn r_return_ref(shared: &Shared) -> &usize;
        fn r_return_str(shared: &Shared) -> &str;
        fn r_return_rust_string() -> String;
        fn r_return_unique_ptr_string() -> UniquePtr<CxxString>;

        fn r_take_primitive(n: usize);
        fn r_take_shared(shared: Shared);
        fn r_take_box(r: Box<R>);
        fn r_take_unique_ptr(c: UniquePtr<C>);
        fn r_take_ref_r(r: &R);
        fn r_take_ref_c(c: &C);
        fn r_take_str(s: &str);
        fn r_take_rust_string(s: String);
        fn r_take_unique_ptr_string(s: UniquePtr<CxxString>);

        fn r_try_return_void() -> Result<()>;
        fn r_try_return_primitive() -> Result<usize>;
        fn r_fail_return_primitive() -> Result<usize>;
    }
}

pub type R = usize;

#[derive(Debug)]
struct Error;

impl std::error::Error for Error {}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("rust error")
    }
}

fn r_return_primitive() -> usize {
    2020
}

fn r_return_shared() -> ffi::Shared {
    ffi::Shared { z: 2020 }
}

fn r_return_box() -> Box<R> {
    Box::new(2020)
}

fn r_return_unique_ptr() -> UniquePtr<ffi::C> {
    extern "C" {
        fn cxx_test_suite_get_unique_ptr() -> *mut ffi::C;
    }
    unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr()) }
}

fn r_return_ref(shared: &ffi::Shared) -> &usize {
    &shared.z
}

fn r_return_str(shared: &ffi::Shared) -> &str {
    let _ = shared;
    "2020"
}

fn r_return_rust_string() -> String {
    "2020".to_owned()
}

fn r_return_unique_ptr_string() -> UniquePtr<CxxString> {
    extern "C" {
        fn cxx_test_suite_get_unique_ptr_string() -> *mut CxxString;
    }
    unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr_string()) }
}

fn r_take_primitive(n: usize) {
    assert_eq!(n, 2020);
}

fn r_take_shared(shared: ffi::Shared) {
    assert_eq!(shared.z, 2020);
}

fn r_take_box(r: Box<R>) {
    let _ = r;
}

fn r_take_unique_ptr(c: UniquePtr<ffi::C>) {
    let _ = c;
}

fn r_take_ref_r(r: &R) {
    let _ = r;
}

fn r_take_ref_c(c: &ffi::C) {
    let _ = c;
}

fn r_take_str(s: &str) {
    assert_eq!(s, "2020");
}

fn r_take_rust_string(s: String) {
    assert_eq!(s, "2020");
}

fn r_take_unique_ptr_string(s: UniquePtr<CxxString>) {
    assert_eq!(s.as_ref().unwrap().to_str().unwrap(), "2020");
}

fn r_try_return_void() -> Result<(), Error> {
    Ok(())
}

fn r_try_return_primitive() -> Result<usize, Error> {
    Ok(2020)
}

fn r_fail_return_primitive() -> Result<usize, Error> {
    Err(Error)
}
<commit_msg>Suppress some clippy lints in test suite<commit_after>#![allow(clippy::boxed_local, clippy::trivially_copy_pass_by_ref)]

use cxx::{CxxString, UniquePtr};
use std::fmt::{self, Display};

#[cxx::bridge(namespace = tests)]
pub mod ffi {
    struct Shared {
        z: usize,
    }

    extern "C" {
        include!("tests/ffi/tests.h");

        type C;

        fn c_return_primitive() -> usize;
        fn c_return_shared() -> Shared;
        fn c_return_box() -> Box<R>;
        fn c_return_unique_ptr() -> UniquePtr<C>;
        fn c_return_ref(shared: &Shared) -> &usize;
        fn c_return_str(shared: &Shared) -> &str;
        fn c_return_rust_string() -> String;
        fn c_return_unique_ptr_string() -> UniquePtr<CxxString>;

        fn c_take_primitive(n: usize);
        fn c_take_shared(shared: Shared);
        fn c_take_box(r: Box<R>);
        fn c_take_unique_ptr(c: UniquePtr<C>);
        fn c_take_ref_r(r: &R);
        fn c_take_ref_c(c: &C);
        fn c_take_str(s: &str);
        fn c_take_rust_string(s: String);
        fn c_take_unique_ptr_string(s: UniquePtr<CxxString>);

        fn c_try_return_void() -> Result<()>;
        fn c_try_return_primitive() -> Result<usize>;
        fn c_fail_return_primitive() -> Result<usize>;
    }

    extern "Rust" {
        type R;

        fn r_return_primitive() -> usize;
        fn r_return_shared() -> Shared;
        fn r_return_box() -> Box<R>;
        fn r_return_unique_ptr() -> UniquePtr<C>;
        fn r_return_ref(shared: &Shared) -> &usize;
        fn r_return_str(shared: &Shared) -> &str;
        fn r_return_rust_string() -> String;
        fn r_return_unique_ptr_string() -> UniquePtr<CxxString>;

        fn r_take_primitive(n: usize);
        fn r_take_shared(shared: Shared);
        fn r_take_box(r: Box<R>);
        fn r_take_unique_ptr(c: UniquePtr<C>);
        fn r_take_ref_r(r: &R);
        fn r_take_ref_c(c: &C);
        fn r_take_str(s: &str);
        fn r_take_rust_string(s: String);
        fn r_take_unique_ptr_string(s: UniquePtr<CxxString>);

        fn r_try_return_void() -> Result<()>;
        fn r_try_return_primitive() -> Result<usize>;
        fn r_fail_return_primitive() -> Result<usize>;
    }
}

pub type R = usize;

#[derive(Debug)]
struct Error;

impl std::error::Error for Error {}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("rust error")
    }
}

fn r_return_primitive() -> usize {
    2020
}

fn r_return_shared() -> ffi::Shared {
    ffi::Shared { z: 2020 }
}

fn r_return_box() -> Box<R> {
    Box::new(2020)
}

fn r_return_unique_ptr() -> UniquePtr<ffi::C> {
    extern "C" {
        fn cxx_test_suite_get_unique_ptr() -> *mut ffi::C;
    }
    unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr()) }
}

fn r_return_ref(shared: &ffi::Shared) -> &usize {
    &shared.z
}

fn r_return_str(shared: &ffi::Shared) -> &str {
    let _ = shared;
    "2020"
}

fn r_return_rust_string() -> String {
    "2020".to_owned()
}

fn r_return_unique_ptr_string() -> UniquePtr<CxxString> {
    extern "C" {
        fn cxx_test_suite_get_unique_ptr_string() -> *mut CxxString;
    }
    unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr_string()) }
}

fn r_take_primitive(n: usize) {
    assert_eq!(n, 2020);
}

fn r_take_shared(shared: ffi::Shared) {
    assert_eq!(shared.z, 2020);
}

fn r_take_box(r: Box<R>) {
    let _ = r;
}

fn r_take_unique_ptr(c: UniquePtr<ffi::C>) {
    let _ = c;
}

fn r_take_ref_r(r: &R) {
    let _ = r;
}

fn r_take_ref_c(c: &ffi::C) {
    let _ = c;
}

fn r_take_str(s: &str) {
    assert_eq!(s, "2020");
}

fn r_take_rust_string(s: String) {
    assert_eq!(s, "2020");
}

fn r_take_unique_ptr_string(s: UniquePtr<CxxString>) {
    assert_eq!(s.as_ref().unwrap().to_str().unwrap(), "2020");
}

fn r_try_return_void() -> Result<(), Error> {
    Ok(())
}

fn r_try_return_primitive() -> Result<usize, Error> {
    Ok(2020)
}

fn r_fail_return_primitive() -> Result<usize, Error> {
    Err(Error)
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

extern crate gtk;
#[macro_use]
extern crate relm;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::Widget;

#[derive(Clone)]
pub struct Model {
    counter: i32,
}

#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
}

// An alternative to the #[widget] attribute which works on stable.
relm_widget! {
    impl Widget for Win {
        // The initial model.
        fn model() -> Model {
            Model {
                counter: 0,
            }
        }

        // Update the model according to the message received.
        fn update(&mut self, event: Msg, model: &mut Model) {
            match event {
                Msg::Decrement => model.counter -= 1,
                Msg::Increment => model.counter += 1,
                Msg::Quit => gtk::main_quit(),
            }
        }

        view! {
            gtk::Window {
                gtk::Box {
                    // Set the orientation property of the Box.
                    orientation: Vertical,
                    // Create a Button inside the Box.
                    gtk::Button {
                        // Send the message Increment when the button is clicked.
                        clicked => Msg::Increment,
                        label: "+",
                    },
                    gtk::Label {
                        // Bind the text property of the label to the counter attribute of the model.
                        text: &model.counter.to_string(),
                    },
                    gtk::Button {
                        clicked => Msg::Decrement,
                        label: "-",
                    },
                },
                delete_event(_, _) => (Msg::Quit, Inhibit(false)),
            }
        }
    }
}

fn main() {
    relm::run::<Win>().unwrap();
}
<commit_msg>Fix buttons-derive example<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

extern crate gtk;
#[macro_use]
extern crate relm;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::Widget;

#[derive(Clone)]
pub struct Model {
    counter: i32,
}

#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
}

// An alternative to the #[widget] attribute which works on stable.
relm_widget! {
    impl Widget for Win {
        // The initial model.
        fn model() -> Model {
            Model {
                counter: 0,
            }
        }

        // Update the model according to the message received.
        fn update(&mut self, event: Msg, model: &mut Model) {
            match event {
                Msg::Decrement => model.counter -= 1,
                Msg::Increment => model.counter += 1,
                Msg::Quit => gtk::main_quit(),
            }
        }

        view! {
            gtk::Window {
                gtk::Box {
                    // Set the orientation property of the Box.
                    orientation: Vertical,
                    // Create a Button inside the Box.
                    gtk::Button {
                        // Send the message Increment when the button is clicked.
                        clicked => Msg::Increment,
                        label: "+",
                    },
                    gtk::Label {
                        // Bind the text property of the label to the counter attribute of the model.
                        text: &model.counter.to_string(),
                    },
                    gtk::Button {
                        clicked => Msg::Decrement,
                        label: "-",
                    },
                },
                delete_event(_, _) => (Msg::Quit, Inhibit(false)),
            }
        }
    }
}

fn main() {
    Win::run(()).unwrap();
}
<|endoftext|>


<commit_before>#![cfg(feature = "std")]

use std::{thread, time::Instant as StdInstant};
use time::{
    ext::{NumericalDuration, NumericalStdDuration},
    Duration, Instant,
};

#[test]
fn elapsed() {
    let instant = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(instant.elapsed() >= 1.milliseconds());
}

#[test]
fn checked_add() {
    let now = Instant::now();
    assert_eq!(now.checked_add(0.seconds()), Some(now));
    assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
    assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
}

#[test]
fn checked_sub() {
    let now = Instant::now();
    assert_eq!(now.checked_sub(0.seconds()), Some(now));
    assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
    assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
}

#[test]
fn from_std() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time);
    assert_eq!(now_time, now_std);
}

#[test]
fn to_std() {
    let now_std = StdInstant::now();
    let now_time = Instant::from(now_std);
    assert_eq!(now_time, now_std);
}

#[test]
fn sub() {
    let start = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(Instant::now() - start >= 1.milliseconds());
}

#[test]
fn sub_std() {
    let start = StdInstant::now();
    thread::sleep(1.std_milliseconds());
    assert!(Instant::now() - start >= 1.milliseconds());
}

#[test]
fn std_sub() {
    let start = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(StdInstant::now() - start >= 1.milliseconds());
}

#[test]
fn add_duration() {
    let start = Instant::now();
    assert!(start + 0.seconds() <= Instant::now());
    thread::sleep(1.std_milliseconds());
    assert!(start + 1.milliseconds() <= Instant::now());
}

#[test]
fn std_add_duration() {
    let start = StdInstant::now();
    thread::sleep(1.std_milliseconds());
    assert!(start + 1.milliseconds() <= StdInstant::now());
}

#[test]
fn add_std_duration() {
    let start = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(start + 1.std_milliseconds() <= Instant::now());
}

#[test]
fn add_assign_duration() {
    let mut start = Instant::now();
    thread::sleep(1.std_milliseconds());
    start += 1.milliseconds();
    assert!(start <= Instant::now());
}

#[test]
fn std_add_assign_duration() {
    let mut start = StdInstant::now();
    thread::sleep(1.std_milliseconds());
    start += 1.milliseconds();
    assert!(start <= StdInstant::now());
}

#[test]
fn add_assign_std_duration() {
    let mut start = Instant::now();
    thread::sleep(1.std_milliseconds());
    start += 1.std_milliseconds();
    assert!(start <= Instant::now());
}

#[test]
fn sub_duration() {
    let instant = Instant::now();
    assert!(instant - 100.milliseconds() <= Instant::now());
}

#[test]
fn std_sub_duration() {
    let instant = StdInstant::now();
    assert!(instant - 100.milliseconds() <= StdInstant::now());
}

#[test]
fn sub_std_duration() {
    let instant = Instant::now();
    assert!(instant - 100.std_milliseconds() <= Instant::now());
}

#[test]
fn sub_assign_duration() {
    let mut instant = Instant::now();
    instant -= 100.milliseconds();
    assert!(instant <= Instant::now());
}

#[test]
fn std_sub_assign_duration() {
    let mut instant = StdInstant::now();
    instant -= 100.milliseconds();
    assert!(instant <= StdInstant::now());
}

#[test]
fn sub_assign_std_duration() {
    let mut instant = Instant::now();
    instant -= 100.std_milliseconds();
    assert!(instant <= Instant::now());
}

#[test]
fn eq_std() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time);
    assert_eq!(now_time, now_std);
}

#[test]
fn std_eq() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time);
    assert_eq!(now_std, now_time);
}

#[test]
fn ord_std() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) + 1.seconds();
    assert!(now_time < now_std);

    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) - 1.seconds();
    assert!(now_time > now_std);
}

#[test]
fn std_ord() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) + 1.seconds();
    assert!(now_std > now_time);

    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) - 1.seconds();
    assert!(now_std < now_time);
}

#[test]
fn sub_regression() {
    let now = Instant::now();
    let future = now + Duration::seconds(5);
    let past = now - Duration::seconds(5);

    assert_eq!(future - now, Duration::seconds(5));
    assert_eq!(now - past, Duration::seconds(5));
    assert_eq!(future - past, Duration::seconds(10));

    assert_eq!(now - future, Duration::seconds(-5));
    assert_eq!(past - now, Duration::seconds(-5));
    assert_eq!(past - future, Duration::seconds(-10));
}
<commit_msg>Fix flipped Instant test names<commit_after>#![cfg(feature = "std")]

use std::{thread, time::Instant as StdInstant};
use time::{
    ext::{NumericalDuration, NumericalStdDuration},
    Duration, Instant,
};

#[test]
fn elapsed() {
    let instant = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(instant.elapsed() >= 1.milliseconds());
}

#[test]
fn checked_add() {
    let now = Instant::now();
    assert_eq!(now.checked_add(0.seconds()), Some(now));
    assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
    assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
}

#[test]
fn checked_sub() {
    let now = Instant::now();
    assert_eq!(now.checked_sub(0.seconds()), Some(now));
    assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
    assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
}

#[test]
fn std_from() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time);
    assert_eq!(now_time, now_std);
}

#[test]
fn from_std() {
    let now_std = StdInstant::now();
    let now_time = Instant::from(now_std);
    assert_eq!(now_time, now_std);
}

#[test]
fn sub() {
    let start = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(Instant::now() - start >= 1.milliseconds());
}

#[test]
fn sub_std() {
    let start = StdInstant::now();
    thread::sleep(1.std_milliseconds());
    assert!(Instant::now() - start >= 1.milliseconds());
}

#[test]
fn std_sub() {
    let start = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(StdInstant::now() - start >= 1.milliseconds());
}

#[test]
fn add_duration() {
    let start = Instant::now();
    assert!(start + 0.seconds() <= Instant::now());
    thread::sleep(1.std_milliseconds());
    assert!(start + 1.milliseconds() <= Instant::now());
}

#[test]
fn std_add_duration() {
    let start = StdInstant::now();
    thread::sleep(1.std_milliseconds());
    assert!(start + 1.milliseconds() <= StdInstant::now());
}

#[test]
fn add_std_duration() {
    let start = Instant::now();
    thread::sleep(1.std_milliseconds());
    assert!(start + 1.std_milliseconds() <= Instant::now());
}

#[test]
fn add_assign_duration() {
    let mut start = Instant::now();
    thread::sleep(1.std_milliseconds());
    start += 1.milliseconds();
    assert!(start <= Instant::now());
}

#[test]
fn std_add_assign_duration() {
    let mut start = StdInstant::now();
    thread::sleep(1.std_milliseconds());
    start += 1.milliseconds();
    assert!(start <= StdInstant::now());
}

#[test]
fn add_assign_std_duration() {
    let mut start = Instant::now();
    thread::sleep(1.std_milliseconds());
    start += 1.std_milliseconds();
    assert!(start <= Instant::now());
}

#[test]
fn sub_duration() {
    let instant = Instant::now();
    assert!(instant - 100.milliseconds() <= Instant::now());
}

#[test]
fn std_sub_duration() {
    let instant = StdInstant::now();
    assert!(instant - 100.milliseconds() <= StdInstant::now());
}

#[test]
fn sub_std_duration() {
    let instant = Instant::now();
    assert!(instant - 100.std_milliseconds() <= Instant::now());
}

#[test]
fn sub_assign_duration() {
    let mut instant = Instant::now();
    instant -= 100.milliseconds();
    assert!(instant <= Instant::now());
}

#[test]
fn std_sub_assign_duration() {
    let mut instant = StdInstant::now();
    instant -= 100.milliseconds();
    assert!(instant <= StdInstant::now());
}

#[test]
fn sub_assign_std_duration() {
    let mut instant = Instant::now();
    instant -= 100.std_milliseconds();
    assert!(instant <= Instant::now());
}

#[test]
fn eq_std() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time);
    assert_eq!(now_time, now_std);
}

#[test]
fn std_eq() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time);
    assert_eq!(now_std, now_time);
}

#[test]
fn ord_std() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) + 1.seconds();
    assert!(now_time < now_std);

    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) - 1.seconds();
    assert!(now_time > now_std);
}

#[test]
fn std_ord() {
    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) + 1.seconds();
    assert!(now_std > now_time);

    let now_time = Instant::now();
    let now_std = StdInstant::from(now_time) - 1.seconds();
    assert!(now_std < now_time);
}

#[test]
fn sub_regression() {
    let now = Instant::now();
    let future = now + Duration::seconds(5);
    let past = now - Duration::seconds(5);

    assert_eq!(future - now, Duration::seconds(5));
    assert_eq!(now - past, Duration::seconds(5));
    assert_eq!(future - past, Duration::seconds(10));

    assert_eq!(now - future, Duration::seconds(-5));
    assert_eq!(past - now, Duration::seconds(-5));
    assert_eq!(past - future, Duration::seconds(-10));
}
<|endoftext|>


<commit_before>//! Handling of DICOM values with the VR PN (person name) as per PS3.5 sect 6.2.
use std::fmt::{Display, Formatter};

/*#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Write error: '{source}'"))]
    Write { source: std::fmt::Error },
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
*/
/// Represents a Dicom `PersonName` (PN).
/// Stores family, given, middle name, prefix and suffix as borrowed values.
/// All name components are optional.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PersonName<'a> {
    prefix: Option<&'a str>,
    family: Option<&'a str>,
    middle: Option<&'a str>,
    given: Option<&'a str>,
    suffix: Option<&'a str>,
}

/// A builder to construct a `PersonName` from it's components.
#[derive(Debug, Copy, Clone)]
pub struct PersonNameBuilder<'a> {
    person_name: PersonName<'a>,
}

impl Display for PersonName<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let components: &[Option<&str>] = &[
            self.prefix,
            self.given,
            self.middle,
            self.family,
            self.suffix,
        ];

        let mut c_iter = components.iter().flatten().peekable();

        while let Some(component) = c_iter.next() {
            if c_iter.peek().is_some() {
                write!(f, "{} ", component)?
            } else {
                write!(f, "{}", component)?
            }
        }
        Ok(())
    }
}

impl<'a> PersonName<'a> {
    /// Retrieve PersonName prefix
    pub fn prefix(&self) -> Option<&str> {
        self.prefix
    }
    /// Retrieve PersonName suffix
    pub fn suffix(&self) -> Option<&str> {
        self.suffix
    }
    /// Retrieve family name from PersonName
    pub fn family(&self) -> Option<&str> {
        self.family
    }
    /// Retrieve given name from PersonName
    pub fn given(&self) -> Option<&str> {
        self.given
    }
    /// Retrieve middle name from PersonName
    pub fn middle(&self) -> Option<&str> {
        self.middle
    }
    /// Convert PersonName into a Dicom formatted string.
    /// Name components are interspersed with a '^' separator.
    /// Leading null components produce a separator, while trailing do not.
    pub fn to_dicom_string(&self) -> String {
        let mut name = String::new();

        let components: &[Option<&str>] = &[
            self.family,
            self.given,
            self.middle,
            self.prefix,
            self.suffix,
        ];

        let mut it  = components.iter().rev().peekable();
        // remove trailing None (null) components
        while it.next_if(|component| component.is_none()).is_some(){}

        let mut it = it.rev().peekable();
        while let Some(option) = it.next() {
            if let Some(component) = option {
                name.push_str(component);
            }
            if it.peek().is_some() {
                name.push('^');
            }
        }

        name
    }
    /// Retrieves a PersonName from a Dicom formatted string slice.
    /// The Dicom string representation is split by '^' separator into its respective components.
    pub fn from_slice(slice: &'a str) -> PersonName<'a> {
        let mut parts = slice.split('^');

        macro_rules! get_component {
            () => {
                parts
                    .next()
                    .and_then(|s| if s.is_empty() { None } else { Some(s) })
            };
        }

        let family = get_component!();
        let given = get_component!();
        let middle = get_component!();
        let prefix = get_component!();
        let suffix = get_component!();

        PersonName {
            prefix,
            given,
            family,
            middle,
            suffix,
        }
    }
    /// Retrieve a builder for a PersonName
    pub fn builder() -> PersonNameBuilder<'a> {
        PersonNameBuilder::new()
    }
}

impl<'a> PersonNameBuilder<'a> {
    pub fn new() -> PersonNameBuilder<'a> {
        PersonNameBuilder {
            person_name: PersonName {
                prefix: None,
                family: None,
                middle: None,
                given: None,
                suffix: None,
            },
        }
    }
    /// Insert family name component
    pub fn with_family(mut self, family_name: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.family = Some(family_name);
        self
    }
    pub fn with_middle(mut self, middle_name: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.middle = Some(middle_name);
        self
    }
    pub fn with_given(mut self, given_name: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.given = Some(given_name);
        self
    }
    pub fn with_prefix(mut self, name_prefix: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.prefix = Some(name_prefix);
        self
    }
    pub fn with_suffix(mut self, name_suffix: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.suffix = Some(name_suffix);
        self
    }
    /// Builds a PersonName
    pub fn build(&self) -> PersonName<'a> {
        self.person_name
    }
}

impl<'a> Default for PersonNameBuilder<'a> {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_person_name_to_dicom_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_dicom_string(), "^^^^B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^Rev.^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^Robert".to_string());
    }
    #[test]
    fn test_person_name_to_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Adams".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev.".to_string());

        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_string(),
            "Rev. John Robert Adams B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "John Robert Adams B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev. John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Robert".to_string());
    }
    #[test]
    fn person_name_from_slice() {
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^Rev."),
            PersonName {
                prefix: Some("Rev."),
                given: None,
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: None,
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^John"),
            PersonName {
                prefix: None,
                given: Some("John"),
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams"),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^Robert^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^John^Robert^Rev.^B.A. M.Div."),
            PersonName {
                prefix: Some("Rev."),
                given: Some("John"),
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
    }
}
<commit_msg>- delete commented error declaration<commit_after>//! Handling of DICOM values with the VR PN (person name) as per PS3.5 sect 6.2.
use std::fmt::{Display, Formatter};
/// Represents a Dicom `PersonName` (PN).
/// Stores family, given, middle name, prefix and suffix as borrowed values.
/// All name components are optional.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PersonName<'a> {
    prefix: Option<&'a str>,
    family: Option<&'a str>,
    middle: Option<&'a str>,
    given: Option<&'a str>,
    suffix: Option<&'a str>,
}

/// A builder to construct a `PersonName` from it's components.
#[derive(Debug, Copy, Clone)]
pub struct PersonNameBuilder<'a> {
    person_name: PersonName<'a>,
}

impl Display for PersonName<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let components: &[Option<&str>] = &[
            self.prefix,
            self.given,
            self.middle,
            self.family,
            self.suffix,
        ];

        let mut c_iter = components.iter().flatten().peekable();

        while let Some(component) = c_iter.next() {
            if c_iter.peek().is_some() {
                write!(f, "{} ", component)?
            } else {
                write!(f, "{}", component)?
            }
        }
        Ok(())
    }
}

impl<'a> PersonName<'a> {
    /// Retrieve PersonName prefix
    pub fn prefix(&self) -> Option<&str> {
        self.prefix
    }
    /// Retrieve PersonName suffix
    pub fn suffix(&self) -> Option<&str> {
        self.suffix
    }
    /// Retrieve family name from PersonName
    pub fn family(&self) -> Option<&str> {
        self.family
    }
    /// Retrieve given name from PersonName
    pub fn given(&self) -> Option<&str> {
        self.given
    }
    /// Retrieve middle name from PersonName
    pub fn middle(&self) -> Option<&str> {
        self.middle
    }
    /// Convert PersonName into a Dicom formatted string.
    /// Name components are interspersed with a '^' separator.
    /// Leading null components produce a separator, while trailing do not.
    pub fn to_dicom_string(&self) -> String {
        let mut name = String::new();

        let components: &[Option<&str>] = &[
            self.family,
            self.given,
            self.middle,
            self.prefix,
            self.suffix,
        ];

        let mut it  = components.iter().rev().peekable();
        // consume trailing None (null) components
        while it.next_if(|component| component.is_none()).is_some(){}

        let mut it = it.rev().peekable();
        while let Some(option) = it.next() {
            if let Some(component) = option {
                name.push_str(component);
            }
            if it.peek().is_some() {
                name.push('^');
            }
        }

        name
    }
    /// Retrieves a PersonName from a Dicom formatted string slice.
    /// The Dicom string representation is split by '^' separator into its respective components.
    pub fn from_slice(slice: &'a str) -> PersonName<'a> {
        let mut parts = slice.split('^');

        macro_rules! get_component {
            () => {
                parts
                    .next()
                    .and_then(|s| if s.is_empty() { None } else { Some(s) })
            };
        }

        let family = get_component!();
        let given = get_component!();
        let middle = get_component!();
        let prefix = get_component!();
        let suffix = get_component!();

        PersonName {
            prefix,
            given,
            family,
            middle,
            suffix,
        }
    }
    /// Retrieve a builder for a PersonName
    pub fn builder() -> PersonNameBuilder<'a> {
        PersonNameBuilder::new()
    }
}

impl<'a> PersonNameBuilder<'a> {
    pub fn new() -> PersonNameBuilder<'a> {
        PersonNameBuilder {
            person_name: PersonName {
                prefix: None,
                family: None,
                middle: None,
                given: None,
                suffix: None,
            },
        }
    }
    /// Insert family name component
    pub fn with_family(mut self, family_name: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.family = Some(family_name);
        self
    }
    pub fn with_middle(mut self, middle_name: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.middle = Some(middle_name);
        self
    }
    pub fn with_given(mut self, given_name: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.given = Some(given_name);
        self
    }
    pub fn with_prefix(mut self, name_prefix: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.prefix = Some(name_prefix);
        self
    }
    pub fn with_suffix(mut self, name_suffix: &'a str) -> PersonNameBuilder<'a> {
        self.person_name.suffix = Some(name_suffix);
        self
    }
    /// Builds a PersonName
    pub fn build(&self) -> PersonName<'a> {
        self.person_name
    }
}

impl<'a> Default for PersonNameBuilder<'a> {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_person_name_to_dicom_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_dicom_string(), "^^^^B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^Rev.^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^Robert".to_string());
    }
    #[test]
    fn test_person_name_to_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Adams".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev.".to_string());

        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_string(),
            "Rev. John Robert Adams B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "John Robert Adams B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev. John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Robert".to_string());
    }
    #[test]
    fn person_name_from_slice() {
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^Rev."),
            PersonName {
                prefix: Some("Rev."),
                given: None,
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: None,
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^John"),
            PersonName {
                prefix: None,
                given: Some("John"),
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams"),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^Robert^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^John^Robert^Rev.^B.A. M.Div."),
            PersonName {
                prefix: Some("Rev."),
                given: Some("John"),
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
    }
}
<|endoftext|>


<commit_before>use support::{ResultTest,Tap,shell_writes};
use hamcrest::{assert_that};
use std::io::{MemWriter, BufWriter, IoResult};
use std::str::from_utf8_lossy;
use cargo::core::shell::{Shell,ShellConfig};
use term::{Terminal,TerminfoTerminal,color};

fn setup() {
}

fn writer(buf: &mut [u8]) -> Box<Writer> {
    box BufWriter::new(buf) as Box<Writer>
}

test!(non_tty {
    let config = ShellConfig { color: true, verbose: true, tty: false };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(color_explicitly_disabled {
    let config = ShellConfig { color: false, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(colored_shell {
    let config = ShellConfig { color: true, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(22, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes(colored_output("Hey Alex\n",
                                                       color::RED).assert()));
    });
})

fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
    let mut term: TerminfoTerminal<MemWriter> =
        Terminal::new(MemWriter::new()).assert();
    try!(term.reset());
    try!(term.fg(color));
    try!(term.write_str(string.as_slice()));
    try!(term.reset());
    try!(term.flush());
    Ok(from_utf8_lossy(term.get_ref().get_ref()).to_str())
}
<commit_msg>Fix a red test<commit_after>use support::{ResultTest,Tap,shell_writes};
use hamcrest::{assert_that};
use std::io::{MemWriter, BufWriter, IoResult};
use std::str::from_utf8_lossy;
use cargo::core::shell::{Shell,ShellConfig};
use term::{Terminal,TerminfoTerminal,color};

fn setup() {
}

fn writer(buf: &mut [u8]) -> Box<Writer> {
    box BufWriter::new(buf) as Box<Writer>
}

test!(non_tty {
    let config = ShellConfig { color: true, verbose: true, tty: false };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(color_explicitly_disabled {
    let config = ShellConfig { color: false, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(colored_shell {
    let config = ShellConfig { color: true, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(100, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        let buf = buf.as_slice().slice_to(buf.iter().position(|a| *a == 0).unwrap());
        assert_that(buf, shell_writes(colored_output("Hey Alex\n",
                                                     color::RED).assert()));
    });
})

fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
    let mut term: TerminfoTerminal<MemWriter> =
        Terminal::new(MemWriter::new()).assert();
    try!(term.reset());
    try!(term.fg(color));
    try!(term.write_str(string.as_slice()));
    try!(term.reset());
    try!(term.flush());
    Ok(from_utf8_lossy(term.get_ref().get_ref()).to_str())
}
<|endoftext|>


<commit_before>//! Main Playform client state code.

use cgmath::Point3;
use std::collections::HashMap;
use std::iter::range_inclusive;
use std::sync::Mutex;

use common::block_position::BlockPosition;
use common::communicate::ClientId;
use common::entity::EntityId;
use common::lod::LODIndex;
use common::surroundings_loader::SurroundingsLoader;
use common::terrain_block;
use common::terrain_block::TerrainBlock;

use terrain_buffers;

/// The distances at which LOD switches.
pub const LOD_THRESHOLDS: [i32; 3] = [1, 8, 32];

/// The main client state.
pub struct Client {
  #[allow(missing_docs)]
  pub id: ClientId,
  #[allow(missing_docs)]
  pub player_id: EntityId,
  #[allow(missing_docs)]
  pub player_position: Mutex<Point3<f32>>,
  #[allow(missing_docs)]
  pub max_load_distance: i32,
  #[allow(missing_docs)]
  pub surroundings_loader: Mutex<SurroundingsLoader>,
  /// A record of all the blocks that have been loaded.
  pub loaded_blocks: Mutex<HashMap<BlockPosition, (TerrainBlock, LODIndex)>>,
}

impl Client {
  #[allow(missing_docs)]
  pub fn new(client_id: ClientId, player_id: EntityId, position: Point3<f32>) -> Client {
    let mut load_distance = load_distance(terrain_buffers::POLYGON_BUDGET as i32);

    // TODO: Remove this once our RAM usage doesn't skyrocket with load distance.
    let max_load_distance = 1;
    if load_distance > max_load_distance {
      info!("load_distance {} capped at {}", load_distance, max_load_distance);
      load_distance = max_load_distance;
    } else {
      info!("load_distance {}", load_distance);
    }

    let surroundings_loader = {
      SurroundingsLoader::new(
        max_load_distance,
        LOD_THRESHOLDS.iter().map(|&x| x).collect(),
      )
    };

    Client {
      id: client_id,
      player_id: player_id,
      player_position: Mutex::new(position),
      max_load_distance: load_distance,
      surroundings_loader: Mutex::new(surroundings_loader),
      loaded_blocks: Mutex::new(HashMap::new()),
    }
  }
}

unsafe impl Sync for Client {}

fn load_distance(mut polygon_budget: i32) -> i32 {
  // TODO: This should try to account for VRAM not used on a per-poly basis.

  let mut load_distance = 0;
  let mut prev_threshold = 0;
  let mut prev_square = 0;
  for (&threshold, &quality) in LOD_THRESHOLDS.iter().zip(terrain_block::EDGE_SAMPLES.iter()) {
    let polygons_per_block = (quality * quality * 4) as i32;
    for i in range_inclusive(prev_threshold, threshold) {
      let i = 2 * i + 1;
      let square = i * i;
      let polygons_in_layer = (square - prev_square) * polygons_per_block;
      polygon_budget -= polygons_in_layer;
      if polygon_budget < 0 {
        break;
      }

      load_distance += 1;
      prev_square = square;
    }
    prev_threshold = threshold + 1;
  }

  let mut width = 2 * prev_threshold + 1;
  loop {
    let square = width * width;
    // The "to infinity and beyond" quality.
    let quality = terrain_block::EDGE_SAMPLES[LOD_THRESHOLDS.len()];
    let polygons_per_block = (quality * quality * 4) as i32;
    let polygons_in_layer = (square - prev_square) * polygons_per_block;
    polygon_budget -= polygons_in_layer;

    if polygon_budget < 0 {
      break;
    }

    width += 2;
    load_distance += 1;
    prev_square = square;
  }

  load_distance
}
<commit_msg>Load distance back to 80<commit_after>//! Main Playform client state code.

use cgmath::Point3;
use std::collections::HashMap;
use std::iter::range_inclusive;
use std::sync::Mutex;

use common::block_position::BlockPosition;
use common::communicate::ClientId;
use common::entity::EntityId;
use common::lod::LODIndex;
use common::surroundings_loader::SurroundingsLoader;
use common::terrain_block;
use common::terrain_block::TerrainBlock;

use terrain_buffers;

/// The distances at which LOD switches.
pub const LOD_THRESHOLDS: [i32; 3] = [1, 8, 32];

/// The main client state.
pub struct Client {
  #[allow(missing_docs)]
  pub id: ClientId,
  #[allow(missing_docs)]
  pub player_id: EntityId,
  #[allow(missing_docs)]
  pub player_position: Mutex<Point3<f32>>,
  #[allow(missing_docs)]
  pub max_load_distance: i32,
  #[allow(missing_docs)]
  pub surroundings_loader: Mutex<SurroundingsLoader>,
  /// A record of all the blocks that have been loaded.
  pub loaded_blocks: Mutex<HashMap<BlockPosition, (TerrainBlock, LODIndex)>>,
}

impl Client {
  #[allow(missing_docs)]
  pub fn new(client_id: ClientId, player_id: EntityId, position: Point3<f32>) -> Client {
    let mut load_distance = load_distance(terrain_buffers::POLYGON_BUDGET as i32);

    // TODO: Remove this once our RAM usage doesn't skyrocket with load distance.
    let max_load_distance = 80;
    if load_distance > max_load_distance {
      info!("load_distance {} capped at {}", load_distance, max_load_distance);
      load_distance = max_load_distance;
    } else {
      info!("load_distance {}", load_distance);
    }

    let surroundings_loader = {
      SurroundingsLoader::new(
        max_load_distance,
        LOD_THRESHOLDS.iter().map(|&x| x).collect(),
      )
    };

    Client {
      id: client_id,
      player_id: player_id,
      player_position: Mutex::new(position),
      max_load_distance: load_distance,
      surroundings_loader: Mutex::new(surroundings_loader),
      loaded_blocks: Mutex::new(HashMap::new()),
    }
  }
}

unsafe impl Sync for Client {}

fn load_distance(mut polygon_budget: i32) -> i32 {
  // TODO: This should try to account for VRAM not used on a per-poly basis.

  let mut load_distance = 0;
  let mut prev_threshold = 0;
  let mut prev_square = 0;
  for (&threshold, &quality) in LOD_THRESHOLDS.iter().zip(terrain_block::EDGE_SAMPLES.iter()) {
    let polygons_per_block = (quality * quality * 4) as i32;
    for i in range_inclusive(prev_threshold, threshold) {
      let i = 2 * i + 1;
      let square = i * i;
      let polygons_in_layer = (square - prev_square) * polygons_per_block;
      polygon_budget -= polygons_in_layer;
      if polygon_budget < 0 {
        break;
      }

      load_distance += 1;
      prev_square = square;
    }
    prev_threshold = threshold + 1;
  }

  let mut width = 2 * prev_threshold + 1;
  loop {
    let square = width * width;
    // The "to infinity and beyond" quality.
    let quality = terrain_block::EDGE_SAMPLES[LOD_THRESHOLDS.len()];
    let polygons_per_block = (quality * quality * 4) as i32;
    let polygons_in_layer = (square - prev_square) * polygons_per_block;
    polygon_budget -= polygons_in_layer;

    if polygon_budget < 0 {
      break;
    }

    width += 2;
    load_distance += 1;
    prev_square = square;
  }

  load_distance
}
<|endoftext|>