<commit_before>extern crate num;
extern crate byteorder;

use std::fs::File;
use std::io::Read;
use std::io::Cursor;
use std::mem;
use byteorder::{ByteOrder, LittleEndian, BigEndian, NativeEndian};
use std::iter::FromIterator;

type c32 = num::Complex<f32>;
type c64 = num::Complex<f64>;

struct Grid<T> {
    points: Vec<Vec<T>>,
}

impl Grid<f32> {
    fn new() -> Self { Grid {points: Vec::new() } }
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
        self.points = Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start = (i * ysize + j) * mem::size_of::<f32>();
                let real = if little_endian {
                    LittleEndian::read_f32(&grid_buf[start .. ])
                } else {
                    BigEndian::read_f32(&grid_buf[start .. ])
                };
                real
            }))
        }))
    }
}

impl Grid<c32> {
    fn new() -> Self { Grid {points: Vec::new() } }
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
         self.points = Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start_1 = (i * ysize + j) * 2 * mem::size_of::<f32>();
                let start_2 = start_1 + mem::size_of::<f32>(); // next f32 number
                let (real, imag) = if little_endian {
                    (LittleEndian::read_f32(&grid_buf[start_1 .. ]),
                     LittleEndian::read_f32(&grid_buf[start_2 .. ]))
                } else {
                    (BigEndian::read_f32(&grid_buf[start_1 .. ]),
                     BigEndian::read_f32(&grid_buf[start_2 .. ]))
                };
                c32::new(real, imag)
            }))
        }));
    }
}

impl Grid<f64> {
    fn new() -> Self { Grid {points: Vec::new() } }
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
         self.points = Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start = (i * ysize + j) * mem::size_of::<f64>();
                let real = if little_endian {
                    LittleEndian::read_f64(&grid_buf[start .. ])
                } else {
                    BigEndian::read_f64(&grid_buf[start .. ])
                };
                real
            }))
        }));
    }
}

impl Grid<c64> {
    fn new() -> Self { Grid {points: Vec::new() } }
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
        self.points =  Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start_1 = (i * ysize + j) * 2 * mem::size_of::<f64>();
                let start_2 = start_1 + mem::size_of::<f64>(); // next f64 number
                let (real, imag) = if little_endian {
                    (LittleEndian::read_f64(&grid_buf[start_1 .. ]),
                     LittleEndian::read_f64(&grid_buf[start_2 .. ]))
                } else {
                    (BigEndian::read_f64(&grid_buf[start_1 .. ]),
                     BigEndian::read_f64(&grid_buf[start_2 .. ]))
                };
                c64::new(real, imag)
            }))
        }));
    }
}

fn main() {
    let mut grid = Grid::<f32>::new();
    grid.read(true, 8, 8, &vec![0u8; 64 * 4]);
}
<commit_msg>refactor `new` via `GridTrait`.<commit_after>extern crate num;
extern crate byteorder;

use std::fs::File;
use std::io::Read;
use std::io::Cursor;
use std::mem;
use byteorder::{ByteOrder, LittleEndian, BigEndian, NativeEndian};
use std::iter::FromIterator;

type c32 = num::Complex<f32>;
type c64 = num::Complex<f64>;

trait GridTrait<T> {
    // a constructor
    fn new() -> Grid<T> { Grid {points: Vec::new() } }

    // unformatted read from the buffer
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>);
}

struct Grid<T> {
    points: Vec<Vec<T>>,
}

impl GridTrait<f32> for Grid<f32> {
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
        self.points = Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start = (i * ysize + j) * mem::size_of::<f32>();
                let real = if little_endian {
                    LittleEndian::read_f32(&grid_buf[start .. ])
                } else {
                    BigEndian::read_f32(&grid_buf[start .. ])
                };
                real
            }))
        }))
    }
}

impl GridTrait<c32> for Grid<c32> {
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
         self.points = Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start_1 = (i * ysize + j) * 2 * mem::size_of::<f32>();
                let start_2 = start_1 + mem::size_of::<f32>(); // next f32 number
                let (real, imag) = if little_endian {
                    (LittleEndian::read_f32(&grid_buf[start_1 .. ]),
                     LittleEndian::read_f32(&grid_buf[start_2 .. ]))
                } else {
                    (BigEndian::read_f32(&grid_buf[start_1 .. ]),
                     BigEndian::read_f32(&grid_buf[start_2 .. ]))
                };
                c32::new(real, imag)
            }))
        }));
    }
}

impl GridTrait<f64> for Grid<f64> {
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
         self.points = Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start = (i * ysize + j) * mem::size_of::<f64>();
                let real = if little_endian {
                    LittleEndian::read_f64(&grid_buf[start .. ])
                } else {
                    BigEndian::read_f64(&grid_buf[start .. ])
                };
                real
            }))
        }));
    }
}

impl GridTrait<c64> for Grid<c64> {
    fn read(&mut self,
            little_endian: bool,
            xsize: usize,
            ysize: usize,
            grid_buf: &Vec<u8>) {
        self.points =  Vec::from_iter((0..xsize).map(|i| {
            Vec::from_iter((0..ysize).map(|j| {
                let start_1 = (i * ysize + j) * 2 * mem::size_of::<f64>();
                let start_2 = start_1 + mem::size_of::<f64>(); // next f64 number
                let (real, imag) = if little_endian {
                    (LittleEndian::read_f64(&grid_buf[start_1 .. ]),
                     LittleEndian::read_f64(&grid_buf[start_2 .. ]))
                } else {
                    (BigEndian::read_f64(&grid_buf[start_1 .. ]),
                     BigEndian::read_f64(&grid_buf[start_2 .. ]))
                };
                c64::new(real, imag)
            }))
        }));
    }
}

fn main() {
    let mut grid = Grid::<f32>::new();
    grid.read(true, 8, 8, &vec![0u8; 64 * mem::size_of::<f32>()]);

    let mut grid1 = Grid::<c32>::new();
    grid1.read(true, 8, 8, &vec![0u8; 64 * mem::size_of::<c32>()]);
}

<|endoftext|>


<commit_before>#![crate_id = "http#0.1-pre"]

#![comment = "Rust HTTP server"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/chris-morgan/rust-http/doc/")]

#![deny(non_camel_case_types)]
//#[deny(missing_doc)];

#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(phase)]
#![macro_escape]

#[phase(syntax, link)] extern crate log;
extern crate url;
extern crate time;
extern crate collections;
extern crate debug;

pub mod buffer;
pub mod client;
pub mod common;
pub mod connecter;
pub mod server;
pub mod method;
pub mod headers;
pub mod rfc2616;
#[path = "generated/status.rs"]
pub mod status;  // Getting an error? It's generated; use ``make`` or see the ``Makefile``

/// TODO: submit upstream
#[cfg(test)]
pub mod memstream;
<commit_msg>Changed phase(syntax, ...) to phase(plugin, ...)<commit_after>#![crate_id = "http#0.1-pre"]

#![comment = "Rust HTTP server"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/chris-morgan/rust-http/doc/")]

#![deny(non_camel_case_types)]
//#[deny(missing_doc)];

#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(phase)]
#![macro_escape]

#[phase(plugin, link)] extern crate log;
extern crate url;
extern crate time;
extern crate collections;
extern crate debug;

pub mod buffer;
pub mod client;
pub mod common;
pub mod connecter;
pub mod server;
pub mod method;
pub mod headers;
pub mod rfc2616;
#[path = "generated/status.rs"]
pub mod status;  // Getting an error? It's generated; use ``make`` or see the ``Makefile``

/// TODO: submit upstream
#[cfg(test)]
pub mod memstream;
<|endoftext|>


<commit_before>#![deny(missing_docs)]
//! Module for tracking the current thread, and wrapping non-`Send` objects in
//! guards that perform runtime thread checks.

use std::sync::Arc;
use std::fmt::{self, Debug};

/// A permanent identifier for a single thread, which will not be reused.
#[derive(Clone)]
pub struct ThreadId(Arc<()>);

impl PartialEq for ThreadId {
    fn eq(&self, other: &Self) -> bool {
        (&*self.0 as *const ()) == (&*other.0 as *const ())
    }
}
impl Eq for ThreadId {}

impl Debug for ThreadId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "thread({:?})", &*self.0 as *const ())
    }
}

// consider using https://github.com/rust-lang/rust/pull/29447 after it lands,
// or a u64 atomic where available
// is there a lock-free way to increment a 64-bit counter?
thread_local!(static THREAD_NONCE: ThreadId = ThreadId(Arc::new(())));

/// Returns a persistent identifier for the current thread.
pub fn current_thread_id() -> ThreadId {
    THREAD_NONCE.with(|r| r.clone())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;

    #[test]
    fn same_thread_id() {
        let id1 = current_thread_id();
        let id2 = current_thread_id();

        assert_eq!(id1, id2);
    }

    #[test]
    fn different_thread_id() {
        let id1 = current_thread_id();
        let id2 = thread::spawn(|| current_thread_id()).join().unwrap();

        assert!(id1 != id2);
    }
}
<commit_msg>Implement ThreadBound<commit_after>#![deny(missing_docs)]
//! Module for tracking the current thread, and wrapping non-`Send` objects in
//! guards that perform runtime thread checks.

use std::sync::Arc;
use std::fmt::{self, Debug};
use std::ptr;
use std::mem;
use std::cell::Cell;
use std::ops::{Deref,DerefMut};

/// A permanent identifier for a single thread, which will not be reused.
#[derive(Clone)]
pub struct ThreadId(Arc<()>);

impl PartialEq for ThreadId {
    fn eq(&self, other: &Self) -> bool {
        (&*self.0 as *const ()) == (&*other.0 as *const ())
    }
}
impl Eq for ThreadId {}

impl Debug for ThreadId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "thread({:?})", &*self.0 as *const ())
    }
}

// consider using https://github.com/rust-lang/rust/pull/29447 after it lands,
// or a u64 atomic where available
// is there a lock-free way to increment a 64-bit counter?
thread_local!(static THREAD_NONCE: ThreadId = ThreadId(Arc::new(())));

/// Returns a persistent identifier for the current thread.
pub fn current_thread_id() -> ThreadId {
    THREAD_NONCE.with(|r| r.clone())
}

struct TBListHead {
    // do not move
    owner: ThreadId,
    head: TBHeader,
    destroying: Cell<bool>,
}

struct TBList {
    list: Arc<TBListHead>,
}

struct TBHeader {
    // do not move
    next: Cell<*const TBHeader>,
    prev: Cell<*const TBHeader>,
    free: unsafe fn(*const TBHeader),
}

struct TBVar<T: 'static> {
    // do not move
    value: T,
    header: TBHeader,
}

/// A handle to a value of type `T` which is owned by a specific thread.  Code running on the same
/// thread can freely manipulate the value; attempts to manipulate the value from other threads
/// will panic at runtime.
///
/// Lifetime is subtle.  Since we do not assume `T` can be safely dropped from any thread other
/// than that where it was created, dropping a `ThreadBound<T>` will only immediately drop the
/// wrapped value in the originating thread.  Drops occuring on other threads will leave the value
/// in a thread-local list associated with the originating thread, and the value will live until
/// the originating thread exits, at which point it will be destroyed. Conversely, if the
/// originating thread exits while there are `ThreadBound<T>` capabilities alive in the heap, all
/// of the underlying values will be dropped (this causes the capabilities to become dangling
/// pointers, but that is OK as the only thread that could dereference them is exiting).
pub struct ThreadBound<T: 'static> {
    list: Arc<TBListHead>,
    var: *mut TBVar<T>,
}

unsafe impl<T: 'static> Send for ThreadBound<T> {}
unsafe impl<T: 'static> Sync for ThreadBound<T> {}

unsafe fn unlink_var(header: *const TBHeader) {
    // precondition: the list is being destroyed or the capability has just been
    // dropped
    // (either way there will be no future attempts to access this header)
    // println!("unlink header {:?}", header);
    let prev = (*header).prev.get();
    let next = (*header).next.get();
    (*next).prev.set(prev);
    (*prev).next.set(next);
}

// unsafe fn list_dumper(why: &'static str, lh: &TBListHead) {
//     let pstart = &lh.head as *const TBHeader;
//     let mut p2 = pstart;
//     println!("list dump {}", why);
//     loop {
//         println!("header@{:?}, next={next:?}, prev={prev:?}, free={free:?}", p2,
//             next = (*p2).next.get(), prev = (*p2).prev.get(), free = (*p2).free);
//         p2 = (*p2).next.get();
//         if p2 == pstart { break; }
//     }
// }

unsafe fn destroy_var(header: *const TBHeader) {
    // println!("destroy header {:?}", header);
    unlink_var(header);
    ((*header).free)(header);
}

impl Drop for TBList {
    fn drop(&mut self) {
        self.list.destroying.set(true);
        let headp = &self.list.head as *const TBHeader;

        unsafe {
            // list_dumper("A",&*self.list);
            while (*headp).next.get() != headp {
                destroy_var((*headp).next.get());
            }
        }
    }
}

impl<T: 'static> Drop for ThreadBound<T> {
    fn drop(&mut self) {
        if self.list.owner == current_thread_id() && !self.list.destroying.get() {
            unsafe {
                // list_dumper("B", &*self.list);
                destroy_var(&(*self.var).header);
            }
        }
        // otherwise the var leaks and will be cleaned up when the originating thread
        // exits.  we could provide a scrub() function to call from the originating
        // thread, at the cost of extra synchronization.
    }
}

impl TBList {
    fn new() -> Self {
        unsafe fn unreachable(_head: *const TBHeader) {
            panic!("attempt to free TBList header");
        }
        let lheader = Arc::new(TBListHead {
            owner: current_thread_id(),
            destroying: Cell::new(false),
            head: TBHeader {
                next: Cell::new(ptr::null_mut()),
                prev: Cell::new(ptr::null_mut()),
                free: unreachable,
            },
        });
        let headp = &lheader.head as *const TBHeader;
        // println!("insert header {:?}", headp);
        unsafe {
            (*headp).next.set(headp);
            (*headp).prev.set(headp);
            // list_dumper("C", &*lheader);
        }
        TBList { list: lheader }
    }

    fn make_bound<T: 'static>(&self, value: T) -> ThreadBound<T> {
        unsafe fn free<T: 'static>(header: *const TBHeader) {
            let offset = &(*(0 as *const TBVar<T>)).header as *const TBHeader as usize;
            let varp = ((header as usize) - offset) as *mut TBVar<T>;
            // println!("free/box {:?}", varp);
            mem::drop(Box::from_raw(varp));
        }

        let new_var: *mut TBVar<T> = Box::into_raw(Box::new(TBVar {
            header: TBHeader {
                next: Cell::new(ptr::null_mut()),
                prev: Cell::new(ptr::null_mut()),
                free: free::<T>,
            },
            value: value,
        }));

        unsafe {
            let new_head = &(*new_var).header as *const TBHeader;
            let list_head = &self.list.head as *const TBHeader;

            (*new_head).next.set(list_head);
            (*new_head).prev.set((*list_head).prev.get());
            (*(*list_head).prev.get()).next.set(new_head);
            (*list_head).prev.set(new_head);
            // list_dumper("D", &*self.list);
        }

        ThreadBound {
            var: new_var,
            list: self.list.clone(),
        }
    }
}

thread_local!(static THREAD_LIST_KEY: TBList = TBList::new());

impl<T: 'static> ThreadBound<T> {
    /// Wraps a value of type `T` in a capability bound to the current thread.
    pub fn new(inner: T) -> Self {
        THREAD_LIST_KEY.with(|tl| tl.make_bound(inner))
    }

    /// Returns true if this capability can be used without panicking.  This will remain true on
    /// the same thread as long as the thread does not enter the TLS destruction phase.
    pub fn accessible(&self) -> bool {
        return self.list.owner == current_thread_id() && !self.list.destroying.get();
    }

    /// Consumes this capability to regain ownership of the underlying value.
    ///
    /// # Panics
    ///
    /// Panics if the capability is not accessible.
    pub fn into_inner(self) -> T {
        self.check_access();
        unsafe {
            unlink_var(&(*self.var).header as *const TBHeader);
            // yes, this is a move, so it invalidates the next/prev
            // println!("from_raw {:?}",self.var);
            let var_guts : TBVar<T> = *Box::from_raw(self.var);
            mem::forget(self); // no double free
            var_guts.value
        }
    }

    fn check_access(&self) {
        if self.list.owner != current_thread_id() {
            panic!("Attempt to access ThreadBound from incorrect thread");
        }

        if self.list.destroying.get() {
            panic!("Attempt to access ThreadBound during TLS destruction phase");
        }
    }
}

impl<T: 'static> Deref for ThreadBound<T> {
    type Target = T;
    /// Can this be documented?
    fn deref(&self) -> &T {
        self.check_access();
        unsafe { &(*self.var).value }
    }
}

impl<T: 'static> DerefMut for ThreadBound<T> {
    fn deref_mut(&mut self) -> &mut T {
        self.check_access();
        unsafe { &mut (*self.var).value }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::TBList;
    use std::thread;
    use std::mem;
    use std::sync::{Arc,Mutex};

    #[test]
    fn same_thread_id() {
        let id1 = current_thread_id();
        let id2 = current_thread_id();

        assert_eq!(id1, id2);
    }

    #[test]
    fn thread_id_formatting() {
        let strg = format!("{:?}", current_thread_id());
        assert!(strg.starts_with("thread("));
    }

    #[test]
    fn different_thread_id() {
        let id1 = current_thread_id();
        let id2 = thread::spawn(|| current_thread_id()).join().unwrap();

        assert!(id1 != id2);
    }

    #[test]
    fn round_tripping() {
        let y = 42;
        let mut cap = ThreadBound::new(y);

        assert!(cap.accessible());

        {
            let r1 : &i32 = &*cap;
            assert_eq!(*r1, 42);
        }

        {
            let r2 : &mut i32 = &mut *cap;
            assert_eq!(*r2, 42);
        }

        {
            let r3 : i32 = cap.into_inner();
            assert_eq!(r3, 42);
        }
    }

    #[test]
    fn wrong_thread_throws() {
        let mut cap = ThreadBound::new(42);
        let res: Box<&'static str> = thread::spawn(move || *cap = 55).join().err().unwrap().downcast().unwrap();
        assert_eq!(*res, "Attempt to access ThreadBound from incorrect thread")
    }

    #[test]
    fn wrong_thread_inaccessible() {
        let cap = ThreadBound::new(42);
        assert!(!thread::spawn(move || cap.accessible()).join().unwrap());
    }

    struct Trap(Arc<Mutex<bool>>);
    impl Drop for Trap {
        fn drop(&mut self) {
            (*self.0.lock().unwrap()) = true;
        }
    }

    #[test]
    fn inaccessible_after_teardown() {
        let cap = {
            let list = TBList::new();
            list.make_bound(42)
        };
        assert!(!cap.accessible());

        let error : Box<&'static str> = thread::spawn(|| {
            let mut cap2 = {
                let list = TBList::new();
                list.make_bound(42)
            };
            *cap2 = 55;
        }).join().err().unwrap().downcast().unwrap();

        assert_eq!(*error, "Attempt to access ThreadBound during TLS destruction phase");
    }

    #[test]
    fn sync_drop() {
        let was_dropped = Arc::new(Mutex::new(false));
        let cap = ThreadBound::new(Trap(was_dropped.clone()));
        mem::drop(cap);
        assert!(*was_dropped.lock().unwrap());
    }

    #[test]
    fn async_drop() {
        let was_dropped = Arc::new(Mutex::new(false));
        let was_dropped_2 = was_dropped.clone();
        let early_dropped = Arc::new(Mutex::new(false));
        let early_dropped_2 = early_dropped.clone();
        thread::spawn(move || {
            let cap = ThreadBound::new(Trap(was_dropped_2.clone()));
            thread::spawn(move || mem::drop(cap)).join().unwrap();
            (*early_dropped_2.lock().unwrap()) = *was_dropped_2.lock().unwrap();
        }).join().unwrap();
        assert!(!*early_dropped.lock().unwrap());
        assert!(*was_dropped.lock().unwrap());
    }
}
<|endoftext|>


<commit_before>//! Exposes the `Iron` type, the main entrance point of the
//! `Iron` library.

use std::io::net::ip::{SocketAddr, IpAddr};

use http::server::{Server, Config};
use http::server::request::{Star, AbsoluteUri, AbsolutePath, Authority};

use super::chain::Chain;
use super::chain::stackchain::StackChain;

use super::response::Response;
use super::request::Request;

pub type ServerT = Iron<StackChain>;

/// The primary entrance point to `Iron`, a `struct` to instantiate a new server.
///
/// The server can be made with a specific `Chain` (using `from_chain`)
/// or with a new `Chain` (using `new`). `Iron` is used to manage the server
/// processes:
/// `Iron.chain.link` is used to add new `Middleware`, and
/// `Iron.listen` is used to kick off a server process.
///
/// `Iron` contains the `Chain` which holds the `Middleware` necessary to run a server.
/// `Iron` is the main interface to adding `Middleware`, and has `Chain` as a
/// public field (for the sake of extensibility).
pub struct Iron<C> {
    /// Add `Middleware` to the `Iron's` `chain` so that requests
    /// are passed through those `Middleware`.
    /// `Middleware` is added to the chain with with `chain.link`.
    pub chain: C,
    ip: Option<IpAddr>,
    port: Option<u16>
}

impl<C: Clone> Clone for Iron<C> {
    fn clone(&self) -> Iron<C> {
        Iron {
            chain: self.chain.clone(),
            ip: self.ip.clone(),
            port: self.port
        }
    }
}

impl<C: Chain> Iron<C> {
    /// Kick off the server process.
    ///
    /// Call this once to begin listening for requests on the server.
    /// This is a blocking operation, and is the final op that should be called
    /// on the `Iron` instance. Once `listen` is called, requests will be
    /// handled as defined through the `Iron's` `chain's` `Middleware`.
    pub fn listen(mut self, ip: IpAddr, port: u16) {
        self.ip = Some(ip);
        self.port = Some(port);
        self.serve_forever();
    }

    /// Instantiate a new instance of `Iron`.
    ///
    /// This will create a new `Iron`, the base unit of the server.
    /// This creates an `Iron` with a default `chain`, the `StackChain`.
    ///
    /// Custom chains can be used with `from_chain`, instead of `new`.
    #[inline]
    pub fn new() -> Iron<C> {
        Iron {
            chain: Chain::new(),
            ip: None,
            port: None
        }
    }

    /// Instantiate a new instance of `Iron` from an existing `Chain`.
    ///
    /// This will create a new `Iron` from a give `Chain`.
    ///
    /// This `Chain` *may already have `Middleware` in it*. An empty default
    /// `Chain` can be created more easily using `new`.
    ///
    /// The `Chain` can also be configured to handle `Middleware` differently than
    /// `StackChain`. For example, this can be used to implement a `Chain`
    /// that logs debug messages as it serves requests.
    ///
    /// Most users will not need to touch `from_chain`. This should only be
    /// used if you need custom handling of `Middleware`.
    pub fn from_chain(chain: C) -> Iron<C> {
        Iron {
            chain: chain,
            ip: None,
            port: None
        }
    }
}

/// Unused, but required for internal functionality.
///
/// This `impl` allows `Iron` to be used as a `Server` by
/// [rust-http]('https://github.com/chris-morgan/rust-http').
/// This is not used by users of this library.
impl<C: Chain> Server for Iron<C> {
    fn get_config(&self) -> Config {
        Config { bind_address: SocketAddr {
            ip: self.ip.unwrap(),
            port: self.port.unwrap()
        } }
    }

    fn handle_request(&self, req: &Request, res: &mut Response) {
        let mut chain = self.chain.clone();
        let _ = chain.dispatch(&mut copy_request(req), res, None);
    }
}

// Makes up for no Clone impl on Request objects.
fn copy_request(req: &Request) -> Request {
    Request {
        remote_addr: req.remote_addr,
        headers: req.headers.clone(),
        body: req.body.clone(),
        method: req.method.clone(),
        request_uri: match req.request_uri {
            Star => Star,
            AbsoluteUri(ref u) => AbsoluteUri(u.clone()),
            AbsolutePath(ref p) => AbsolutePath(p.clone()),
            Authority(ref s) => Authority(s.clone())
        },
        close_connection: req.close_connection,
        version: (1, 1)
    }
}

<commit_msg>(fix) Updated to latest rust-http.<commit_after>//! Exposes the `Iron` type, the main entrance point of the
//! `Iron` library.

use std::io::net::ip::{SocketAddr, IpAddr};

use http::server::{Server, Config};

use super::chain::Chain;
use super::chain::stackchain::StackChain;

use super::response::Response;
use super::request::Request;

pub type ServerT = Iron<StackChain>;

/// The primary entrance point to `Iron`, a `struct` to instantiate a new server.
///
/// The server can be made with a specific `Chain` (using `from_chain`)
/// or with a new `Chain` (using `new`). `Iron` is used to manage the server
/// processes:
/// `Iron.chain.link` is used to add new `Middleware`, and
/// `Iron.listen` is used to kick off a server process.
///
/// `Iron` contains the `Chain` which holds the `Middleware` necessary to run a server.
/// `Iron` is the main interface to adding `Middleware`, and has `Chain` as a
/// public field (for the sake of extensibility).
pub struct Iron<C> {
    /// Add `Middleware` to the `Iron's` `chain` so that requests
    /// are passed through those `Middleware`.
    /// `Middleware` is added to the chain with with `chain.link`.
    pub chain: C,
    ip: Option<IpAddr>,
    port: Option<u16>
}

impl<C: Clone> Clone for Iron<C> {
    fn clone(&self) -> Iron<C> {
        Iron {
            chain: self.chain.clone(),
            ip: self.ip.clone(),
            port: self.port
        }
    }
}

impl<C: Chain> Iron<C> {
    /// Kick off the server process.
    ///
    /// Call this once to begin listening for requests on the server.
    /// This is a blocking operation, and is the final op that should be called
    /// on the `Iron` instance. Once `listen` is called, requests will be
    /// handled as defined through the `Iron's` `chain's` `Middleware`.
    pub fn listen(mut self, ip: IpAddr, port: u16) {
        self.ip = Some(ip);
        self.port = Some(port);
        self.serve_forever();
    }

    /// Instantiate a new instance of `Iron`.
    ///
    /// This will create a new `Iron`, the base unit of the server.
    /// This creates an `Iron` with a default `chain`, the `StackChain`.
    ///
    /// Custom chains can be used with `from_chain`, instead of `new`.
    #[inline]
    pub fn new() -> Iron<C> {
        Iron {
            chain: Chain::new(),
            ip: None,
            port: None
        }
    }

    /// Instantiate a new instance of `Iron` from an existing `Chain`.
    ///
    /// This will create a new `Iron` from a give `Chain`.
    ///
    /// This `Chain` *may already have `Middleware` in it*. An empty default
    /// `Chain` can be created more easily using `new`.
    ///
    /// The `Chain` can also be configured to handle `Middleware` differently than
    /// `StackChain`. For example, this can be used to implement a `Chain`
    /// that logs debug messages as it serves requests.
    ///
    /// Most users will not need to touch `from_chain`. This should only be
    /// used if you need custom handling of `Middleware`.
    pub fn from_chain(chain: C) -> Iron<C> {
        Iron {
            chain: chain,
            ip: None,
            port: None
        }
    }
}

/// Unused, but required for internal functionality.
///
/// This `impl` allows `Iron` to be used as a `Server` by
/// [rust-http]('https://github.com/chris-morgan/rust-http').
/// This is not used by users of this library.
impl<C: Chain> Server for Iron<C> {
    fn get_config(&self) -> Config {
        Config { bind_address: SocketAddr {
            ip: self.ip.unwrap(),
            port: self.port.unwrap()
        } }
    }

    fn handle_request(&self, mut req: Request, res: &mut Response) {
        let mut chain = self.chain.clone();
        let _ = chain.dispatch(&mut req, res, None);
    }
}
<|endoftext|>


<commit_before>// Copyright 2015-2016 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

//! Extension trait for factorization math on iterators.

use num;
use num::{One, FromPrimitive};
use num::{Num, Integer};
use crate::util::mod_pow;

/// Prime-factorization-based functions implemented on arbitrary
///  iterables of `(prime, power)` pairs.
///
/// There are certain preconditions for using these methods:
///
///   * In each pair, `prime` must actually be a prime;
///     It is forbidden to be zero, one, negative, or composite.
///   * `power` must not be zero.
///   * The primes must be sorted, with each appearing only once.
///
/// A diagnostic for violations of these conditions (with the exception
///  of non-compositeness) may be provided in debug builds.
pub trait FactorExt<X: Ord>: Iterator<Item = (X, usize)> {
    /// Recover an integer from its prime decomposition.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().factor_product(), 20);
    /// ```
    fn factor_product(self) -> X
    where
        X: Clone + One,
        Self: Sized,
    {
        self.fold(X::one(), |acc, (k, v)| acc * num::pow(k.clone(), v.clone()))
    }

    /// Compute the total number of positive integers which evenly divide
    ///  a number from its prime decomposition.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().divisor_count(), 6);
    /// ```
    fn divisor_count(self) -> X
    where
        X: Clone + FromPrimitive + One,
        Self: Sized,
    {
        // product( n[i]+1 );  we're counting the possible ways to select a power
        //                      from 0 to n[i] (inclusive) for each prime p[i]
        self.fold(X::one(), |acc, (_, v)| {
            acc * FromPrimitive::from_usize(v.clone() + 1).unwrap()
        })
    }

    /// Compute the sum of all positive integers which evenly divide the number
    ///  represented by the `Factorization` (including 1 and the number itself).
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().divisor_sum(), 42);
    /// ```
    fn divisor_sum(self) -> X
    where
        X: Clone + One + Num,
        Self: Sized,
    {
        // A geometric series for each factor
        self.fold(X::one(), |mut acc, (k, v)| {
            let numer = (num::pow(k.clone(), v.clone() + 1) - One::one());
            let denom = (k.clone() - One::one());
            acc * numer / denom
        })
    }

    /// Compute the Euler totient `phi(x)`, the total number of
    ///  positive integers less than `x` that are coprime to `x`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().totient(), 8);
    /// ```
    fn totient(self) -> X
    where
        X: Clone + One + Num,
        Self: Sized,
    {
        // product( (p[i] - 1) * pow(p[i], n[i]-1) )
        self.fold(X::one(), |acc, (k, v)| {
            acc * num::pow(k.clone(), v.clone() - 1) * (k.clone() - One::one())
        })
    }

    // FIXME: sigma_k for other k?

    // FIXME for now I see no issue with just returning a ::std::vec::IntoIter.  Do that.
    // TODO: pending unboxed abstract types
    // fn iter_divisors(&self) -> Iterator<K>

    /// Compute the value mod `m`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f: factor::Factored<_> = (1..=20u64).map(factor::factorize).product();
    /// assert_eq!(f.into_iter().factor_product_mod(&1297), 278);
    /// ```
    fn factor_product_mod(self, modulus: &X) -> X
    where
        X: Clone + One + Integer,
        Self: Sized,
    {
        self.fold(X::one(), |mut acc, (k, v)| {
            acc = acc * mod_pow(k.clone(), v.clone(), modulus.clone());
            acc = acc % modulus.clone();
            acc
        })
    }
}

impl<I, X: Ord> FactorExt<X> for I where I: Iterator<Item = (X, usize)> {}
<commit_msg>put ext trait on IntoIterator, not Iterator<commit_after>// Copyright 2015-2016 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

//! Extension trait for factorization math on iterators.

use num;
use num::{One, FromPrimitive};
use num::{Num, Integer};
use crate::util::mod_pow;

/// Prime-factorization-based functions implemented on arbitrary
///  iterables of `(prime, power)` pairs.
///
/// There are certain preconditions for using these methods:
///
///   * In each pair, `prime` must actually be a prime;
///     It is forbidden to be zero, one, negative, or composite.
///   * `power` must not be zero.
///   * The primes must be sorted, with each appearing only once.
///
/// A diagnostic for violations of these conditions (with the exception
///  of non-compositeness) may be provided in debug builds.
pub trait FactorExt<X: Ord>: IntoIterator<Item = (X, usize)> {
    /// Recover an integer from its prime decomposition.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().factor_product(), 20);
    /// ```
    fn factor_product(self) -> X
    where
        X: Clone + One,
        Self: Sized,
    {
        self.into_iter().fold(X::one(), |acc, (k, v)| acc * num::pow(k.clone(), v.clone()))
    }

    /// Compute the total number of positive integers which evenly divide
    ///  a number from its prime decomposition.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().divisor_count(), 6);
    /// ```
    fn divisor_count(self) -> X
    where
        X: Clone + FromPrimitive + One,
        Self: Sized,
    {
        // product( n[i]+1 );  we're counting the possible ways to select a power
        //                      from 0 to n[i] (inclusive) for each prime p[i]
        self.into_iter().fold(X::one(), |acc, (_, v)| {
            acc * FromPrimitive::from_usize(v.clone() + 1).unwrap()
        })
    }

    /// Compute the sum of all positive integers which evenly divide the number
    ///  represented by the `Factorization` (including 1 and the number itself).
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().divisor_sum(), 42);
    /// ```
    fn divisor_sum(self) -> X
    where
        X: Clone + One + Num,
        Self: Sized,
    {
        // A geometric series for each factor
        self.into_iter().fold(X::one(), |mut acc, (k, v)| {
            let numer = (num::pow(k.clone(), v.clone() + 1) - One::one());
            let denom = (k.clone() - One::one());
            acc * numer / denom
        })
    }

    /// Compute the Euler totient `phi(x)`, the total number of
    ///  positive integers less than `x` that are coprime to `x`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f = factor::factorize(20u64);
    /// assert_eq!(f.into_iter().totient(), 8);
    /// ```
    fn totient(self) -> X
    where
        X: Clone + One + Num,
        Self: Sized,
    {
        // product( (p[i] - 1) * pow(p[i], n[i]-1) )
        self.into_iter().fold(X::one(), |acc, (k, v)| {
            acc * num::pow(k.clone(), v.clone() - 1) * (k.clone() - One::one())
        })
    }

    // FIXME: sigma_k for other k?

    // FIXME for now I see no issue with just returning a ::std::vec::IntoIter.  Do that.
    // TODO: pending unboxed abstract types
    // fn iter_divisors(&self) -> Iterator<K>

    /// Compute the value mod `m`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f: factor::Factored<_> = (1..=20u64).map(factor::factorize).product();
    /// assert_eq!(f.into_iter().factor_product_mod(&1297), 278);
    /// ```
    fn factor_product_mod(self, modulus: &X) -> X
    where
        X: Clone + One + Integer,
        Self: Sized,
    {
        self.into_iter().fold(X::one(), |mut acc, (k, v)| {
            acc = acc * mod_pow(k.clone(), v.clone(), modulus.clone());
            acc = acc % modulus.clone();
            acc
        })
    }
}

impl<I, X: Ord> FactorExt<X> for I where I: IntoIterator<Item = (X, usize)> {}
<|endoftext|>


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

use Rng;
use distributions::Distribution;

/// The Bernoulli distribution.
///
/// This is a special case of the Binomial distribution where `n = 1`.
///
/// # Example
///
/// ```rust
/// use rand::distributions::{Bernoulli, Distribution};
///
/// let d = Bernoulli::new(0.3);
/// let v = d.sample(&mut rand::thread_rng());
/// println!("{} is from a Bernoulli distribution", v);
/// ```
///
/// # Precision
///
/// This `Bernoulli` distribution uses 64 bits from the RNG (a `u64`),
/// so only probabilities that are multiples of 2-64 can be
/// represented.
#[derive(Clone, Copy, Debug)]
pub struct Bernoulli {
    /// Probability of success, relative to the maximal integer.
    p_int: u64,
}

impl Bernoulli {
    /// Construct a new `Bernoulli` with the given probability of success `p`.
    ///
    /// # Panics
    ///
    /// If `p < 0` or `p > 1`.
    ///
    /// # Precision
    ///
    /// For `p = 1.0`, the resulting distribution will always generate true.
    /// For `p = 0.0`, the resulting distribution will always generate false.
    ///
    /// This method is accurate for any input `p` in the range `[0, 1]` which is
    /// a multiple of 2-64. (Note that not all multiples of
    /// 2-64 in `[0, 1]` can be represented as a `f64`.)
    #[inline]
    pub fn new(p: f64) -> Bernoulli {
        assert!((p >= 0.0) & (p <= 1.0), "Bernoulli::new not called with 0 <= p <= 0");
        let p_int = if p < 1.0 {
            (p * (::core::u64::MAX as f64)) as u64
        } else {
            // Avoid overflow: u64::MAX as f64 cannot be represented as u64.
            ::core::u64::MAX
        };
        Bernoulli { p_int }
    }
}

impl Distribution<bool> for Bernoulli {
    #[inline]
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> bool {
        // Make sure to always return true for p = 1.0.
        if self.p_int == ::core::u64::MAX {
            return true;
        }
        let r: u64 = rng.gen();
        r < self.p_int
    }
}

#[cfg(test)]
mod test {
    use Rng;
    use distributions::Distribution;
    use super::Bernoulli;

    #[test]
    fn test_trivial() {
        let mut r = ::test::rng(1);
        let always_false = Bernoulli::new(0.0);
        let always_true = Bernoulli::new(1.0);
        for _ in 0..5 {
            assert_eq!(r.sample::<bool, _>(&always_false), false);
            assert_eq!(r.sample::<bool, _>(&always_true), true);
            assert_eq!(Distribution::<bool>::sample(&always_false, &mut r), false);
            assert_eq!(Distribution::<bool>::sample(&always_true, &mut r), true);
        }
    }

    #[test]
    fn test_average() {
        const P: f64 = 0.3;
        let d = Bernoulli::new(P);
        const N: u32 = 10_000_000;

        let mut sum: u32 = 0;
        let mut rng = ::test::rng(2);
        for _ in 0..N {
            if d.sample(&mut rng) {
                sum += 1;
            }
        }
        let avg = (sum as f64) / (N as f64);

        assert!((avg - P).abs() < 1e-3);
    }
}
<commit_msg>Clarify constant in Bernoulli<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Bernoulli distribution.

use Rng;
use distributions::Distribution;

/// The Bernoulli distribution.
///
/// This is a special case of the Binomial distribution where `n = 1`.
///
/// # Example
///
/// ```rust
/// use rand::distributions::{Bernoulli, Distribution};
///
/// let d = Bernoulli::new(0.3);
/// let v = d.sample(&mut rand::thread_rng());
/// println!("{} is from a Bernoulli distribution", v);
/// ```
///
/// # Precision
///
/// This `Bernoulli` distribution uses 64 bits from the RNG (a `u64`),
/// so only probabilities that are multiples of 2-64 can be
/// represented.
#[derive(Clone, Copy, Debug)]
pub struct Bernoulli {
    /// Probability of success, relative to the maximal integer.
    p_int: u64,
}

impl Bernoulli {
    /// Construct a new `Bernoulli` with the given probability of success `p`.
    ///
    /// # Panics
    ///
    /// If `p < 0` or `p > 1`.
    ///
    /// # Precision
    ///
    /// For `p = 1.0`, the resulting distribution will always generate true.
    /// For `p = 0.0`, the resulting distribution will always generate false.
    ///
    /// This method is accurate for any input `p` in the range `[0, 1]` which is
    /// a multiple of 2-64. (Note that not all multiples of
    /// 2-64 in `[0, 1]` can be represented as a `f64`.)
    #[inline]
    pub fn new(p: f64) -> Bernoulli {
        assert!((p >= 0.0) & (p <= 1.0), "Bernoulli::new not called with 0 <= p <= 0");
        // Technically, this should be 2^64 or `u64::MAX + 1` because we compare
        // using `<` when sampling. However, `u64::MAX` rounds to an `f64`
        // larger than `u64::MAX` anyway.
        const MAX_P_INT: f64 = ::core::u64::MAX as f64;
        let p_int = if p < 1.0 {
            (p * MAX_P_INT) as u64
        } else {
            // Avoid overflow: `MAX_P_INT` cannot be represented as u64.
            ::core::u64::MAX
        };
        Bernoulli { p_int }
    }
}

impl Distribution<bool> for Bernoulli {
    #[inline]
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> bool {
        // Make sure to always return true for p = 1.0.
        if self.p_int == ::core::u64::MAX {
            return true;
        }
        let r: u64 = rng.gen();
        r < self.p_int
    }
}

#[cfg(test)]
mod test {
    use Rng;
    use distributions::Distribution;
    use super::Bernoulli;

    #[test]
    fn test_trivial() {
        let mut r = ::test::rng(1);
        let always_false = Bernoulli::new(0.0);
        let always_true = Bernoulli::new(1.0);
        for _ in 0..5 {
            assert_eq!(r.sample::<bool, _>(&always_false), false);
            assert_eq!(r.sample::<bool, _>(&always_true), true);
            assert_eq!(Distribution::<bool>::sample(&always_false, &mut r), false);
            assert_eq!(Distribution::<bool>::sample(&always_true, &mut r), true);
        }
    }

    #[test]
    fn test_average() {
        const P: f64 = 0.3;
        let d = Bernoulli::new(P);
        const N: u32 = 10_000_000;

        let mut sum: u32 = 0;
        let mut rng = ::test::rng(2);
        for _ in 0..N {
            if d.sample(&mut rng) {
                sum += 1;
            }
        }
        let avg = (sum as f64) / (N as f64);

        assert!((avg - P).abs() < 1e-3);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::TransactionContext;
use libra_crypto::{ed25519::Ed25519PublicKey, x25519};
use libra_management::error::Error;
use libra_secure_json_rpc::VMStatusView;
use libra_types::{validator_config::ValidatorConfig, validator_info::ValidatorInfo};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(about = "Tool used for Operators")]
pub enum Command {
    #[structopt(about = "Set the waypoint in the validator storage")]
    InsertWaypoint(crate::waypoint::InsertWaypoint),
    #[structopt(about = "Sets the validator config")]
    SetValidatorConfig(crate::validator_config::SetValidatorConfig),
    #[structopt(about = "Rotates the consensus key for a validator")]
    RotateConsensusKey(crate::validator_config::RotateConsensusKey),
    #[structopt(about = "Rotates a full node network key")]
    RotateFullNodeNetworkKey(crate::validator_config::RotateFullNodeNetworkKey),
    #[structopt(about = "Rotates a validator network key")]
    RotateValidatorNetworkKey(crate::validator_config::RotateValidatorNetworkKey),
    #[structopt(about = "Validates a transaction")]
    ValidateTransaction(crate::validate_transaction::ValidateTransaction),
    #[structopt(about = "Displays the current validator config registered on the blockchain")]
    ValidatorConfig(crate::validator_config::ValidatorConfig),
    #[structopt(about = "Displays the current validator set infos registered on the blockchain")]
    ValidatorSet(crate::validator_set::ValidatorSet),
}

#[derive(Debug, PartialEq)]
pub enum CommandName {
    InsertWaypoint,
    SetValidatorConfig,
    RotateConsensusKey,
    RotateFullNodeNetworkKey,
    RotateValidatorNetworkKey,
    ValidateTransaction,
    ValidatorConfig,
    ValidatorSet,
}

impl From<&Command> for CommandName {
    fn from(command: &Command) -> Self {
        match command {
            Command::InsertWaypoint(_) => CommandName::InsertWaypoint,
            Command::SetValidatorConfig(_) => CommandName::SetValidatorConfig,
            Command::RotateConsensusKey(_) => CommandName::RotateConsensusKey,
            Command::RotateFullNodeNetworkKey(_) => CommandName::RotateFullNodeNetworkKey,
            Command::RotateValidatorNetworkKey(_) => CommandName::RotateValidatorNetworkKey,
            Command::ValidateTransaction(_) => CommandName::ValidateTransaction,
            Command::ValidatorConfig(_) => CommandName::ValidatorConfig,
            Command::ValidatorSet(_) => CommandName::ValidatorSet,
        }
    }
}

impl std::fmt::Display for CommandName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        let name = match self {
            CommandName::InsertWaypoint => "insert-waypoint",
            CommandName::SetValidatorConfig => "set-validator-config",
            CommandName::RotateConsensusKey => "rotate-consensus-key",
            CommandName::RotateFullNodeNetworkKey => "rotate-fullnode-network-key",
            CommandName::RotateValidatorNetworkKey => "rotate-validator-network-key",
            CommandName::ValidateTransaction => "validate-transaction",
            CommandName::ValidatorConfig => "validator-config",
            CommandName::ValidatorSet => "validator-set",
        };
        write!(f, "{}", name)
    }
}

impl Command {
    pub fn execute(self) -> String {
        match self {
            Command::InsertWaypoint(cmd) => {
                format!("{:?}", cmd.execute().map(|()| "success").unwrap())
            }
            Command::SetValidatorConfig(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::RotateConsensusKey(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::RotateFullNodeNetworkKey(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::RotateValidatorNetworkKey(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::ValidateTransaction(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::ValidatorConfig(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::ValidatorSet(cmd) => format!("{:?}", cmd.execute().unwrap()),
        }
    }

    pub fn insert_waypoint(self) -> Result<(), Error> {
        match self {
            Command::InsertWaypoint(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::InsertWaypoint)),
        }
    }

    pub fn set_validator_config(self) -> Result<TransactionContext, Error> {
        match self {
            Command::SetValidatorConfig(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::SetValidatorConfig)),
        }
    }

    pub fn rotate_consensus_key(self) -> Result<(TransactionContext, Ed25519PublicKey), Error> {
        match self {
            Command::RotateConsensusKey(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::RotateConsensusKey)),
        }
    }

    pub fn rotate_fullnode_network_key(
        self,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        match self {
            Command::RotateFullNodeNetworkKey(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::RotateFullNodeNetworkKey)),
        }
    }

    pub fn rotate_validator_network_key(
        self,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        match self {
            Command::RotateValidatorNetworkKey(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::RotateValidatorNetworkKey)),
        }
    }

    pub fn validate_transaction(self) -> Result<Option<VMStatusView>, Error> {
        match self {
            Command::ValidateTransaction(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::ValidateTransaction)),
        }
    }

    pub fn validator_config(self) -> Result<ValidatorConfig, Error> {
        match self {
            Command::ValidatorConfig(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::ValidatorConfig)),
        }
    }

    pub fn validator_set(self) -> Result<Vec<ValidatorInfo>, Error> {
        match self {
            Command::ValidatorSet(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::ValidatorSet)),
        }
    }

    fn unexpected_command(self, expected: CommandName) -> Error {
        Error::UnexpectedCommand(expected.to_string(), CommandName::from(&self).to_string())
    }
}
<commit_msg>[management] operational aesthetic improvements<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::TransactionContext;
use libra_crypto::{ed25519::Ed25519PublicKey, x25519};
use libra_management::error::Error;
use libra_secure_json_rpc::VMStatusView;
use libra_types::{validator_config::ValidatorConfig, validator_info::ValidatorInfo};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(about = "Tool used for Operators")]
pub enum Command {
    #[structopt(about = "Set the waypoint in the validator storage")]
    InsertWaypoint(crate::waypoint::InsertWaypoint),
    #[structopt(about = "Rotates the consensus key for a validator")]
    RotateConsensusKey(crate::validator_config::RotateConsensusKey),
    #[structopt(about = "Rotates a full node network key")]
    RotateFullNodeNetworkKey(crate::validator_config::RotateFullNodeNetworkKey),
    #[structopt(about = "Rotates a validator network key")]
    RotateValidatorNetworkKey(crate::validator_config::RotateValidatorNetworkKey),
    #[structopt(about = "Sets the validator config")]
    SetValidatorConfig(crate::validator_config::SetValidatorConfig),
    #[structopt(about = "Validates a transaction")]
    ValidateTransaction(crate::validate_transaction::ValidateTransaction),
    #[structopt(about = "Displays the current validator config registered on the blockchain")]
    ValidatorConfig(crate::validator_config::ValidatorConfig),
    #[structopt(about = "Displays the current validator set infos registered on the blockchain")]
    ValidatorSet(crate::validator_set::ValidatorSet),
}

#[derive(Debug, PartialEq)]
pub enum CommandName {
    InsertWaypoint,
    RotateConsensusKey,
    RotateFullNodeNetworkKey,
    RotateValidatorNetworkKey,
    SetValidatorConfig,
    ValidateTransaction,
    ValidatorConfig,
    ValidatorSet,
}

impl From<&Command> for CommandName {
    fn from(command: &Command) -> Self {
        match command {
            Command::InsertWaypoint(_) => CommandName::InsertWaypoint,
            Command::RotateConsensusKey(_) => CommandName::RotateConsensusKey,
            Command::RotateFullNodeNetworkKey(_) => CommandName::RotateFullNodeNetworkKey,
            Command::RotateValidatorNetworkKey(_) => CommandName::RotateValidatorNetworkKey,
            Command::SetValidatorConfig(_) => CommandName::SetValidatorConfig,
            Command::ValidateTransaction(_) => CommandName::ValidateTransaction,
            Command::ValidatorConfig(_) => CommandName::ValidatorConfig,
            Command::ValidatorSet(_) => CommandName::ValidatorSet,
        }
    }
}

impl std::fmt::Display for CommandName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        let name = match self {
            CommandName::InsertWaypoint => "insert-waypoint",
            CommandName::RotateConsensusKey => "rotate-consensus-key",
            CommandName::RotateFullNodeNetworkKey => "rotate-fullnode-network-key",
            CommandName::RotateValidatorNetworkKey => "rotate-validator-network-key",
            CommandName::SetValidatorConfig => "set-validator-config",
            CommandName::ValidateTransaction => "validate-transaction",
            CommandName::ValidatorConfig => "validator-config",
            CommandName::ValidatorSet => "validator-set",
        };
        write!(f, "{}", name)
    }
}

impl Command {
    pub fn execute(self) -> String {
        match self {
            Command::InsertWaypoint(cmd) => {
                format!("{:?}", cmd.execute().map(|()| "success").unwrap())
            }
            Command::RotateConsensusKey(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::RotateFullNodeNetworkKey(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::RotateValidatorNetworkKey(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::SetValidatorConfig(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::ValidateTransaction(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::ValidatorConfig(cmd) => format!("{:?}", cmd.execute().unwrap()),
            Command::ValidatorSet(cmd) => format!("{:?}", cmd.execute().unwrap()),
        }
    }

    pub fn insert_waypoint(self) -> Result<(), Error> {
        match self {
            Command::InsertWaypoint(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::InsertWaypoint)),
        }
    }

    pub fn rotate_consensus_key(self) -> Result<(TransactionContext, Ed25519PublicKey), Error> {
        match self {
            Command::RotateConsensusKey(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::RotateConsensusKey)),
        }
    }

    pub fn rotate_fullnode_network_key(
        self,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        match self {
            Command::RotateFullNodeNetworkKey(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::RotateFullNodeNetworkKey)),
        }
    }

    pub fn rotate_validator_network_key(
        self,
    ) -> Result<(TransactionContext, x25519::PublicKey), Error> {
        match self {
            Command::RotateValidatorNetworkKey(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::RotateValidatorNetworkKey)),
        }
    }

    pub fn set_validator_config(self) -> Result<TransactionContext, Error> {
        match self {
            Command::SetValidatorConfig(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::SetValidatorConfig)),
        }
    }

    pub fn validate_transaction(self) -> Result<Option<VMStatusView>, Error> {
        match self {
            Command::ValidateTransaction(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::ValidateTransaction)),
        }
    }

    pub fn validator_config(self) -> Result<ValidatorConfig, Error> {
        match self {
            Command::ValidatorConfig(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::ValidatorConfig)),
        }
    }

    pub fn validator_set(self) -> Result<Vec<ValidatorInfo>, Error> {
        match self {
            Command::ValidatorSet(cmd) => cmd.execute(),
            _ => Err(self.unexpected_command(CommandName::ValidatorSet)),
        }
    }

    fn unexpected_command(self, expected: CommandName) -> Error {
        Error::UnexpectedCommand(expected.to_string(), CommandName::from(&self).to_string())
    }
}
<|endoftext|>


<commit_before><commit_msg>Allow disabling perf access via `RA_DISABLE_PERF`<commit_after><|endoftext|>


<commit_before>//!
//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! `knob::Settings` expects all values to implement `Show` + `FromStr` and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading yourself.
//!
//! `knob` is typesafe in a sense that it will return the expected type you wanted if possible and
//! fails otherwise.
//!
//! `knob` allows you to decorate the `Settings` structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an IP address in `knob`:
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use std::io::net::ip::IpAddr;
//! use knob::Settings;
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set("ip", "0.0.0.0");
//!   let socket: IpAddr = settings.fetch("ip").unwrap();
//!   assert_eq!(socket.to_str(), "0.0.0.0".to_owned());
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use knob::Settings;
//! use std::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip").unwrap();
//!   assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement `Show`:
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use knob::Settings;
//! use std::io::net::ip::IpAddr;
//!
//! #[deriving(Show)]
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip).unwrap();
//!   assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! `knob` allows you to register command line options to read from the command line later.
//!
//! The options are `getopts` option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! extern crate getopts;
//! extern crate knob;
//!
//! use getopts::optopt;
//! use knob::Settings;
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"));
//!   settings.opt(optopt("e", "environment", "the environment to run in", ""));
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println!("{}", settings.usage("Try one of these:"));
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use knob::Settings;
//! use std::io::net::ip::{IpAddr,Ipv4Addr,SocketAddr};
//!
//! #[deriving(Show)]
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     self.fetch_with(Addr, |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     })
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.ip();
//!   assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
//! }
//! ~~~
//!
//! knob goes up to 11.

#![crate_id = "github.com/skade/knob#knob:1.1.1"]
#![crate_type = "lib"]
#![comment = "A convenient Rust settings system"]
#![license = "MIT"]

extern crate getopts;
extern crate collections;

use collections::hashmap::HashMap;
use std::os;
use std::from_str::FromStr;
use std::to_str::ToStr;

use getopts::{usage,getopts,OptGroup};
use getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  store: HashMap<~str,~str>,
  options: Box<Vec<OptGroup>>,
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: box Vec::new() }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// value is not None. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if value.is_some() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to the given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: |Option<T>| -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for later use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: Vec<~str>) -> Option<Fail_> {
    let ref prog_name = args.get(0);

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options.as_slice()) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have a brief message included before the usage strings.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options.as_slice())
  }
}

<commit_msg>Version bump to 1.1.2<commit_after>//!
//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! `knob::Settings` expects all values to implement `Show` + `FromStr` and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading yourself.
//!
//! `knob` is typesafe in a sense that it will return the expected type you wanted if possible and
//! fails otherwise.
//!
//! `knob` allows you to decorate the `Settings` structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an IP address in `knob`:
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use std::io::net::ip::IpAddr;
//! use knob::Settings;
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set("ip", "0.0.0.0");
//!   let socket: IpAddr = settings.fetch("ip").unwrap();
//!   assert_eq!(socket.to_str(), "0.0.0.0".to_owned());
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use knob::Settings;
//! use std::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip").unwrap();
//!   assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement `Show`:
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use knob::Settings;
//! use std::io::net::ip::IpAddr;
//!
//! #[deriving(Show)]
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip).unwrap();
//!   assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! `knob` allows you to register command line options to read from the command line later.
//!
//! The options are `getopts` option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! extern crate getopts;
//! extern crate knob;
//!
//! use getopts::optopt;
//! use knob::Settings;
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"));
//!   settings.opt(optopt("e", "environment", "the environment to run in", ""));
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println!("{}", settings.usage("Try one of these:"));
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! extern crate knob;
//!
//! use knob::Settings;
//! use std::io::net::ip::{IpAddr,Ipv4Addr,SocketAddr};
//!
//! #[deriving(Show)]
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     self.fetch_with(Addr, |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     })
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//!
//! fn main() {
//!   let mut settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.ip();
//!   assert_eq!(socket.to_str(), "::0.0.0.1".to_owned());
//! }
//! ~~~
//!
//! knob goes up to 11.

#![crate_id = "github.com/skade/knob#knob:1.1.2"]
#![crate_type = "lib"]
#![comment = "A convenient Rust settings system"]
#![license = "MIT"]

extern crate getopts;
extern crate collections;

use collections::hashmap::HashMap;
use std::os;
use std::from_str::FromStr;
use std::to_str::ToStr;

use getopts::{usage,getopts,OptGroup};
use getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  store: HashMap<~str,~str>,
  options: Box<Vec<OptGroup>>,
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: box Vec::new() }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// value is not None. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if value.is_some() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to the given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: |Option<T>| -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for later use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: Vec<~str>) -> Option<Fail_> {
    let ref prog_name = args.get(0);

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options.as_slice()) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have a brief message included before the usage strings.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options.as_slice())
  }
}

<|endoftext|>


<commit_before>use dces::prelude::{Entity, World};
use std::{cell::RefCell, collections::HashMap, sync::mpsc};

use crate::{
    prelude::*,
    properties::Constraint,
    render, shell,
    shell::{ShellRequest, WindowRequest, WindowSettings},
    tree::Tree,
    utils::{Point, Rectangle},
};

/// Represents a window. Each window has its own tree, event pipeline and shell.
pub struct WindowAdapter {
    world: World<Tree, StringComponentStore, render::RenderContext2D>,
    ctx: ContextProvider,
}

impl WindowAdapter {
    /// Creates a new WindowAdapter.
    pub fn new(
        world: World<Tree, StringComponentStore, render::RenderContext2D>,
        ctx: ContextProvider,
    ) -> Self {
        WindowAdapter { world, ctx }
    }
}

impl WindowAdapter {
    fn root(&mut self) -> Entity {
        self.world
            .entity_component_manager()
            .entity_store()
            .root
            .unwrap()
    }
}

impl shell::WindowAdapter for WindowAdapter {
    fn resize(&mut self, width: f64, height: f64) {
        let root = self.root();
        self.ctx
            .event_queue
            .borrow_mut()
            .register_event_with_strategy(
                WindowEvent::Resize { width, height },
                EventStrategy::Direct,
                root,
            );
    }

    fn mouse(&mut self, x: f64, y: f64) {
        let root = self.root();
        self.ctx.mouse_position.set(Point::new(x, y));
        self.ctx
            .event_queue
            .borrow_mut()
            .register_event(MouseMoveEvent { x, y }, root)
    }

    fn scroll(&mut self, delta_x: f64, delta_y: f64) {
        let root = self.root();
        self.ctx.event_queue.borrow_mut().register_event(
            ScrollEvent {
                delta: Point::new(delta_x, delta_y),
            },
            root,
        )
    }

    fn mouse_event(&mut self, event: shell::MouseEvent) {
        let root = self.root();
        match event.state {
            shell::ButtonState::Up => {
                self.ctx.event_queue.borrow_mut().register_event(
                    MouseUpEvent {
                        x: event.x,
                        y: event.y,
                        button: event.button,
                    },
                    root,
                );
                self.ctx.event_queue.borrow_mut().register_event(
                    GlobalMouseUpEvent {
                        x: event.x,
                        y: event.y,
                        button: event.button,
                    },
                    root,
                );
            }
            shell::ButtonState::Down => self.ctx.event_queue.borrow_mut().register_event(
                MouseDownEvent {
                    x: event.x,
                    y: event.y,
                    button: event.button,
                },
                root,
            ),
        }
    }

    fn mouse_position(&self) -> Point {
        self.ctx.mouse_position.get()
    }

    fn key_event(&mut self, event: shell::KeyEvent) {
        let root = self.root();
        match event.state {
            shell::ButtonState::Up => self
                .ctx
                .event_queue
                .borrow_mut()
                .register_event(KeyUpEvent { event }, root),
            shell::ButtonState::Down => self
                .ctx
                .event_queue
                .borrow_mut()
                .register_event(KeyDownEvent { event }, root),
        }
    }

    fn quit_event(&mut self) {
        let root = self.root();

        self.ctx
            .event_queue
            .borrow_mut()
            .register_event(SystemEvent::Quit, root);
    }

    fn active(&mut self, active: bool) {
        let root = self.root();

        self.ctx
            .event_queue
            .borrow_mut()
            .register_event_with_strategy(
                WindowEvent::ActiveChanged(active),
                EventStrategy::Direct,
                root,
            );
    }

    fn run(&mut self, render_context: &mut render::RenderContext2D) {
        self.world.run_with_context(render_context);
    }
}

/// Creates a `WindowAdapter` and a `WindowSettings` object from a window builder closure.
pub fn create_window<F: Fn(&mut BuildContext) -> Entity + 'static>(
    app_name: impl Into<String>,
    request_sender: mpsc::Sender<ShellRequest<WindowAdapter>>,
    create_fn: F,
) -> (WindowAdapter, WindowSettings, mpsc::Receiver<WindowRequest>) {
    let app_name = app_name.into();
    let mut world: World<Tree, StringComponentStore, render::RenderContext2D> =
        World::from_stores(Tree::default(), StringComponentStore::default());

    let (sender, receiver) = mpsc::channel();

    let registry = Rc::new(RefCell::new(Registry::new()));

    if app_name.is_empty() {
        registry
            .borrow_mut()
            .register("settings", Settings::default());
    } else {
        registry
            .borrow_mut()
            .register("settings", Settings::new(app_name.clone()));
    };

    let context_provider = ContextProvider::new(sender, request_sender.clone(), app_name);

    let theme = crate::theme::default_theme();

    let window = {
        let overlay = Overlay::new().build(&mut BuildContext::new(
            world.entity_component_manager(),
            &context_provider.render_objects,
            &context_provider.layouts,
            &context_provider.handler_map,
            &mut *context_provider.states.borrow_mut(),
            &theme,
        ));

        {
            let tree: &mut Tree = world.entity_component_manager().entity_store_mut();
            tree.set_overlay(overlay);
        }

        let window = create_fn(&mut BuildContext::new(
            world.entity_component_manager(),
            &context_provider.render_objects,
            &context_provider.layouts,
            &context_provider.handler_map,
            &mut *context_provider.states.borrow_mut(),
            &theme,
        ));

        {
            let tree: &mut Tree = world.entity_component_manager().entity_store_mut();
            tree.set_root(window);
        }

        window
    };

    let constraint = *world
        .entity_component_manager()
        .component_store()
        .get::<Constraint>("constraint", window)
        .unwrap();

    let position = *world
        .entity_component_manager()
        .component_store()
        .get::<Point>("position", window)
        .unwrap();

    let mut fonts = HashMap::new();
    fonts.insert(
        "Roboto Regular".to_string(),
        crate::theme::fonts::ROBOTO_REGULAR_FONT,
    );
    fonts.insert(
        "Roboto Medium".to_string(),
        crate::theme::fonts::ROBOTO_MEDIUM_FONT,
    );
    fonts.insert(
        "Material Icons".to_string(),
        crate::theme::fonts::MATERIAL_ICONS_REGULAR_FONT,
    );

    let settings = WindowSettings {
        title: world
            .entity_component_manager()
            .component_store()
            .get::<String>("title", window)
            .unwrap()
            .clone(),
        borderless: *world
            .entity_component_manager()
            .component_store()
            .get::<bool>("borderless", window)
            .unwrap(),
        resizeable: *world
            .entity_component_manager()
            .component_store()
            .get::<bool>("resizeable", window)
            .unwrap(),
        always_on_top: *world
            .entity_component_manager()
            .component_store()
            .get::<bool>("always_on_top", window)
            .unwrap(),
        position: (position.x, position.y),
        size: (constraint.width(), constraint.height()),
        fonts,
    };

    world
        .entity_component_manager()
        .component_store_mut()
        .register("global", window, Global::default());
    world
        .entity_component_manager()
        .component_store_mut()
        .register("global", window, Global::default());
    world
        .entity_component_manager()
        .component_store_mut()
        .register(
            "bounds",
            window,
            Rectangle::from((0.0, 0.0, constraint.width(), constraint.height())),
        );

    world.register_init_system(InitSystem::new(context_provider.clone(), registry.clone()));

    world.register_cleanup_system(CleanupSystem::new(
        context_provider.clone(),
        registry.clone(),
    ));

    world
        .create_system(EventStateSystem::new(
            context_provider.clone(),
            registry.clone(),
        ))
        .with_priority(0)
        .build();

    world
        .create_system(LayoutSystem::new(context_provider.clone()))
        .with_priority(1)
        .build();

    world
        .create_system(PostLayoutStateSystem::new(
            context_provider.clone(),
            registry.clone(),
        ))
        .with_priority(2)
        .build();

    world
        .create_system(RenderSystem::new(context_provider.clone()))
        .with_priority(3)
        .build();

    (
        WindowAdapter::new(world, context_provider),
        settings,
        receiver,
    )
}
<commit_msg>api: application: windows_adapter update<commit_after>use dces::prelude::{Entity, World};
use std::{cell::RefCell, collections::HashMap, sync::mpsc};

use crate::{
    prelude::*,
    properties::Constraint,
    render, shell,
    shell::{ShellRequest, WindowRequest, WindowSettings},
    tree::Tree,
    utils::{Point, Rectangle},
};

/// Represents a window. Each window has its own tree, event pipeline and shell.
pub struct WindowAdapter {
    world: World<Tree, StringComponentStore, render::RenderContext2D>,
    ctx: ContextProvider,
}

impl WindowAdapter {
    /// Creates a new WindowAdapter.
    pub fn new(
        world: World<Tree, StringComponentStore, render::RenderContext2D>,
        ctx: ContextProvider,
    ) -> Self {
        WindowAdapter { world, ctx }
    }
}

impl WindowAdapter {
    fn root(&mut self) -> Entity {
        self.world
            .entity_component_manager()
            .entity_store()
            .root
            .unwrap()
    }
}

impl shell::WindowAdapter for WindowAdapter {
    fn resize(&mut self, width: f64, height: f64) {
        let root = self.root();
        self.ctx
            .event_queue
            .borrow_mut()
            .register_event_with_strategy(
                WindowEvent::Resize { width, height },
                EventStrategy::Direct,
                root,
            );
    }

    fn mouse(&mut self, x: f64, y: f64) {
        let root = self.root();
        self.ctx.mouse_position.set(Point::new(x, y));
        self.ctx
            .event_queue
            .borrow_mut()
            .register_event(MouseMoveEvent { x, y }, root)
    }

    fn scroll(&mut self, delta_x: f64, delta_y: f64) {
        let root = self.root();
        self.ctx.event_queue.borrow_mut().register_event(
            ScrollEvent {
                delta: Point::new(delta_x, delta_y),
            },
            root,
        )
    }

    fn mouse_event(&mut self, event: shell::MouseEvent) {
        let root = self.root();
        match event.state {
            shell::ButtonState::Up => {
                self.ctx.event_queue.borrow_mut().register_event(
                    MouseUpEvent {
                        x: event.x,
                        y: event.y,
                        button: event.button,
                    },
                    root,
                );
                self.ctx.event_queue.borrow_mut().register_event(
                    GlobalMouseUpEvent {
                        x: event.x,
                        y: event.y,
                        button: event.button,
                    },
                    root,
                );
            }
            shell::ButtonState::Down => self.ctx.event_queue.borrow_mut().register_event(
                MouseDownEvent {
                    x: event.x,
                    y: event.y,
                    button: event.button,
                },
                root,
            ),
        }
    }

    fn mouse_position(&self) -> Point {
        self.ctx.mouse_position.get()
    }

    fn key_event(&mut self, event: shell::KeyEvent) {
        let root = self.root();
        match event.state {
            shell::ButtonState::Up => self
                .ctx
                .event_queue
                .borrow_mut()
                .register_event(KeyUpEvent { event }, root),
            shell::ButtonState::Down => self
                .ctx
                .event_queue
                .borrow_mut()
                .register_event(KeyDownEvent { event }, root),
        }
    }

    fn quit_event(&mut self) {
        let root = self.root();

        self.ctx
            .event_queue
            .borrow_mut()
            .register_event(SystemEvent::Quit, root);
    }

    fn active(&mut self, active: bool) {
        let root = self.root();

        self.ctx
            .event_queue
            .borrow_mut()
            .register_event_with_strategy(
                WindowEvent::ActiveChanged(active),
                EventStrategy::Direct,
                root,
            );
    }

    fn run(&mut self, render_context: &mut render::RenderContext2D) {
        self.world.run_with_context(render_context);
    }
}

/// Creates a `WindowAdapter` and a `WindowSettings` object from a window builder closure.
pub fn create_window<F: Fn(&mut BuildContext) -> Entity + 'static>(
    app_name: impl Into<String>,
    request_sender: mpsc::Sender<ShellRequest<WindowAdapter>>,
    create_fn: F,
) -> (WindowAdapter, WindowSettings, mpsc::Receiver<WindowRequest>) {
    let app_name = app_name.into();
    let mut world: World<Tree, StringComponentStore, render::RenderContext2D> =
        World::from_stores(Tree::default(), StringComponentStore::default());

    let (sender, receiver) = mpsc::channel();

    let registry = Rc::new(RefCell::new(Registry::new()));

    if app_name.is_empty() {
        registry
            .borrow_mut()
            .register("settings", Settings::default());
    } else {
        registry
            .borrow_mut()
            .register("settings", Settings::new(app_name.clone()));
    };

    let context_provider = ContextProvider::new(sender, request_sender.clone(), app_name);

    let theme = crate::theme::default_theme();

    let window = {
        let overlay = Overlay::new().build(&mut BuildContext::new(
            world.entity_component_manager(),
            &context_provider.render_objects,
            &context_provider.layouts,
            &context_provider.handler_map,
            &mut *context_provider.states.borrow_mut(),
            &theme,
        ));

        {
            let tree: &mut Tree = world.entity_component_manager().entity_store_mut();
            tree.set_overlay(overlay);
        }

        let window = create_fn(&mut BuildContext::new(
            world.entity_component_manager(),
            &context_provider.render_objects,
            &context_provider.layouts,
            &context_provider.handler_map,
            &mut *context_provider.states.borrow_mut(),
            &theme,
        ));

        {
            let tree: &mut Tree = world.entity_component_manager().entity_store_mut();
            tree.set_root(window);
        }

        window
    };

    let constraint = *world
        .entity_component_manager()
        .component_store()
        .get::<Constraint>("constraint", window)
        .unwrap();

    let position = *world
        .entity_component_manager()
        .component_store()
        .get::<Point>("position", window)
        .unwrap();

    let mut fonts = HashMap::new();
    fonts.insert(
        "Roboto Regular".to_string(),
        crate::theme::fonts::ROBOTO_REGULAR_FONT,
    );
    fonts.insert(
        "Roboto Medium".to_string(),
        crate::theme::fonts::ROBOTO_MEDIUM_FONT,
    );
    fonts.insert(
        "Material Icons".to_string(),
        crate::theme::fonts::MATERIAL_ICONS_FONT_TTF,
    );

    let settings = WindowSettings {
        title: world
            .entity_component_manager()
            .component_store()
            .get::<String>("title", window)
            .unwrap()
            .clone(),
        borderless: *world
            .entity_component_manager()
            .component_store()
            .get::<bool>("borderless", window)
            .unwrap(),
        resizeable: *world
            .entity_component_manager()
            .component_store()
            .get::<bool>("resizeable", window)
            .unwrap(),
        always_on_top: *world
            .entity_component_manager()
            .component_store()
            .get::<bool>("always_on_top", window)
            .unwrap(),
        position: (position.x, position.y),
        size: (constraint.width(), constraint.height()),
        fonts,
    };

    world
        .entity_component_manager()
        .component_store_mut()
        .register("global", window, Global::default());
    world
        .entity_component_manager()
        .component_store_mut()
        .register("global", window, Global::default());
    world
        .entity_component_manager()
        .component_store_mut()
        .register(
            "bounds",
            window,
            Rectangle::from((0.0, 0.0, constraint.width(), constraint.height())),
        );

    world.register_init_system(InitSystem::new(context_provider.clone(), registry.clone()));

    world.register_cleanup_system(CleanupSystem::new(
        context_provider.clone(),
        registry.clone(),
    ));

    world
        .create_system(EventStateSystem::new(
            context_provider.clone(),
            registry.clone(),
        ))
        .with_priority(0)
        .build();

    world
        .create_system(LayoutSystem::new(context_provider.clone()))
        .with_priority(1)
        .build();

    world
        .create_system(PostLayoutStateSystem::new(
            context_provider.clone(),
            registry.clone(),
        ))
        .with_priority(2)
        .build();

    world
        .create_system(RenderSystem::new(context_provider.clone()))
        .with_priority(3)
        .build();

    (
        WindowAdapter::new(world, context_provider),
        settings,
        receiver,
    )
}
<|endoftext|>