<commit_before>//! Client-side Wayland connector
//!
//! # Overview
//!
//! Connection to the Wayland compositor is achieved by
//! the `default_connect()` function, which provides you
//! with a `WlDisplay` and an `EventQueue`.
//!
//! From the display, you'll retrieve the registry, from
//! which you can instanciate the globals you need.
//!
//! You then register your handlers for events to the
//! event queue, and integrate it in your main event loop.
//!
//! # Handlers and event queues
//!
//! This crate mirrors the callback-oriented design of the
//! Wayland C library by using handler structs: each wayland
//! type defines a `Handler` trait in its module, which one
//! method for each possible event this object can receive.
//!
//! To use it, you need to build a struct (or enum) that will
//! implement all the traits for all the events you are interested
//! in. All methods of handler traits provide a default
//! implementation foing nothing, so you don't need to write
//! empty methods for events you want to ignore. You also need
//! to declare the handler capability for your struct using
//! the `declare_handler!(..)` macro. A single struct can be
//! handler for several wayland interfaces at once.
//!
//! ## Example of handler
//!
//! ```ignore
//! /*  writing a handler for an wl_foo interface */
//! // import the module of this interface
//! use wl_foo;
//!
//! struct MyHandler { /* some fields to store state */ }
//!
//! // implement handerl trait:
//! impl wl_foo::Handler for MyHandler {
//!     fn an_event(&mut self,
//!                 evqh: &mut EventQueueHandle,
//!                 me: &wl_foo::WlFoo,
//!                 arg1, arg2, // the actual args of the event
//!     ) {
//!         /* handle the event */
//!     }
//! }
//!
//! // declare the handler capability
//! // this boring step is necessary because Rust's type system is
//! // not yet magical enough
//! declare_handler!(MyHandler, wl_foo::Handler, wl_foo::WlFoo);
//! ```
//!
//! ## Event Queues and handlers
//!
//! In your initialization code, you'll need to instanciate
//! your handler and give it to the event queue:
//!
//! ```ignore
//! let handler_id = event_queue.add_handler(MyHandler::new());
//! ```
//!
//! Then, you can register your wayland objects to this handler:
//!
//! ```ignore
//! // This type info is necessary for safety, as at registration
//! // time the event_queue will check that the handler you
//! // specified using handler_id has the same type as provided
//! // as argument, and that this type implements the appropriate
//! // handler trait.
//! event_queue.register::<_, MyHandler>(&my_object, handler_id);
//! ```
//!
//! You can have several handlers in the same event queue,
//! but they cannot share their state without synchronisation
//! primitives like `Arc`, `Mutex` and friends, so if two handlers
//! need to share some state, you should consider building them
//! as a single struct.
//!
//! A given wayland object can only be registered to a single
//! handler at a given time, re-registering it to a new handler
//! will overwrite the previous configuration.
//!
//! Handlers can be created, and objects registered to them
//! from within a handler method, using the `&EventQueueHandle`
//! argument.
//!
//! ## Event loop integration
//!
//! Once this setup is done, you can integrate the event queue
//! to the main event loop of your program:
//!
//! ```ignore
//! loop {
//!     // flush events to the server
//!     display.flush().unwrap();
//!     // receive events from the server and dispatch them
//!     // to handlers (might block)
//!     event_queue.dispatch().unwrap();
//! }
//! ```
//!
//! For more precise control of the flow of the event queue
//! (and importantly non-blocking options), see `EventQueue`
//! documentation.
//!
//! # Protocols integration
//!
//! This crate provides the basic primitives as well as the
//! core wayland protocol (in the `protocol` module), but
//! other protocols can be integrated from XML descriptions.
//!
//! The the crate `wayland_scanner` and its documentation for
//! details about how to do so.

#![warn(missing_docs)]

#[macro_use] extern crate bitflags;
#[macro_use] extern crate wayland_sys;
extern crate libc;

pub use generated::client as protocol;

use wayland_sys::client::wl_proxy;
use wayland_sys::common::{wl_interface, wl_argument};

mod display;
mod event_queue;
mod env;

pub use event_queue::{EventQueue, EventQueueHandle, StateGuard};
pub use display::{default_connect, ConnectError, FatalError};
pub use env::{EnvHandler, EnvHandlerInner};

/// Common routines for wayland proxy objects.
///
/// All wayland objects automatically implement this trait
/// as generated by the scanner.
///
/// It is mostly used for internal use by the library, and you
/// should only need these methods for interfacing with C library
/// working on wayland objects.
pub trait Proxy {
    /// Pointer to the underlying wayland proxy object
    fn ptr(&self) -> *mut wl_proxy;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland proxy
    /// of the appropriate interface, but that have not
    /// yet been seen by the library.
    ///
    /// The library will take control of the object (notably
    /// overwrite its user_data).
    unsafe fn from_ptr_new(*mut wl_proxy) -> Self;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland proxy
    /// of the appropriate interface, and have already been
    /// initialized by the library (it'll assume this proxy
    /// user_data contains a certain kind of data).
    unsafe fn from_ptr_initialized(*mut wl_proxy) -> Self;
    /// Pointer to the interface representation
    fn interface_ptr() -> *const wl_interface;
    /// Internal wayland name of this interface
    fn interface_name() -> &'static str;
    /// Max version of this interface supported
    fn supported_version() -> u32;
    /// Current version of the interface this proxy is instanciated with
    fn version(&self) -> u32;
    /// Check if the proxt behind this handle is actually still alive
    fn is_alive(&self) -> bool;
}

/// Possible outcome of the call of a request on a proxy
pub enum RequestResult<T> {
    /// Message has been buffered and will be sent to server
    Sent(T),
    /// This proxy is already destroyed, request has been ignored
    Destroyed
}

impl<T> RequestResult<T> {
    /// Assert that result is successfull and extract the value.
    ///
    /// Panics with provided error message if the result was `Destroyed`.
    pub fn expect(self, error: &str) -> T {
        match self {
            RequestResult::Sent(v) => v,
            RequestResult::Destroyed => panic!("{}", error)
        }
    }
}

/// Generic handler trait
///
/// This trait is automatically implemented for objects that implement
/// the appropriate interface-specific `Handler` traits. It represents
/// the hability for a type to handle events directed to a given wayland
/// interface.
///
/// For example, implementing `wl_surface::Handler` for you type will
/// automatically provide it with an implementation of
/// `Handler<WlSurface>` as well. This is the only correct way
/// to implement this trait, and you should not attempt to implement it
/// yourself.
pub unsafe trait Handler<T: Proxy> {
    /// Dispatch a message.
    unsafe fn message(&mut self, evq: &mut EventQueueHandle, proxy: &T, opcode: u32, args: *const wl_argument) -> Result<(),()>;
}

mod generated {
    #![allow(dead_code,non_camel_case_types,unused_unsafe,unused_variables)]
    #![allow(non_upper_case_globals,non_snake_case,unused_imports)]
    #![allow(missing_docs)]

    pub mod interfaces {
        include!(concat!(env!("OUT_DIR"), "/wayland_interfaces.rs"));
    }

    pub mod client {
        //! The wayland core protocol
        //!
        //! This module contains all objects of the core wayland protocol.
        //!
        //! It has been generated from the `wayland.xml` protocol file
        //! using `wayland_scanner`.

        // Imports that need to be available to submodules
        // but should not be in public API.
        // Will be fixable with pub(restricted).
        #[doc(hidden)] pub use {Proxy, Handler, RequestResult};
        #[doc(hidden)] pub use event_queue::EventQueueHandle;
        #[doc(hidden)] pub use super::interfaces;
        include!(concat!(env!("OUT_DIR"), "/wayland_api.rs"));
    }
}

pub mod sys {
    //! Reexports of types and objects from wayland-sys
    pub use wayland_sys::common::*;
    pub use wayland_sys::client::*;
}
<commit_msg>client: mention EnvHandler in crate-level doc<commit_after>//! Client-side Wayland connector
//!
//! # Overview
//!
//! Connection to the Wayland compositor is achieved by
//! the `default_connect()` function, which provides you
//! with a `WlDisplay` and an `EventQueue`.
//!
//! From the display, you'll retrieve the registry, from
//! which you can instanciate the globals you need. This
//! step being really similar in most cases, this crate
//! contains an utility struct `EnvHandler` which can do
//! this job for you. See its documentation for details.
//!
//! You then register your handlers for events to the
//! event queue, and integrate it in your main event loop.
//!
//! # Handlers and event queues
//!
//! This crate mirrors the callback-oriented design of the
//! Wayland C library by using handler structs: each wayland
//! type defines a `Handler` trait in its module, which one
//! method for each possible event this object can receive.
//!
//! To use it, you need to build a struct (or enum) that will
//! implement all the traits for all the events you are interested
//! in. All methods of handler traits provide a default
//! implementation foing nothing, so you don't need to write
//! empty methods for events you want to ignore. You also need
//! to declare the handler capability for your struct using
//! the `declare_handler!(..)` macro. A single struct can be
//! handler for several wayland interfaces at once.
//!
//! ## Example of handler
//!
//! ```ignore
//! /*  writing a handler for an wl_foo interface */
//! // import the module of this interface
//! use wl_foo;
//!
//! struct MyHandler { /* some fields to store state */ }
//!
//! // implement handerl trait:
//! impl wl_foo::Handler for MyHandler {
//!     fn an_event(&mut self,
//!                 evqh: &mut EventQueueHandle,
//!                 me: &wl_foo::WlFoo,
//!                 arg1, arg2, // the actual args of the event
//!     ) {
//!         /* handle the event */
//!     }
//! }
//!
//! // declare the handler capability
//! // this boring step is necessary because Rust's type system is
//! // not yet magical enough
//! declare_handler!(MyHandler, wl_foo::Handler, wl_foo::WlFoo);
//! ```
//!
//! ## Event Queues and handlers
//!
//! In your initialization code, you'll need to instanciate
//! your handler and give it to the event queue:
//!
//! ```ignore
//! let handler_id = event_queue.add_handler(MyHandler::new());
//! ```
//!
//! Then, you can register your wayland objects to this handler:
//!
//! ```ignore
//! // This type info is necessary for safety, as at registration
//! // time the event_queue will check that the handler you
//! // specified using handler_id has the same type as provided
//! // as argument, and that this type implements the appropriate
//! // handler trait.
//! event_queue.register::<_, MyHandler>(&my_object, handler_id);
//! ```
//!
//! You can have several handlers in the same event queue,
//! but they cannot share their state without synchronisation
//! primitives like `Arc`, `Mutex` and friends, so if two handlers
//! need to share some state, you should consider building them
//! as a single struct.
//!
//! A given wayland object can only be registered to a single
//! handler at a given time, re-registering it to a new handler
//! will overwrite the previous configuration.
//!
//! Handlers can be created, and objects registered to them
//! from within a handler method, using the `&EventQueueHandle`
//! argument.
//!
//! ## Event loop integration
//!
//! Once this setup is done, you can integrate the event queue
//! to the main event loop of your program:
//!
//! ```ignore
//! loop {
//!     // flush events to the server
//!     display.flush().unwrap();
//!     // receive events from the server and dispatch them
//!     // to handlers (might block)
//!     event_queue.dispatch().unwrap();
//! }
//! ```
//!
//! For more precise control of the flow of the event queue
//! (and importantly non-blocking options), see `EventQueue`
//! documentation.
//!
//! # Protocols integration
//!
//! This crate provides the basic primitives as well as the
//! core wayland protocol (in the `protocol` module), but
//! other protocols can be integrated from XML descriptions.
//!
//! The the crate `wayland_scanner` and its documentation for
//! details about how to do so.

#![warn(missing_docs)]

#[macro_use] extern crate bitflags;
#[macro_use] extern crate wayland_sys;
extern crate libc;

pub use generated::client as protocol;

use wayland_sys::client::wl_proxy;
use wayland_sys::common::{wl_interface, wl_argument};

mod display;
mod event_queue;
mod env;

pub use event_queue::{EventQueue, EventQueueHandle, StateGuard};
pub use display::{default_connect, ConnectError, FatalError};
pub use env::{EnvHandler, EnvHandlerInner};

/// Common routines for wayland proxy objects.
///
/// All wayland objects automatically implement this trait
/// as generated by the scanner.
///
/// It is mostly used for internal use by the library, and you
/// should only need these methods for interfacing with C library
/// working on wayland objects.
pub trait Proxy {
    /// Pointer to the underlying wayland proxy object
    fn ptr(&self) -> *mut wl_proxy;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland proxy
    /// of the appropriate interface, but that have not
    /// yet been seen by the library.
    ///
    /// The library will take control of the object (notably
    /// overwrite its user_data).
    unsafe fn from_ptr_new(*mut wl_proxy) -> Self;
    /// Create an instance from a wayland pointer
    ///
    /// The pointer must refer to a valid wayland proxy
    /// of the appropriate interface, and have already been
    /// initialized by the library (it'll assume this proxy
    /// user_data contains a certain kind of data).
    unsafe fn from_ptr_initialized(*mut wl_proxy) -> Self;
    /// Pointer to the interface representation
    fn interface_ptr() -> *const wl_interface;
    /// Internal wayland name of this interface
    fn interface_name() -> &'static str;
    /// Max version of this interface supported
    fn supported_version() -> u32;
    /// Current version of the interface this proxy is instanciated with
    fn version(&self) -> u32;
    /// Check if the proxt behind this handle is actually still alive
    fn is_alive(&self) -> bool;
}

/// Possible outcome of the call of a request on a proxy
pub enum RequestResult<T> {
    /// Message has been buffered and will be sent to server
    Sent(T),
    /// This proxy is already destroyed, request has been ignored
    Destroyed
}

impl<T> RequestResult<T> {
    /// Assert that result is successfull and extract the value.
    ///
    /// Panics with provided error message if the result was `Destroyed`.
    pub fn expect(self, error: &str) -> T {
        match self {
            RequestResult::Sent(v) => v,
            RequestResult::Destroyed => panic!("{}", error)
        }
    }
}

/// Generic handler trait
///
/// This trait is automatically implemented for objects that implement
/// the appropriate interface-specific `Handler` traits. It represents
/// the hability for a type to handle events directed to a given wayland
/// interface.
///
/// For example, implementing `wl_surface::Handler` for you type will
/// automatically provide it with an implementation of
/// `Handler<WlSurface>` as well. This is the only correct way
/// to implement this trait, and you should not attempt to implement it
/// yourself.
pub unsafe trait Handler<T: Proxy> {
    /// Dispatch a message.
    unsafe fn message(&mut self, evq: &mut EventQueueHandle, proxy: &T, opcode: u32, args: *const wl_argument) -> Result<(),()>;
}

mod generated {
    #![allow(dead_code,non_camel_case_types,unused_unsafe,unused_variables)]
    #![allow(non_upper_case_globals,non_snake_case,unused_imports)]
    #![allow(missing_docs)]

    pub mod interfaces {
        include!(concat!(env!("OUT_DIR"), "/wayland_interfaces.rs"));
    }

    pub mod client {
        //! The wayland core protocol
        //!
        //! This module contains all objects of the core wayland protocol.
        //!
        //! It has been generated from the `wayland.xml` protocol file
        //! using `wayland_scanner`.

        // Imports that need to be available to submodules
        // but should not be in public API.
        // Will be fixable with pub(restricted).
        #[doc(hidden)] pub use {Proxy, Handler, RequestResult};
        #[doc(hidden)] pub use event_queue::EventQueueHandle;
        #[doc(hidden)] pub use super::interfaces;
        include!(concat!(env!("OUT_DIR"), "/wayland_api.rs"));
    }
}

pub mod sys {
    //! Reexports of types and objects from wayland-sys
    pub use wayland_sys::common::*;
    pub use wayland_sys::client::*;
}
<|endoftext|>


<commit_before>use std::ops::{Mul, Add, Div, Sub, Index};

struct Matrix {
	cols: usize,
	rows: usize,
	data: Vec<f32>
}

impl Matrix {
    fn new(cols: usize, rows: usize, data: Vec<f32>) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    fn zeros(cols: usize, rows: usize) -> Matrix {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols*rows]
        }
    }

    fn identity(size: usize) -> Matrix {
    	let mut data = Vec::with_capacity(size * size);

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = 1.0;
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn from_diag(diag: &Vec<f32>) -> Matrix {
    	let size = diag.len();
    	let mut data = Vec::with_capacity(size * size);

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }
}

impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, m: f32) -> Matrix {
        let new_data = self.data.into_iter().map(|v| v * m).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Mul<Matrix> for Matrix {
	type Output = Matrix;

	fn mul(self, m: Matrix) -> Matrix {
		// Will use Strassen algorithm if large, traditional otherwise
		return self;
	}
}

impl Add<f32> for Matrix {
	type Output = Matrix;

	fn add(self, m: f32) -> Matrix {
		for entry in &self.data {
			entry + m;
		}

		return self;
	}
}

impl Add<Matrix> for Matrix {
	type Output = Matrix;

	fn add(self, m: Matrix) -> Matrix {
		return self;
	}
}

impl Div<f32> for Matrix {
	type Output = Matrix;

	fn div(self, f: f32) -> Matrix {
		return self;
	}
}<commit_msg>Fixing vector initialization.<commit_after>use std::ops::{Mul, Add, Div, Sub, Index};

struct Matrix {
	cols: usize,
	rows: usize,
	data: Vec<f32>
}

impl Matrix {
    fn new(cols: usize, rows: usize, data: Vec<f32>) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: data
        }
    }

    fn zeros(cols: usize, rows: usize) -> Matrix {
    	Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols*rows]
        }
    }

    fn identity(size: usize) -> Matrix {
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = 1.0;
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }

    fn from_diag(diag: &Vec<f32>) -> Matrix {
    	let size = diag.len();
    	let mut data = vec![0.0; size * size];

    	for i in 0..size
    	{
    		data[(i*(size+1)) as usize] = diag[i];
    	}

    	Matrix {
            cols: size,
            rows: size,
            data: data
        }
    }
}

impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, m: f32) -> Matrix {
        let new_data = self.data.into_iter().map(|v| v * m).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

impl Mul<Matrix> for Matrix {
	type Output = Matrix;

	fn mul(self, m: Matrix) -> Matrix {
		// Will use Strassen algorithm if large, traditional otherwise
		return self;
	}
}

impl Add<f32> for Matrix {
	type Output = Matrix;

	fn add(self, m: f32) -> Matrix {
		for entry in &self.data {
			entry + m;
		}

		return self;
	}
}

impl Add<Matrix> for Matrix {
	type Output = Matrix;

	fn add(self, m: Matrix) -> Matrix {
		return self;
	}
}

impl Div<f32> for Matrix {
	type Output = Matrix;

	fn div(self, f: f32) -> Matrix {
		return self;
	}
}<|endoftext|>


<commit_before>//! Encapsulates logic required for updating the Habitat Supervisor
//! itself.

use crate::{env,
            util};
use habitat_common::command::package::install::InstallSource;
use habitat_core::{package::{PackageIdent,
                             PackageInstall},
                   ChannelIdent};
use std::time::Duration;
use time::{Duration as TimeDuration,
           SteadyTime};
use tokio::{self,
            sync::oneshot::{self,
                            error::TryRecvError,
                            Receiver,
                            Sender},
            time as tokiotime};

pub const SUP_PKG_IDENT: &str = "core/hab-sup";
const DEFAULT_FREQUENCY: i64 = 60_000;
const FREQUENCY_ENVVAR: &str = "HAB_SUP_UPDATE_MS";

pub struct SelfUpdater {
    rx:             Receiver<PackageInstall>,
    current:        PackageIdent,
    update_url:     String,
    update_channel: ChannelIdent,
}

// TODO (CM): Want to use the Periodic trait here, but can't due to
// how things are currently structured (The service updater had a worker)

impl SelfUpdater {
    pub fn new(current: PackageIdent, update_url: String, update_channel: ChannelIdent) -> Self {
        let rx = Self::init(current.clone(), update_url.clone(), update_channel.clone());
        SelfUpdater { rx,
                      current,
                      update_url,
                      update_channel }
    }

    /// Spawn a new Supervisor updater thread.
    fn init(current: PackageIdent,
            update_url: String,
            update_channel: ChannelIdent)
            -> Receiver<PackageInstall> {
        let (tx, rx) = oneshot::channel();
        tokio::spawn(Self::run(tx, current, update_url, update_channel));
        rx
    }

    async fn run(tx: Sender<PackageInstall>,
                 current: PackageIdent,
                 update_url: String,
                 update_channel: ChannelIdent) {
        debug!("Self updater current package, {}", current);
        // SUP_PKG_IDENT will always parse as a valid PackageIdent,
        // and thus a valid InstallSource
        let install_source: InstallSource = SUP_PKG_IDENT.parse().unwrap();
        loop {
            let next_check = SteadyTime::now() + TimeDuration::milliseconds(update_frequency());

            match util::pkg::install_no_ui(&update_url, &install_source, &update_channel).await {
                Ok(package) => {
                    if &current < package.ident() {
                        debug!("Self updater installing newer Supervisor, {}",
                               package.ident());
                        tx.send(package).expect("Main thread has gone away!");
                        break;
                    } else {
                        debug!("Supervisor package found is not newer than ours");
                    }
                }
                Err(err) => {
                    warn!("Self updater failed to get latest, {}", err);
                }
            }

            let time_to_wait = (next_check - SteadyTime::now()).num_milliseconds();
            if time_to_wait > 0 {
                tokiotime::delay_for(Duration::from_millis(time_to_wait as u64)).await;
            }
        }
    }

    pub async fn updated(&mut self) -> Option<PackageInstall> {
        match self.rx.try_recv() {
            Ok(package) => Some(package),
            Err(TryRecvError::Empty) => None,
            Err(TryRecvError::Closed) => {
                debug!("Self updater has died, restarting...");
                self.rx = Self::init(self.current.clone(),
                                     self.update_url.clone(),
                                     self.update_channel.clone());
                None
            }
        }
    }
}

fn update_frequency() -> i64 {
    match env::var(FREQUENCY_ENVVAR) {
        Ok(val) => val.parse::<i64>().unwrap_or(DEFAULT_FREQUENCY),
        Err(_) => DEFAULT_FREQUENCY,
    }
}
<commit_msg>Use env_config_duration in self updater<commit_after>//! Encapsulates logic required for updating the Habitat Supervisor
//! itself.

use crate::util;
use habitat_common::command::package::install::InstallSource;
use habitat_core::{package::{PackageIdent,
                             PackageInstall},
                   ChannelIdent};
use std::time::Duration;
use tokio::{self,
            sync::oneshot::{self,
                            error::TryRecvError,
                            Receiver,
                            Sender},
            time as tokiotime};

pub const SUP_PKG_IDENT: &str = "core/hab-sup";
const DEFAULT_PERIOD: Duration = Duration::from_secs(60);

habitat_core::env_config_duration!(
    /// Represents how far apart checks for updates are, in milliseconds.
    SelfUpdatePeriod,
    HAB_SUP_UPDATE_MS => from_millis,
    DEFAULT_PERIOD);

pub struct SelfUpdater {
    rx:             Receiver<PackageInstall>,
    current:        PackageIdent,
    update_url:     String,
    update_channel: ChannelIdent,
}

// TODO (CM): Want to use the Periodic trait here, but can't due to
// how things are currently structured (The service updater had a worker)

impl SelfUpdater {
    pub fn new(current: PackageIdent, update_url: String, update_channel: ChannelIdent) -> Self {
        let rx = Self::init(current.clone(), update_url.clone(), update_channel.clone());
        SelfUpdater { rx,
                      current,
                      update_url,
                      update_channel }
    }

    /// Spawn a new Supervisor updater thread.
    fn init(current: PackageIdent,
            update_url: String,
            update_channel: ChannelIdent)
            -> Receiver<PackageInstall> {
        let (tx, rx) = oneshot::channel();
        tokio::spawn(Self::run(tx, current, update_url, update_channel));
        rx
    }

    async fn run(tx: Sender<PackageInstall>,
                 current: PackageIdent,
                 update_url: String,
                 update_channel: ChannelIdent) {
        debug!("Self updater current package, {}", current);
        // SUP_PKG_IDENT will always parse as a valid PackageIdent,
        // and thus a valid InstallSource
        let install_source: InstallSource = SUP_PKG_IDENT.parse().unwrap();
        let delay = SelfUpdatePeriod::configured_value().into();
        loop {
            match util::pkg::install_no_ui(&update_url, &install_source, &update_channel).await {
                Ok(package) => {
                    if &current < package.ident() {
                        debug!("Self updater installing newer Supervisor, {}",
                               package.ident());
                        tx.send(package).expect("Main thread has gone away!");
                        break;
                    } else {
                        debug!("Supervisor package found is not newer than ours");
                    }
                }
                Err(err) => {
                    warn!("Self updater failed to get latest, {}", err);
                }
            }
            tokiotime::delay_for(delay).await;
        }
    }

    pub async fn updated(&mut self) -> Option<PackageInstall> {
        match self.rx.try_recv() {
            Ok(package) => Some(package),
            Err(TryRecvError::Empty) => None,
            Err(TryRecvError::Closed) => {
                debug!("Self updater has died, restarting...");
                self.rx = Self::init(self.current.clone(),
                                     self.update_url.clone(),
                                     self.update_channel.clone());
                None
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate lopdf;
use lopdf::xobject;
use lopdf::Document;
use std::str::FromStr;

fn convert_number_to_bits<T: std::fmt::Binary>(num: T, size: usize) -> Vec<u8> {
	let bin = format!("{:b}", num);
	let pad = "0".repeat(size - bin.len());
	let mut bytes = (pad + &bin).into_bytes();
	bytes.reverse();
	bytes
}

fn generate_barcode(page: u32, code: u16) -> Vec<(f64, f64, f64, f64, u8)> {
	assert!(page > 0 && page <= 255, "页码超出了取值范围1-255");
	assert!(code <= 511, "代码超出了取值范围0-511");
	let page_bits = convert_number_to_bits(page, 8);
	let code_bits = convert_number_to_bits(code, 9);
	let mut rects = vec![];
	let mut x = 0.0;
	let y = 0.0;
	let w = 9.0;
	let h = 10.0;
	{
		let mut add_flag = |w, bit| {
			rects.push((x, y, w, h, bit));
			x += w;
		};
		add_flag(w, b'0');
		for bit in page_bits {
			add_flag(w, bit);
		}
		add_flag(w, code_bits[0]);
		add_flag(6.53, b'0');
		add_flag(w, code_bits[1]);
		add_flag(w, code_bits[2]);
		add_flag(w, code_bits[3]);
		add_flag(w, code_bits[4]);
		add_flag(w, b'1');
		add_flag(w, b'0');
		add_flag(w, code_bits[5]);
		add_flag(w, code_bits[6]);
		add_flag(w, code_bits[7]);
		add_flag(w, code_bits[8]);
	}
	return rects;
}

fn generate_operations(rects: Vec<(f64, f64, f64, f64, u8)>) -> String {
	let mut operations = String::new();
	let mut current_color = b'\0';
	for (x, y, w, h, bit) in rects {
		if bit != current_color {
			operations.push_str(match bit {
				b'0' => "1 1 1 rg\n",
				b'1' => "0 0 0 rg\n",
				_ => "\n",
			});
			current_color = bit;
		}
		operations.push_str(&format!("{} {} {} {} re\nf\n", x, y, w, h));
	}
	operations
}

#[allow(non_upper_case_globals)]
const mm2pt: f64 = 2.834;

fn main() {
	let args: Vec<String> = std::env::args().collect();
	assert!(args.len() == 4, "缺少命令行参数");
	let pdf_file = &args[1];
	let code = u16::from_str(&args[2]).expect("error in parsing code argument");
	let output_file = &args[3];
	let mut doc = Document::load(pdf_file).unwrap();
	for (page_number, page_id) in doc.get_pages() {
		let operations = generate_operations(generate_barcode(page_number, code));
		let barcode = xobject::form(
			vec![0.0, 0.0, 595.0 - 12.44 * mm2pt * 2.0, 10.0 * mm2pt],
			vec![mm2pt, 0.0, 0.0, mm2pt, 12.44 * mm2pt, 842.0 - 14.53 * mm2pt],
			operations.as_bytes().to_vec(),
		);
		doc.insert_form_object(page_id, barcode);
	}
	doc.save(output_file).unwrap();
}
<commit_msg>Update example<commit_after>extern crate lopdf;
use lopdf::xobject;
use lopdf::Document;
use std::str::FromStr;

fn convert_number_to_bits<T: std::fmt::Binary>(num: T, size: usize) -> Vec<u8> {
	let bin = format!("{:b}", num);
	let pad = "0".repeat(size - bin.len());
	let mut bytes = (pad + &bin).into_bytes();
	bytes.reverse();
	bytes
}

fn generate_barcode(page: u32, code: u16) -> Vec<(f64, f64, f64, f64, u8)> {
	assert!(page > 0 && page <= 255, "Page number should within range: 1-255");
	assert!(code <= 511, "Bar code should within range: 0-511");
	let page_bits = convert_number_to_bits(page, 8);
	let code_bits = convert_number_to_bits(code, 9);
	let mut rects = vec![];
	let mut x = 0.0;
	let y = 0.0;
	let w = 9.0;
	let h = 10.0;
	{
		let mut add_flag = |w, bit| {
			rects.push((x, y, w, h, bit));
			x += w;
		};
		add_flag(w, b'0');
		for bit in page_bits {
			add_flag(w, bit);
		}
		add_flag(w, code_bits[0]);
		add_flag(6.53, b'0');
		add_flag(w, code_bits[1]);
		add_flag(w, code_bits[2]);
		add_flag(w, code_bits[3]);
		add_flag(w, code_bits[4]);
		add_flag(w, b'1');
		add_flag(w, b'0');
		add_flag(w, code_bits[5]);
		add_flag(w, code_bits[6]);
		add_flag(w, code_bits[7]);
		add_flag(w, code_bits[8]);
	}
	return rects;
}

fn generate_operations(rects: Vec<(f64, f64, f64, f64, u8)>) -> String {
	let mut operations = String::new();
	let mut current_color = b'\0';
	for (x, y, w, h, bit) in rects {
		if bit != current_color {
			operations.push_str(match bit {
				b'0' => "1 1 1 rg\n",
				b'1' => "0 0 0 rg\n",
				_ => "\n",
			});
			current_color = bit;
		}
		operations.push_str(&format!("{} {} {} {} re\nf\n", x, y, w, h));
	}
	operations
}

#[allow(non_upper_case_globals)]
const mm2pt: f64 = 2.834;

fn main() {
	let args: Vec<String> = std::env::args().collect();
	assert!(args.len() == 4, "Not enough arguments: pdf_file bar_code output_file");
	let pdf_file = &args[1];
	let code = u16::from_str(&args[2]).expect("error in parsing code argument");
	let output_file = &args[3];
	let mut doc = Document::load(pdf_file).unwrap();
	for (page_number, page_id) in doc.get_pages() {
		let operations = generate_operations(generate_barcode(page_number, code));
		let barcode = xobject::form(
			vec![0.0, 0.0, 595.0 - 12.44 * mm2pt * 2.0, 10.0 * mm2pt],
			vec![mm2pt, 0.0, 0.0, mm2pt, 12.44 * mm2pt, 842.0 - 14.53 * mm2pt],
			operations.as_bytes().to_vec(),
		);
		doc.insert_form_object(page_id, barcode);
	}
	doc.save(output_file).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>modify update to support insert_or_update<commit_after><|endoftext|>


<commit_before>//! Data types and utility function for units:
//! Implemet a poor man's unit type system for now...
//!
//! Maybe we can have s.th. like this (F#) for Rust: https://en.wikibooks.org/wiki/F_Sharp_Programming/Units_of_Measure
//! Alternatively, see here:
//! https://www.reddit.com/r/rust/comments/37qut9/typesafe_userdefined_units_of_measure_for_rust/
//! https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/

use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use std::cmp::PartialEq;

#[derive(Debug)]
pub struct Meter(pub f64);

impl PartialEq for Meter {
    fn eq(self: &Meter, &Meter(rhs): &Meter) -> bool {
        let Meter(lhs) = *self;
        lhs == rhs
    }
}

impl Add for Meter {
    type Output = Meter;

    fn add(self: Meter, Meter(rhs): Meter) -> Meter {
        let Meter(lhs) = self;
        Meter(lhs + rhs)
    }
}

impl Sub for Meter {
    type Output = Meter;

    fn sub(self: Meter, Meter(rhs): Meter) -> Meter {
        let Meter(lhs) = self;
        Meter(lhs - rhs)
    }
}

impl Mul<Meter> for Meter {
    type Output = Meter2;

    fn mul(self: Meter, Meter(rhs): Meter) -> Meter2 {
        let Meter(lhs) = self;
        Meter2(lhs * rhs)
    }
}

impl Mul<f64> for Meter {
    type Output = Meter;

    fn mul(self: Meter, rhs: f64) -> Meter {
        let Meter(lhs) = self;
        Meter(lhs * rhs)
    }
}

impl Div<Meter> for Meter {
    type Output = f64;

    fn div(self: Meter, Meter(rhs): Meter) -> f64 {
        let Meter(lhs) = self;
        lhs / rhs
    }
}

impl Div<Second> for Meter {
    type Output = MeterPerSecond;

    fn div(self: Meter, Second(rhs): Second) -> MeterPerSecond {
        let Meter(lhs) = self;
        MeterPerSecond(lhs / rhs)
    }
}

#[derive(Debug)]
pub struct Meter2(pub f64);

impl PartialEq for Meter2 {
    fn eq(self: &Meter2, &Meter2(rhs): &Meter2) -> bool {
        let Meter2(lhs) = *self;
        lhs == rhs
    }
}

#[derive(Debug)]
pub struct Second(pub f64);

impl Add for Second {
    type Output = Second;

    fn add(self: Second, Second(rhs): Second) -> Second {
        let Second(lhs) = self;
        Second(lhs + rhs)
    }
}

impl Sub for Second {
    type Output = Second;

    fn sub(self: Second, Second(rhs): Second) -> Second {
        let Second(lhs) = self;
        Second(lhs - rhs)
    }
}

impl Mul<Second> for Second {
    type Output = Second2;

    fn mul(self: Second, Second(rhs): Second) -> Second2 {
        let Second(lhs) = self;
        Second2(lhs * rhs)
    }
}

impl Mul<f64> for Second {
    type Output = Second;

    fn mul(self: Second, rhs: f64) -> Second {
        let Second(lhs) = self;
        Second(lhs * rhs)
    }
}

impl Div<Second> for Second {
    type Output = f64;

    fn div(self: Second, Second(rhs): Second) -> f64 {
        let Second(lhs) = self;
        lhs / rhs
    }
}

#[derive(Debug)]
pub struct Second2(pub f64);

#[derive(Debug)]
pub struct MeterPerSecond(pub f64);

impl PartialEq for MeterPerSecond {
    fn eq(self: &MeterPerSecond, &MeterPerSecond(rhs): &MeterPerSecond) -> bool {
        let MeterPerSecond(lhs) = *self;
        lhs == rhs
    }
}

impl Add for MeterPerSecond {
    type Output = MeterPerSecond;

    fn add(self: MeterPerSecond, MeterPerSecond(rhs): MeterPerSecond) -> MeterPerSecond {
        let MeterPerSecond(lhs) = self;
        MeterPerSecond(lhs + rhs)
    }
}

impl Sub for MeterPerSecond {
    type Output = MeterPerSecond;

    fn sub(self: MeterPerSecond, MeterPerSecond(rhs): MeterPerSecond) -> MeterPerSecond {
        let MeterPerSecond(lhs) = self;
        MeterPerSecond(lhs - rhs)
    }
}

impl Mul<Second> for MeterPerSecond {
    type Output = Meter;

    fn mul(self: MeterPerSecond, Second(rhs): Second) -> Meter {
        let MeterPerSecond(lhs) = self;
        Meter(lhs * rhs)
    }
}
<commit_msg>add macros to simplify unit creation<commit_after>//! Data types and utility function for units:
//! Implemet a poor man's unit type system for now...
//!
//! Maybe we can have s.th. like this (F#) for Rust: https://en.wikibooks.org/wiki/F_Sharp_Programming/Units_of_Measure
//! Alternatively, see here:
//! https://www.reddit.com/r/rust/comments/37qut9/typesafe_userdefined_units_of_measure_for_rust/
//! https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/

use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use std::cmp::PartialEq;

macro_rules! init_unit {
    ($i:ident) => {
        #[derive(Debug)]
        pub struct $i(pub f64);

        impl PartialEq for $i {
            fn eq(self: &$i, &$i(rhs): &$i) -> bool {
                let $i(lhs) = *self;
                lhs == rhs
            }
        }

        impl Add for $i {
            type Output = $i;

            fn add(self: $i, $i(rhs): $i) -> $i {
                let $i(lhs) = self;
                $i(lhs + rhs)
            }
        }

        impl Sub for $i {
            type Output = $i;

            fn sub(self: $i, $i(rhs): $i) -> $i {
                let $i(lhs) = self;
                $i(lhs - rhs)
            }
        }

        impl Mul<f64> for $i {
            type Output = $i;

            fn mul(self: $i, rhs: f64) -> $i {
                let $i(lhs) = self;
                $i(lhs * rhs)
            }
        }

        impl Div<f64> for $i {
            type Output = $i;

            fn div(self: $i, rhs: f64) -> $i {
                let $i(lhs) = self;
                $i(lhs / rhs)
            }
        }

        impl Div<$i> for $i {
            type Output = f64;

            fn div(self: $i, $i(rhs): $i) -> f64 {
                let $i(lhs) = self;
                lhs / rhs
            }
        }
    }
}

macro_rules! mul_unit {
    ($i1:ident, $i2:ident, $i3:ident) => {
        impl Mul<$i2> for $i1 {
            type Output = $i3;

            fn mul(self: $i1, $i2(rhs): $i2) -> $i3 {
                let $i1(lhs) = self;
                $i3(lhs * rhs)
            }
        }
    }
}

macro_rules! div_unit {
    ($i1:ident, $i2:ident, $i3:ident) => {
        impl Div<$i2> for $i1 {
            type Output = $i3;

            fn div(self: $i1, $i2(rhs): $i2) -> $i3 {
                let $i1(lhs) = self;
                $i3(lhs / rhs)
            }
        }
    }
}

init_unit!(Meter);

init_unit!(Meter2);

mul_unit!(Meter, Meter, Meter2);

init_unit!(Second);

init_unit!(Second2);

mul_unit!(Second, Second, Second2);

init_unit!(MeterPerSecond);

div_unit!(Meter, Second, MeterPerSecond);

mul_unit!(MeterPerSecond, Second, Meter);
<|endoftext|>


<commit_before>use std::ops::Deref;
use std::ops::DerefMut;
use std::cmp;

use game::*;
use behaviour::LeafResolution;
use direction::Direction;
use coord::{Coord, StraightLine};

pub fn player_input<K: KnowledgeRenderer, I: 'static + InputSource + Clone>(input_source: I) -> BehaviourLeaf<K> {
    BehaviourLeaf::new(move |input| {
        loop {
            if let Some(meta_action) = get_meta_action(input, input_source.clone()) {
                return LeafResolution::Yield(meta_action);
            }
        }
    })
}

fn get_direction<I: InputSource>(map: &ControlMap, mut input_source: I) -> Option<Direction> {
    input_source.next_input().and_then(|event| {
        map.control(event).and_then(|control| {
            control_to_direction(control)
        })
    })
}

fn control_to_direction(control: Control) -> Option<Direction> {
    match control {
        Control::Direction(d) => Some(d),
        _ => None,
    }
}

fn aim<R: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<R>, map: &ControlMap, mut input_source: I) -> Option<Coord> {
    let start = input.entity.position().unwrap();
    let mut knowledge = input.entity.drawable_knowledge_borrow_mut().unwrap();
    let level_knowledge = knowledge.level_mut_or_insert_size(input.level_id,
                                                             input.spatial_hash.width(),
                                                             input.spatial_hash.height());

    let targets = level_knowledge.sort_targets(start);
    let mut target_idx = 0;

    let mut end = if !targets.is_empty() {
        targets[target_idx]
    } else {
        start
    };

    let mut renderer = input.renderer.borrow_mut();

    loop {

        let overlay = RenderOverlay::aim_line(StraightLine::new(start, end));
        renderer.draw_with_overlay(&overlay);

        if let Some(event) = input_source.next_input() {
            if let Some(control) = map.control(event) {
                if let Some(direction) = control_to_direction(control) {
                    let next_end = end + direction.vector();
                    if renderer.contains_world_coord(next_end) {
                        end = next_end;
                    }
                } else if control == Control::NextTarget {
                    if !targets.is_empty() {
                        target_idx = (target_idx + 1) % targets.len();
                        end = targets[target_idx];
                    }
                } else if control == Control::PrevTarget {
                    if !targets.is_empty() {
                        target_idx = (target_idx + targets.len() - 1) % targets.len();
                        end = targets[target_idx];
                    }
                } else if control == Control::Fire {
                    renderer.draw();
                    return Some(end);
                } else {
                    break;
                }
            } else {
                break;
            }
        }
    }

    renderer.draw();
    None
}

fn display_message_log<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I, map: &ControlMap) {

    let mut renderer = input.renderer.borrow_mut();
    let message_log = input.entity.message_log_borrow().unwrap();

    let mut offset = 0;
    let num_lines = renderer.display_log_num_lines();
    let num_messages = message_log.len();
    let max_offset = if num_messages > num_lines {
        num_messages - num_lines
    } else {
        0
    };

    loop {
        renderer.display_log(message_log.deref(), offset, input.language);

        if let Some(event) = input_source.next_input() {
            if let Some(control) = map.control(event) {
                match control {
                    Control::Quit |
                        Control::DisplayMessageLog => break,
                    Control::Direction(Direction::North) => {
                        offset = cmp::min(max_offset, offset + 1);
                    }
                    Control::Direction(Direction::South) => {
                        if offset > 0 {
                            offset -= 1;
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    renderer.draw();
}

fn examine<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I, map: &ControlMap) {

    let mut knowledge = input.entity.drawable_knowledge_borrow_mut().unwrap();
    let level_knowledge = knowledge.level_mut_or_insert_size(input.level_id,
                                                             input.spatial_hash.width(),
                                                             input.spatial_hash.height());

    let mut renderer = input.renderer.borrow_mut();
    let mut message_log = input.entity.message_log_borrow_mut().unwrap();
    let position = input.entity.position().unwrap();

    let mut cursor = position;
    let mut alternative_message = false;

    loop {

        let cell = level_knowledge.get_with_default(cursor);

        if alternative_message {
            alternative_message = false;
        } else {
            let message = if cell.last_updated() == input.action_env.id {
                MessageType::YouSee(cell.you_see())
            } else if cell.last_updated() == 0 {
                MessageType::Unseen
            } else {
                MessageType::YouRemember(cell.you_see())
            };

            message_log.add_temporary(message);
            renderer.update_log(message_log.deref(), input.language);
        }

        let overlay = RenderOverlay::examine_cursor(cursor);
        renderer.draw_with_overlay(&overlay);

        if let Some(event) = input_source.next_input() {
            if let Some(control) = map.control(event) {
                match control {
                    Control::Quit |
                        Control::Examine => break,
                    Control::Direction(direction) => {
                        cursor += direction.vector();
                    }
                    Control::Select => {
                        let message = if let Some(description) = cell.description() {
                            MessageType::Description(description)
                        } else if let Some(you_see) = cell.you_see() {
                            MessageType::YouSeeDescription(you_see)
                        } else {
                            message_log.add_temporary(MessageType::NoDescription);
                            renderer.update_log(message_log.deref(), input.language);
                            alternative_message = true;
                            continue;
                        };

                        renderer.display_message_fullscreen(message, input.language);
                        input_source.next_input();
                    }
                    _ => {}
                }
            }
        }
    }

    message_log.add_temporary(MessageType::Empty);
    renderer.update_log(message_log.deref(), input.language);
    renderer.draw();
}

fn display_help<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I, map: &ControlMap) {
    let mut message = Message::new();
    input.language.translate_controls(map, &mut message);
    display_message_scrolling(input.renderer.borrow_mut().deref_mut(), &mut input_source, &message, true);
}

fn get_meta_action<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I) -> Option<MetaAction> {
    input_source.next_input().and_then(|event| {
        input.entity.control_map_borrow().and_then(|map_ref| {
            let map = map_ref.deref();
            map.control(event).and_then(|control| {
                match control {
                    Control::Direction(d) => Some(MetaAction::ActionArgs(ActionArgs::Walk(input.entity.id(), d))),
                    Control::Close => {
                        get_direction(map, input_source).map(|d| MetaAction::ActionArgs(ActionArgs::Close(input.entity.id(), d)))
                    }
                    Control::Fire => {
                        aim(input, map, input_source).map(|coord| {
                            let delta = coord - input.entity.position().unwrap();

                            MetaAction::ActionArgs(ActionArgs::FireBullet(input.entity.id(), delta))
                        })
                    }
                    Control::Wait => {
                        Some(MetaAction::ActionArgs(ActionArgs::Null))
                    }
                    Control::Quit => Some(MetaAction::External(External::Quit)),
                    Control::DisplayMessageLog => {
                        display_message_log(input, input_source, map);
                        None
                    }
                    Control::Examine => {
                        examine(input, input_source, map);
                        None
                    }
                    Control::Help => {
                        display_help(input, input_source, map);
                        None
                    }
                    _ => None,
                }
            })
        })
    })
}
<commit_msg>Redrawing hud upon returning from fullscreen<commit_after>use std::ops::Deref;
use std::ops::DerefMut;
use std::cmp;

use game::*;
use behaviour::LeafResolution;
use direction::Direction;
use coord::{Coord, StraightLine};

pub fn player_input<K: KnowledgeRenderer, I: 'static + InputSource + Clone>(input_source: I) -> BehaviourLeaf<K> {
    BehaviourLeaf::new(move |input| {
        loop {
            if let Some(meta_action) = get_meta_action(input, input_source.clone()) {
                return LeafResolution::Yield(meta_action);
            }
        }
    })
}

fn get_direction<I: InputSource>(map: &ControlMap, mut input_source: I) -> Option<Direction> {
    input_source.next_input().and_then(|event| {
        map.control(event).and_then(|control| {
            control_to_direction(control)
        })
    })
}

fn control_to_direction(control: Control) -> Option<Direction> {
    match control {
        Control::Direction(d) => Some(d),
        _ => None,
    }
}

fn aim<R: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<R>, map: &ControlMap, mut input_source: I) -> Option<Coord> {
    let start = input.entity.position().unwrap();
    let mut knowledge = input.entity.drawable_knowledge_borrow_mut().unwrap();
    let level_knowledge = knowledge.level_mut_or_insert_size(input.level_id,
                                                             input.spatial_hash.width(),
                                                             input.spatial_hash.height());

    let targets = level_knowledge.sort_targets(start);
    let mut target_idx = 0;

    let mut end = if !targets.is_empty() {
        targets[target_idx]
    } else {
        start
    };

    let mut renderer = input.renderer.borrow_mut();

    loop {

        let overlay = RenderOverlay::aim_line(StraightLine::new(start, end));
        renderer.draw_with_overlay(&overlay);

        if let Some(event) = input_source.next_input() {
            if let Some(control) = map.control(event) {
                if let Some(direction) = control_to_direction(control) {
                    let next_end = end + direction.vector();
                    if renderer.contains_world_coord(next_end) {
                        end = next_end;
                    }
                } else if control == Control::NextTarget {
                    if !targets.is_empty() {
                        target_idx = (target_idx + 1) % targets.len();
                        end = targets[target_idx];
                    }
                } else if control == Control::PrevTarget {
                    if !targets.is_empty() {
                        target_idx = (target_idx + targets.len() - 1) % targets.len();
                        end = targets[target_idx];
                    }
                } else if control == Control::Fire {
                    renderer.draw();
                    return Some(end);
                } else {
                    break;
                }
            } else {
                break;
            }
        }
    }

    renderer.draw();
    None
}

fn display_message_log<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I, map: &ControlMap) {

    let mut renderer = input.renderer.borrow_mut();
    let message_log = input.entity.message_log_borrow().unwrap();

    let mut offset = 0;
    let num_lines = renderer.display_log_num_lines();
    let num_messages = message_log.len();
    let max_offset = if num_messages > num_lines {
        num_messages - num_lines
    } else {
        0
    };

    loop {
        renderer.display_log(message_log.deref(), offset, input.language);

        if let Some(event) = input_source.next_input() {
            if let Some(control) = map.control(event) {
                match control {
                    Control::Quit |
                        Control::DisplayMessageLog => break,
                    Control::Direction(Direction::North) => {
                        offset = cmp::min(max_offset, offset + 1);
                    }
                    Control::Direction(Direction::South) => {
                        if offset > 0 {
                            offset -= 1;
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    renderer.update_hud(input.entity, input.language);
    renderer.draw();
}

fn examine<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I, map: &ControlMap) {

    let mut knowledge = input.entity.drawable_knowledge_borrow_mut().unwrap();
    let level_knowledge = knowledge.level_mut_or_insert_size(input.level_id,
                                                             input.spatial_hash.width(),
                                                             input.spatial_hash.height());

    let mut renderer = input.renderer.borrow_mut();
    let mut message_log = input.entity.message_log_borrow_mut().unwrap();
    let position = input.entity.position().unwrap();

    let mut cursor = position;
    let mut alternative_message = false;

    loop {

        let cell = level_knowledge.get_with_default(cursor);

        if alternative_message {
            alternative_message = false;
        } else {
            let message = if cell.last_updated() == input.action_env.id {
                MessageType::YouSee(cell.you_see())
            } else if cell.last_updated() == 0 {
                MessageType::Unseen
            } else {
                MessageType::YouRemember(cell.you_see())
            };

            message_log.add_temporary(message);
            renderer.update_log(message_log.deref(), input.language);
        }

        let overlay = RenderOverlay::examine_cursor(cursor);
        renderer.update_hud(input.entity, input.language);
        renderer.draw_with_overlay(&overlay);

        if let Some(event) = input_source.next_input() {
            if let Some(control) = map.control(event) {
                match control {
                    Control::Quit |
                        Control::Examine => break,
                    Control::Direction(direction) => {
                        cursor += direction.vector();
                    }
                    Control::Select => {
                        let message = if let Some(description) = cell.description() {
                            MessageType::Description(description)
                        } else if let Some(you_see) = cell.you_see() {
                            MessageType::YouSeeDescription(you_see)
                        } else {
                            message_log.add_temporary(MessageType::NoDescription);
                            renderer.update_log(message_log.deref(), input.language);
                            alternative_message = true;
                            continue;
                        };

                        renderer.display_message_fullscreen(message, input.language);
                        input_source.next_input();
                    }
                    _ => {}
                }
            }
        }
    }

    message_log.add_temporary(MessageType::Empty);
    renderer.update_log(message_log.deref(), input.language);
    renderer.update_hud(input.entity, input.language);
    renderer.draw();
}

fn display_help<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I, map: &ControlMap) {
    let mut message = Message::new();
    input.language.translate_controls(map, &mut message);
    display_message_scrolling(input.renderer.borrow_mut().deref_mut(), &mut input_source, &message, true);
}

fn get_meta_action<K: KnowledgeRenderer, I: InputSource>(input: BehaviourInput<K>, mut input_source: I) -> Option<MetaAction> {
    input_source.next_input().and_then(|event| {
        input.entity.control_map_borrow().and_then(|map_ref| {
            let map = map_ref.deref();
            map.control(event).and_then(|control| {
                match control {
                    Control::Direction(d) => Some(MetaAction::ActionArgs(ActionArgs::Walk(input.entity.id(), d))),
                    Control::Close => {
                        get_direction(map, input_source).map(|d| MetaAction::ActionArgs(ActionArgs::Close(input.entity.id(), d)))
                    }
                    Control::Fire => {
                        aim(input, map, input_source).map(|coord| {
                            let delta = coord - input.entity.position().unwrap();

                            MetaAction::ActionArgs(ActionArgs::FireBullet(input.entity.id(), delta))
                        })
                    }
                    Control::Wait => {
                        Some(MetaAction::ActionArgs(ActionArgs::Null))
                    }
                    Control::Quit => Some(MetaAction::External(External::Quit)),
                    Control::DisplayMessageLog => {
                        display_message_log(input, input_source, map);
                        None
                    }
                    Control::Examine => {
                        examine(input, input_source, map);
                        None
                    }
                    Control::Help => {
                        display_help(input, input_source, map);
                        None
                    }
                    _ => None,
                }
            })
        })
    })
}
<|endoftext|>


<commit_before>use if_chain::if_chain;
use rustc::hir::def::{CtorKind, Def};
use rustc::hir::intravisit::{walk_item, walk_path, walk_ty, NestedVisitorMap, Visitor};
use rustc::hir::*;
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
use rustc::ty;
use rustc::ty::DefIdTree;
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use syntax_pos::symbol::keywords::SelfUpper;

use crate::utils::span_lint_and_sugg;

declare_clippy_lint! {
    /// **What it does:** Checks for unnecessary repetition of structure name when a
    /// replacement with `Self` is applicable.
    ///
    /// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct
    /// name
    /// feels inconsistent.
    ///
    /// **Known problems:**
    /// - False positive when using associated types (#2843)
    /// - False positives in some situations when using generics (#3410)
    ///
    /// **Example:**
    /// ```rust
    /// struct Foo {}
    /// impl Foo {
    ///     fn new() -> Foo {
    ///         Foo {}
    ///     }
    /// }
    /// ```
    /// could be
    /// ```rust
    /// struct Foo {}
    /// impl Foo {
    ///     fn new() -> Self {
    ///         Self {}
    ///     }
    /// }
    /// ```
    pub USE_SELF,
    pedantic,
    "Unnecessary structure name repetition whereas `Self` is applicable"
}

declare_lint_pass!(UseSelf => [USE_SELF]);

const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";

fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) {
    // Path segments only include actual path, no methods or fields.
    let last_path_span = path.segments.last().expect(SEGMENTS_MSG).ident.span;
    // Only take path up to the end of last_path_span.
    let span = path.span.with_hi(last_path_span.hi());

    span_lint_and_sugg(
        cx,
        USE_SELF,
        span,
        "unnecessary structure name repetition",
        "use the applicable keyword",
        "Self".to_owned(),
        Applicability::MachineApplicable,
    );
}

struct TraitImplTyVisitor<'a, 'tcx: 'a> {
    item_type: ty::Ty<'tcx>,
    cx: &'a LateContext<'a, 'tcx>,
    trait_type_walker: ty::walk::TypeWalker<'tcx>,
    impl_type_walker: ty::walk::TypeWalker<'tcx>,
}

impl<'a, 'tcx> Visitor<'tcx> for TraitImplTyVisitor<'a, 'tcx> {
    fn visit_ty(&mut self, t: &'tcx Ty) {
        let trait_ty = self.trait_type_walker.next();
        let impl_ty = self.impl_type_walker.next();

        if let TyKind::Path(QPath::Resolved(_, path)) = &t.node {
            // The implementation and trait types don't match which means that
            // the concrete type was specified by the implementation
            if impl_ty != trait_ty {
                if let Some(impl_ty) = impl_ty {
                    if self.item_type == impl_ty {
                        let is_self_ty = if let def::Def::SelfTy(..) = path.def {
                            true
                        } else {
                            false
                        };

                        if !is_self_ty {
                            span_use_self_lint(self.cx, path);
                        }
                    }
                }
            }
        }

        walk_ty(self, t)
    }

    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::None
    }
}

fn check_trait_method_impl_decl<'a, 'tcx: 'a>(
    cx: &'a LateContext<'a, 'tcx>,
    item_type: ty::Ty<'tcx>,
    impl_item: &ImplItem,
    impl_decl: &'tcx FnDecl,
    impl_trait_ref: &ty::TraitRef<'_>,
) {
    let trait_method = cx
        .tcx
        .associated_items(impl_trait_ref.def_id)
        .find(|assoc_item| {
            assoc_item.kind == ty::AssociatedKind::Method
                && cx
                    .tcx
                    .hygienic_eq(impl_item.ident, assoc_item.ident, impl_trait_ref.def_id)
        })
        .expect("impl method matches a trait method");

    let trait_method_sig = cx.tcx.fn_sig(trait_method.def_id);
    let trait_method_sig = cx.tcx.erase_late_bound_regions(&trait_method_sig);

    let impl_method_def_id = cx.tcx.hir().local_def_id_from_hir_id(impl_item.hir_id);
    let impl_method_sig = cx.tcx.fn_sig(impl_method_def_id);
    let impl_method_sig = cx.tcx.erase_late_bound_regions(&impl_method_sig);

    let output_ty = if let FunctionRetTy::Return(ty) = &impl_decl.output {
        Some(&**ty)
    } else {
        None
    };

    // `impl_decl_ty` (of type `hir::Ty`) represents the type declared in the signature.
    // `impl_ty` (of type `ty:TyS`) is the concrete type that the compiler has determined for
    // that declaration. We use `impl_decl_ty` to see if the type was declared as `Self`
    // and use `impl_ty` to check its concrete type.
    for (impl_decl_ty, (impl_ty, trait_ty)) in impl_decl.inputs.iter().chain(output_ty).zip(
        impl_method_sig
            .inputs_and_output
            .iter()
            .zip(trait_method_sig.inputs_and_output),
    ) {
        let mut visitor = TraitImplTyVisitor {
            cx,
            item_type,
            trait_type_walker: trait_ty.walk(),
            impl_type_walker: impl_ty.walk(),
        };

        visitor.visit_ty(&impl_decl_ty);
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
    fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
        if in_external_macro(cx.sess(), item.span) {
            return;
        }
        if_chain! {
            if let ItemKind::Impl(.., ref item_type, ref refs) = item.node;
            if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.node;
            then {
                let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
                let should_check = if let Some(ref params) = *parameters {
                    !params.parenthesized && !params.args.iter().any(|arg| match arg {
                        GenericArg::Lifetime(_) => true,
                        _ => false,
                    })
                } else {
                    true
                };

                if should_check {
                    let visitor = &mut UseSelfVisitor {
                        item_path,
                        cx,
                    };
                    let impl_def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                    let impl_trait_ref = cx.tcx.impl_trait_ref(impl_def_id);

                    if let Some(impl_trait_ref) = impl_trait_ref {
                        for impl_item_ref in refs {
                            let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
                            if let ImplItemKind::Method(MethodSig{ decl: impl_decl, .. }, impl_body_id)
                                    = &impl_item.node {
                                let item_type = cx.tcx.type_of(impl_def_id);
                                check_trait_method_impl_decl(cx, item_type, impl_item, impl_decl, &impl_trait_ref);

                                let body = cx.tcx.hir().body(*impl_body_id);
                                visitor.visit_body(body);
                            } else {
                                visitor.visit_impl_item(impl_item);
                            }
                        }
                    } else {
                        for impl_item_ref in refs {
                            let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
                            visitor.visit_impl_item(impl_item);
                        }
                    }
                }
            }
        }
    }
}

struct UseSelfVisitor<'a, 'tcx: 'a> {
    item_path: &'a Path,
    cx: &'a LateContext<'a, 'tcx>,
}

impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> {
    fn visit_path(&mut self, path: &'tcx Path, _id: HirId) {
        if path.segments.last().expect(SEGMENTS_MSG).ident.name != SelfUpper.name() {
            if self.item_path.def == path.def {
                span_use_self_lint(self.cx, path);
            } else if let Def::Ctor(ctor_did, def::CtorOf::Struct, CtorKind::Fn) = path.def {
                if self.item_path.def.opt_def_id() == self.cx.tcx.parent(ctor_did) {
                    span_use_self_lint(self.cx, path);
                }
            }
        }
        walk_path(self, path);
    }

    fn visit_item(&mut self, item: &'tcx Item) {
        match item.node {
            ItemKind::Use(..)
            | ItemKind::Static(..)
            | ItemKind::Enum(..)
            | ItemKind::Struct(..)
            | ItemKind::Union(..)
            | ItemKind::Impl(..)
            | ItemKind::Fn(..) => {
                // Don't check statements that shadow `Self` or where `Self` can't be used
            },
            _ => walk_item(self, item),
        }
    }

    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::All(&self.cx.tcx.hir())
    }
}
<commit_msg>Rustup to rustc 1.36.0-nightly (c7fcbfbf1 2019-04-29)<commit_after>use if_chain::if_chain;
use rustc::hir;
use rustc::hir::def::{CtorKind, Def};
use rustc::hir::intravisit::{walk_item, walk_path, walk_ty, NestedVisitorMap, Visitor};
use rustc::hir::*;
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
use rustc::ty;
use rustc::ty::{DefIdTree, Ty};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use syntax_pos::symbol::keywords::SelfUpper;

use crate::utils::span_lint_and_sugg;

declare_clippy_lint! {
    /// **What it does:** Checks for unnecessary repetition of structure name when a
    /// replacement with `Self` is applicable.
    ///
    /// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct
    /// name
    /// feels inconsistent.
    ///
    /// **Known problems:**
    /// - False positive when using associated types (#2843)
    /// - False positives in some situations when using generics (#3410)
    ///
    /// **Example:**
    /// ```rust
    /// struct Foo {}
    /// impl Foo {
    ///     fn new() -> Foo {
    ///         Foo {}
    ///     }
    /// }
    /// ```
    /// could be
    /// ```rust
    /// struct Foo {}
    /// impl Foo {
    ///     fn new() -> Self {
    ///         Self {}
    ///     }
    /// }
    /// ```
    pub USE_SELF,
    pedantic,
    "Unnecessary structure name repetition whereas `Self` is applicable"
}

declare_lint_pass!(UseSelf => [USE_SELF]);

const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";

fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) {
    // Path segments only include actual path, no methods or fields.
    let last_path_span = path.segments.last().expect(SEGMENTS_MSG).ident.span;
    // Only take path up to the end of last_path_span.
    let span = path.span.with_hi(last_path_span.hi());

    span_lint_and_sugg(
        cx,
        USE_SELF,
        span,
        "unnecessary structure name repetition",
        "use the applicable keyword",
        "Self".to_owned(),
        Applicability::MachineApplicable,
    );
}

struct TraitImplTyVisitor<'a, 'tcx: 'a> {
    item_type: Ty<'tcx>,
    cx: &'a LateContext<'a, 'tcx>,
    trait_type_walker: ty::walk::TypeWalker<'tcx>,
    impl_type_walker: ty::walk::TypeWalker<'tcx>,
}

impl<'a, 'tcx> Visitor<'tcx> for TraitImplTyVisitor<'a, 'tcx> {
    fn visit_ty(&mut self, t: &'tcx hir::Ty) {
        let trait_ty = self.trait_type_walker.next();
        let impl_ty = self.impl_type_walker.next();

        if let TyKind::Path(QPath::Resolved(_, path)) = &t.node {
            // The implementation and trait types don't match which means that
            // the concrete type was specified by the implementation
            if impl_ty != trait_ty {
                if let Some(impl_ty) = impl_ty {
                    if self.item_type == impl_ty {
                        let is_self_ty = if let def::Def::SelfTy(..) = path.def {
                            true
                        } else {
                            false
                        };

                        if !is_self_ty {
                            span_use_self_lint(self.cx, path);
                        }
                    }
                }
            }
        }

        walk_ty(self, t)
    }

    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::None
    }
}

fn check_trait_method_impl_decl<'a, 'tcx: 'a>(
    cx: &'a LateContext<'a, 'tcx>,
    item_type: Ty<'tcx>,
    impl_item: &ImplItem,
    impl_decl: &'tcx FnDecl,
    impl_trait_ref: &ty::TraitRef<'_>,
) {
    let trait_method = cx
        .tcx
        .associated_items(impl_trait_ref.def_id)
        .find(|assoc_item| {
            assoc_item.kind == ty::AssociatedKind::Method
                && cx
                    .tcx
                    .hygienic_eq(impl_item.ident, assoc_item.ident, impl_trait_ref.def_id)
        })
        .expect("impl method matches a trait method");

    let trait_method_sig = cx.tcx.fn_sig(trait_method.def_id);
    let trait_method_sig = cx.tcx.erase_late_bound_regions(&trait_method_sig);

    let impl_method_def_id = cx.tcx.hir().local_def_id_from_hir_id(impl_item.hir_id);
    let impl_method_sig = cx.tcx.fn_sig(impl_method_def_id);
    let impl_method_sig = cx.tcx.erase_late_bound_regions(&impl_method_sig);

    let output_ty = if let FunctionRetTy::Return(ty) = &impl_decl.output {
        Some(&**ty)
    } else {
        None
    };

    // `impl_decl_ty` (of type `hir::Ty`) represents the type declared in the signature.
    // `impl_ty` (of type `ty:TyS`) is the concrete type that the compiler has determined for
    // that declaration. We use `impl_decl_ty` to see if the type was declared as `Self`
    // and use `impl_ty` to check its concrete type.
    for (impl_decl_ty, (impl_ty, trait_ty)) in impl_decl.inputs.iter().chain(output_ty).zip(
        impl_method_sig
            .inputs_and_output
            .iter()
            .zip(trait_method_sig.inputs_and_output),
    ) {
        let mut visitor = TraitImplTyVisitor {
            cx,
            item_type,
            trait_type_walker: trait_ty.walk(),
            impl_type_walker: impl_ty.walk(),
        };

        visitor.visit_ty(&impl_decl_ty);
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
    fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
        if in_external_macro(cx.sess(), item.span) {
            return;
        }
        if_chain! {
            if let ItemKind::Impl(.., ref item_type, ref refs) = item.node;
            if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.node;
            then {
                let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
                let should_check = if let Some(ref params) = *parameters {
                    !params.parenthesized && !params.args.iter().any(|arg| match arg {
                        GenericArg::Lifetime(_) => true,
                        _ => false,
                    })
                } else {
                    true
                };

                if should_check {
                    let visitor = &mut UseSelfVisitor {
                        item_path,
                        cx,
                    };
                    let impl_def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                    let impl_trait_ref = cx.tcx.impl_trait_ref(impl_def_id);

                    if let Some(impl_trait_ref) = impl_trait_ref {
                        for impl_item_ref in refs {
                            let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
                            if let ImplItemKind::Method(MethodSig{ decl: impl_decl, .. }, impl_body_id)
                                    = &impl_item.node {
                                let item_type = cx.tcx.type_of(impl_def_id);
                                check_trait_method_impl_decl(cx, item_type, impl_item, impl_decl, &impl_trait_ref);

                                let body = cx.tcx.hir().body(*impl_body_id);
                                visitor.visit_body(body);
                            } else {
                                visitor.visit_impl_item(impl_item);
                            }
                        }
                    } else {
                        for impl_item_ref in refs {
                            let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
                            visitor.visit_impl_item(impl_item);
                        }
                    }
                }
            }
        }
    }
}

struct UseSelfVisitor<'a, 'tcx: 'a> {
    item_path: &'a Path,
    cx: &'a LateContext<'a, 'tcx>,
}

impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> {
    fn visit_path(&mut self, path: &'tcx Path, _id: HirId) {
        if path.segments.last().expect(SEGMENTS_MSG).ident.name != SelfUpper.name() {
            if self.item_path.def == path.def {
                span_use_self_lint(self.cx, path);
            } else if let Def::Ctor(ctor_did, def::CtorOf::Struct, CtorKind::Fn) = path.def {
                if self.item_path.def.opt_def_id() == self.cx.tcx.parent(ctor_did) {
                    span_use_self_lint(self.cx, path);
                }
            }
        }
        walk_path(self, path);
    }

    fn visit_item(&mut self, item: &'tcx Item) {
        match item.node {
            ItemKind::Use(..)
            | ItemKind::Static(..)
            | ItemKind::Enum(..)
            | ItemKind::Struct(..)
            | ItemKind::Union(..)
            | ItemKind::Impl(..)
            | ItemKind::Fn(..) => {
                // Don't check statements that shadow `Self` or where `Self` can't be used
            },
            _ => walk_item(self, item),
        }
    }

    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::All(&self.cx.tcx.hir())
    }
}
<|endoftext|>


<commit_before>//! Matrix user identifiers.

use std::{convert::TryFrom, fmt, num::NonZeroU8};

use crate::ServerName;

/// A Matrix user ID.
///
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::UserId;
/// assert_eq!(
///     UserId::try_from("@carl:example.com").unwrap().as_ref(),
///     "@carl:example.com"
/// );
/// ```
#[derive(Clone)]
pub struct UserId {
    full_id: Box<str>,
    colon_idx: NonZeroU8,

    /// Whether this user id is a historical one.
    ///
    /// A historical user id is one that is not legal per the regular user id rules, but was
    /// accepted by previous versions of the spec and thus has to be supported because users with
    /// these kinds of ids still exist.
    is_historical: bool,
}

impl fmt::Debug for UserId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(&self.full_id)
    }
}

impl UserId {
    /// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
    /// 12 random ASCII characters.
    #[cfg(feature = "rand")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
    pub fn new(server_name: &ServerName) -> Self {
        use crate::generate_localpart;

        let full_id = format!("@{}:{}", generate_localpart(12).to_lowercase(), server_name).into();

        Self { full_id, colon_idx: NonZeroU8::new(13).unwrap(), is_historical: false }
    }

    /// Attempts to complete a user ID, by adding the colon + server name and `@` prefix, if not
    /// present already.
    ///
    /// This is a convenience function for the login API, where a user can supply either their full
    /// user ID or just the localpart. It only supports a valid user ID or a valid user ID
    /// localpart, not the localpart plus the `@` prefix, or the localpart plus server name without
    /// the `@` prefix.
    pub fn parse_with_server_name(
        id: impl AsRef<str> + Into<Box<str>>,
        server_name: &ServerName,
    ) -> Result<Self, crate::Error> {
        let id_str = id.as_ref();

        if id_str.starts_with('@') {
            try_from(id.into())
        } else {
            let is_fully_conforming = localpart_is_fully_conforming(id_str)?;

            Ok(Self {
                full_id: format!("@{}:{}", id_str, server_name).into(),
                colon_idx: NonZeroU8::new(id_str.len() as u8 + 1).unwrap(),
                is_historical: !is_fully_conforming,
            })
        }
    }

    /// Returns the user's localpart.
    pub fn localpart(&self) -> &str {
        &self.full_id[1..self.colon_idx.get() as usize]
    }

    /// Returns the server name of the user ID.
    pub fn server_name(&self) -> &ServerName {
        <&ServerName>::try_from(&self.full_id[self.colon_idx.get() as usize + 1..]).unwrap()
    }

    /// Whether this user ID is a historical one, i.e. one that doesn't conform to the latest
    /// specification of the user ID grammar but is still accepted because it was previously
    /// allowed.
    pub fn is_historical(&self) -> bool {
        self.is_historical
    }
}

/// Attempts to create a new Matrix user ID from a string representation.
///
/// The string must include the leading @ sigil, the localpart, a literal colon, and a server name.
fn try_from<S>(user_id: S) -> Result<UserId, crate::Error>
where
    S: AsRef<str> + Into<Box<str>>,
{
    let (colon_idx, is_historical) =
        ruma_identifiers_validation::user_id::validate(user_id.as_ref())?;
    Ok(UserId { full_id: user_id.into(), colon_idx, is_historical: !is_historical })
}

common_impls!(UserId, try_from, "a Matrix user ID");

pub use ruma_identifiers_validation::user_id::localpart_is_fully_conforming;

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use super::UserId;
    use crate::{Error, ServerName};

    #[test]
    fn valid_user_id_from_str() {
        let user_id = UserId::try_from("@carl:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@carl:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id =
            UserId::parse_with_server_name("carl", server_name).expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn valid_historical_user_id() {
        let user_id = UserId::try_from("@a%b[irc]:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@a%b[irc]:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("a%b[irc]", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn uppercase_user_id() {
        let user_id = UserId::try_from("@CARL:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@CARL:example.com");
        assert!(user_id.is_historical());
    }

    #[cfg(feature = "rand")]
    #[test]
    fn generate_random_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::new(server_name);
        assert_eq!(user_id.localpart().len(), 12);
        assert_eq!(user_id.server_name(), "example.com");

        let id_str = user_id.as_str();

        assert!(id_str.starts_with('@'));
        assert_eq!(id_str.len(), 25);
    }

    #[cfg(feature = "serde")]
    #[test]
    fn serialize_valid_user_id() {
        assert_eq!(
            serde_json::to_string(
                &UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
            )
            .expect("Failed to convert UserId to JSON."),
            r#""@carl:example.com""#
        );
    }

    #[cfg(feature = "serde")]
    #[test]
    fn deserialize_valid_user_id() {
        assert_eq!(
            serde_json::from_str::<UserId>(r#""@carl:example.com""#)
                .expect("Failed to convert JSON to UserId"),
            UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
        );
    }

    #[test]
    fn valid_user_id_with_explicit_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:443").expect("Failed to create UserId.").as_ref(),
            "@carl:example.com:443"
        );
    }

    #[test]
    fn valid_user_id_with_non_standard_port() {
        let user_id = UserId::try_from("@carl:example.com:5000").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com:5000");
        assert!(!user_id.is_historical());
    }

    #[test]
    #[cfg(not(feature = "compat"))]
    fn invalid_characters_in_user_id_localpart() {
        assert_eq!(UserId::try_from("@te\nst:example.com").unwrap_err(), Error::InvalidCharacters);
    }

    #[test]
    fn missing_user_id_sigil() {
        assert_eq!(UserId::try_from("carl:example.com").unwrap_err(), Error::MissingLeadingSigil);
    }

    #[test]
    fn missing_user_id_delimiter() {
        assert_eq!(UserId::try_from("@carl").unwrap_err(), Error::MissingDelimiter);
    }

    #[test]
    fn invalid_user_id_host() {
        assert_eq!(UserId::try_from("@carl:/").unwrap_err(), Error::InvalidServerName);
    }

    #[test]
    fn invalid_user_id_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:notaport").unwrap_err(),
            Error::InvalidServerName
        );
    }
}
<commit_msg>identifiers: Rewrap doc comment<commit_after>//! Matrix user identifiers.

use std::{convert::TryFrom, fmt, num::NonZeroU8};

use crate::ServerName;

/// A Matrix user ID.
///
/// A `UserId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::UserId;
/// assert_eq!(
///     UserId::try_from("@carl:example.com").unwrap().as_ref(),
///     "@carl:example.com"
/// );
/// ```
#[derive(Clone)]
pub struct UserId {
    full_id: Box<str>,
    colon_idx: NonZeroU8,

    /// Whether this user id is a historical one.
    ///
    /// A historical user id is one that is not legal per the regular user id rules, but was
    /// accepted by previous versions of the spec and thus has to be supported because users with
    /// these kinds of ids still exist.
    is_historical: bool,
}

impl fmt::Debug for UserId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(&self.full_id)
    }
}

impl UserId {
    /// Attempts to generate a `UserId` for the given origin server with a localpart consisting of
    /// 12 random ASCII characters.
    #[cfg(feature = "rand")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
    pub fn new(server_name: &ServerName) -> Self {
        use crate::generate_localpart;

        let full_id = format!("@{}:{}", generate_localpart(12).to_lowercase(), server_name).into();

        Self { full_id, colon_idx: NonZeroU8::new(13).unwrap(), is_historical: false }
    }

    /// Attempts to complete a user ID, by adding the colon + server name and `@` prefix, if not
    /// present already.
    ///
    /// This is a convenience function for the login API, where a user can supply either their full
    /// user ID or just the localpart. It only supports a valid user ID or a valid user ID
    /// localpart, not the localpart plus the `@` prefix, or the localpart plus server name without
    /// the `@` prefix.
    pub fn parse_with_server_name(
        id: impl AsRef<str> + Into<Box<str>>,
        server_name: &ServerName,
    ) -> Result<Self, crate::Error> {
        let id_str = id.as_ref();

        if id_str.starts_with('@') {
            try_from(id.into())
        } else {
            let is_fully_conforming = localpart_is_fully_conforming(id_str)?;

            Ok(Self {
                full_id: format!("@{}:{}", id_str, server_name).into(),
                colon_idx: NonZeroU8::new(id_str.len() as u8 + 1).unwrap(),
                is_historical: !is_fully_conforming,
            })
        }
    }

    /// Returns the user's localpart.
    pub fn localpart(&self) -> &str {
        &self.full_id[1..self.colon_idx.get() as usize]
    }

    /// Returns the server name of the user ID.
    pub fn server_name(&self) -> &ServerName {
        <&ServerName>::try_from(&self.full_id[self.colon_idx.get() as usize + 1..]).unwrap()
    }

    /// Whether this user ID is a historical one.
    ///
    /// A historical user ID is one that doesn't conform to the latest specification of the user ID
    /// grammar but is still accepted because it was previously allowed.
    pub fn is_historical(&self) -> bool {
        self.is_historical
    }
}

/// Attempts to create a new Matrix user ID from a string representation.
///
/// The string must include the leading @ sigil, the localpart, a literal colon, and a server name.
fn try_from<S>(user_id: S) -> Result<UserId, crate::Error>
where
    S: AsRef<str> + Into<Box<str>>,
{
    let (colon_idx, is_historical) =
        ruma_identifiers_validation::user_id::validate(user_id.as_ref())?;
    Ok(UserId { full_id: user_id.into(), colon_idx, is_historical: !is_historical })
}

common_impls!(UserId, try_from, "a Matrix user ID");

pub use ruma_identifiers_validation::user_id::localpart_is_fully_conforming;

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use super::UserId;
    use crate::{Error, ServerName};

    #[test]
    fn valid_user_id_from_str() {
        let user_id = UserId::try_from("@carl:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@carl:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn parse_valid_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id =
            UserId::parse_with_server_name("carl", server_name).expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com");
        assert_eq!(user_id.localpart(), "carl");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(!user_id.is_historical());
    }

    #[test]
    fn valid_historical_user_id() {
        let user_id = UserId::try_from("@a%b[irc]:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("@a%b[irc]:example.com", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn parse_valid_historical_user_id_parts() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::parse_with_server_name("a%b[irc]", server_name)
            .expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@a%b[irc]:example.com");
        assert_eq!(user_id.localpart(), "a%b[irc]");
        assert_eq!(user_id.server_name(), "example.com");
        assert!(user_id.is_historical());
    }

    #[test]
    fn uppercase_user_id() {
        let user_id = UserId::try_from("@CARL:example.com").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@CARL:example.com");
        assert!(user_id.is_historical());
    }

    #[cfg(feature = "rand")]
    #[test]
    fn generate_random_valid_user_id() {
        let server_name = <&ServerName>::try_from("example.com").unwrap();
        let user_id = UserId::new(server_name);
        assert_eq!(user_id.localpart().len(), 12);
        assert_eq!(user_id.server_name(), "example.com");

        let id_str = user_id.as_str();

        assert!(id_str.starts_with('@'));
        assert_eq!(id_str.len(), 25);
    }

    #[cfg(feature = "serde")]
    #[test]
    fn serialize_valid_user_id() {
        assert_eq!(
            serde_json::to_string(
                &UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
            )
            .expect("Failed to convert UserId to JSON."),
            r#""@carl:example.com""#
        );
    }

    #[cfg(feature = "serde")]
    #[test]
    fn deserialize_valid_user_id() {
        assert_eq!(
            serde_json::from_str::<UserId>(r#""@carl:example.com""#)
                .expect("Failed to convert JSON to UserId"),
            UserId::try_from("@carl:example.com").expect("Failed to create UserId.")
        );
    }

    #[test]
    fn valid_user_id_with_explicit_standard_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:443").expect("Failed to create UserId.").as_ref(),
            "@carl:example.com:443"
        );
    }

    #[test]
    fn valid_user_id_with_non_standard_port() {
        let user_id = UserId::try_from("@carl:example.com:5000").expect("Failed to create UserId.");
        assert_eq!(user_id.as_ref(), "@carl:example.com:5000");
        assert!(!user_id.is_historical());
    }

    #[test]
    #[cfg(not(feature = "compat"))]
    fn invalid_characters_in_user_id_localpart() {
        assert_eq!(UserId::try_from("@te\nst:example.com").unwrap_err(), Error::InvalidCharacters);
    }

    #[test]
    fn missing_user_id_sigil() {
        assert_eq!(UserId::try_from("carl:example.com").unwrap_err(), Error::MissingLeadingSigil);
    }

    #[test]
    fn missing_user_id_delimiter() {
        assert_eq!(UserId::try_from("@carl").unwrap_err(), Error::MissingDelimiter);
    }

    #[test]
    fn invalid_user_id_host() {
        assert_eq!(UserId::try_from("@carl:/").unwrap_err(), Error::InvalidServerName);
    }

    #[test]
    fn invalid_user_id_port() {
        assert_eq!(
            UserId::try_from("@carl:example.com:notaport").unwrap_err(),
            Error::InvalidServerName
        );
    }
}
<|endoftext|>