<commit_before>//! Implements a database that stores results of previously performed
//! searches.
//!
//! Using such a database (called "transposition table") is a way to
//! greatly reduce the search space of a chess tree with little
//! negative impact. Chess programs, during their brute-force search,
//! encounter the same positions again and again, but from different
//! sequences of moves, which is called a transposition.
//!
//! When the search encounters a transposition, it is beneficial to
//! "remember" what was determined last time the position was
//! examined, rather than redoing the entire search again. For this
//! reason, chess programs have a transposition table, which is a
//! large hash table storing information about positions previously
//! searched, how deeply they were searched, and what we concluded
//! about them.

use std;
use std::cell::{UnsafeCell, Cell};
use std::mem::transmute;
use std::num::Wrapping;
use basetypes::Value;
use chess_move::MoveDigest;

/// `BOUND_EXACT`, `BOUND_LOWER`, `BOUND_UPPER`, or `BOUND_NONE`.
///
/// * `BOUND_EXACT` means that the evaluation is exact.
///
/// * `BOUND_LOWER` means that the real value is greater or equal to
///    the evaluation.
///
/// * `BOUND_UPPER` means that the real value is lesser or equal to
///   the evaluation.
///
/// * `BOUND_NONE` means that the real value might be lesser, equal,
///   or grater than the evaluation.
pub type BoundType = u8;

/// The evaluation is not bounded.
pub const BOUND_NONE: BoundType = 0;

/// The evaluation is an upper bound.
pub const BOUND_UPPER: BoundType = 0b10;

/// The evaluation is a lower bound.
pub const BOUND_LOWER: BoundType = 0b01;

/// The evaluation is exact.
pub const BOUND_EXACT: BoundType = BOUND_UPPER | BOUND_LOWER;

/// Stores information about a particular position.
#[derive(Copy, Clone)]
pub struct EntryData {
    move16: MoveDigest,
    value: Value,
    eval_value: Value,
    gen_bound: u8,
    depth: u8,
}

impl EntryData {
    /// Creates a new instance.
    ///
    /// * `value` -- the value assigned to the position;
    ///
    /// * `bound` -- the meaning of the assigned `value`;
    ///
    /// * `depth` -- the depth of search;
    ///
    /// * `move16` -- best or refutation move, or `0` if no move is
    /// available;
    ///
    /// * `eval_value` -- the calculated static evaluation for the
    ///   position.
    pub fn new(value: Value,
               bound: BoundType,
               depth: u8,
               move16: MoveDigest,
               eval_value: Value)
               -> EntryData {
        assert!(bound <= 0b11);
        assert!(depth < 127);
        EntryData {
            move16: move16,
            value: value,
            eval_value: eval_value,
            gen_bound: bound, // Stores the entry's generation and the bound.
            depth: depth,
        }
    }

    #[inline(always)]
    pub fn value(&self) -> Value {
        self.value
    }

    #[inline(always)]
    pub fn bound(&self) -> BoundType {
        self.gen_bound & 0b11
    }

    #[inline(always)]
    pub fn depth(&self) -> u8 {
        self.depth
    }

    #[inline(always)]
    pub fn move16(&self) -> MoveDigest {
        self.move16
    }

    #[inline(always)]
    pub fn eval_value(&self) -> Value {
        self.eval_value
    }
}

// Represents transposition table entry.
//
// It is 16 bytes, defined as below:
//
// * key        64 bit
// * move16     16 bit
// * value      16 bit
// * eval value 16 bit
// * generation  6 bit
// * bound type  2 bit
// * depth       8 bit
#[derive(Copy, Clone)]
struct Entry {
    key: u64,
    data: EntryData,
}

impl Default for Entry {
    fn default() -> Entry {
        Entry {
            key: 0,
            data: unsafe { transmute(0u64) },
        }
    }
}

impl Entry {
    // Returns the whole contained data as one `u64` value.
    //
    // This is needed for implementing the lock-less probing and
    // storing.
    #[inline(always)]
    fn data_u64(&self) -> u64 {
        unsafe { transmute(self.data) }
    }

    // Returns entry's generation.
    #[inline(always)]
    fn generation(&self) -> u8 {
        self.data.gen_bound & 0b11111100
    }

    // Updates entry's generation.
    //
    // Since the `key` is saved xored with the data, when we change
    // the data, we have to change the stored `key` as well.
    #[inline(always)]
    fn update_generation(&mut self, generation: u8) {
        assert_eq!(generation & 0b11, 0);
        let old_data_u64 = self.data_u64();
        self.data.gen_bound = generation | self.data.bound();
        self.key ^= old_data_u64 ^ self.data_u64();
    }
}

/// A large hash-table that stores results of previously performed
/// searches.
pub struct TranspositionTable {
    generation: Cell<u8>,
    cluster_count: usize,
    table: UnsafeCell<Vec<[Entry; 4]>>,
}

impl TranspositionTable {
    /// Creates a new transposition table.
    ///
    /// The newly created table has the minimum possible size. Before
    /// using the new table for anything, `resize()` should be called
    /// on it, specifying the desired size.
    pub fn new() -> TranspositionTable {
        TranspositionTable {
            generation: Cell::new(0),
            cluster_count: 1,
            table: UnsafeCell::new(vec![Default::default()]),
        }
    }

    /// Resizes the transpositon table. All entries in the table will
    /// be lost.
    ///
    /// `size_mb` is the desired new size in Mbytes. If `size_mb` is
    /// not in the form "2**n", the new size of the transposition
    /// table will be as close as possible, but less than `size_mb`.
    pub fn resize(&mut self, size_mb: usize) {
        // The cluster count should be in the form "2**n", so the best
        // we can do is to ensure that the new cluster count will be
        // as close as possible but no greater than the requested one.
        let requested_cluster_count = (size_mb * 1024 * 1024) / std::mem::size_of::<[Entry; 4]>();

        // First, make sure `requested_cluster_count` is exceeded.
        let mut new_cluster_count = 1;
        while requested_cluster_count >= new_cluster_count {
            new_cluster_count <<= 1;
        }

        // Then make one step back, being careful so that the new
        // cluster count is not zero.
        if new_cluster_count > 1 {
            new_cluster_count >>= 1;
        } else {
            new_cluster_count = 1;
        }

        // Finally, reallocate the vector of clusters.
        if new_cluster_count != self.cluster_count {
            self.cluster_count = new_cluster_count;
            self.table = UnsafeCell::new(vec![Default::default(); new_cluster_count]);
        }
    }

    /// Returns the size of the transposition table in Mbytes.
    pub fn size(&self) -> usize {
        unsafe { &*self.table.get() }.len() * std::mem::size_of::<[Entry; 4]>() / 1024 / 1024
    }

    /// Removes all entries in the table.
    pub fn clear(&self) {
        let table = unsafe { self.table.get().as_mut().unwrap() };
        for cluster in table {
            for entry in cluster.iter_mut() {
                *entry = Default::default();
            }
        }
    }

    /// Signals that a new search is about to begin.
    ///
    /// Internally, the transposition table maintains a generation
    /// counter that is used to implement an efficient replacement
    /// strategy. This method increases this counter.
    pub fn new_search(&self) {
        // The lowest 2 bits of the `generation` field are used by
        // bound type.
        self.generation.set((Wrapping(self.generation.get()) + Wrapping(0b100)).0);
        assert_eq!(self.generation.get() & 0b11, 0);
    }

    /// Probes for data by a specific key.
    #[inline]
    pub fn probe(&self, key: u64) -> Option<EntryData> {
        let cluster = unsafe { self.cluster_mut(key) };
        for entry in cluster.iter_mut() {
            if entry.key ^ entry.data_u64() == key {
                // If `key` and `data` were written simultaneously by
                // different search instances with different keys,
                // this will yield in a mismatch of the above
                // comparison (except for the rare and inherent key
                // collisions).
                entry.update_generation(self.generation.get());
                return Some(entry.data);
            }
        }
        None
    }

    /// Stores data by a specific key.
    ///
    /// After being stored, the data might be retrieved by
    /// `probe(key)`. This is not guaranteed though, because in the
    /// meantime it might have been overwritten.
    pub fn store(&self, key: u64, mut data: EntryData) {
        // `store` and `probe` jointly implement a clever lock-less
        // hashing method. Rather than to store two disjoint items,
        // the key is stored xored with data, while data is stored
        // additionally as usual.

        data.gen_bound |= self.generation.get();  // Sets the generation.
        let mut cluster = unsafe { self.cluster_mut(key) };
        let mut replace_index = 0;
        let mut replace_score = 0xff;
        for (i, entry) in cluster.iter_mut().enumerate() {
            // Check if this is an empty slot, or an old entry for the
            // same key. If this this is the case we will use this
            // slot for the new entry.
            if entry.key == 0 || entry.key ^ entry.data_u64() == key {
                if data.move16 == 0 {
                    data.move16 = entry.data.move16;  // Preserve any existing move.
                }
                replace_index = i;
                break;
            }
            // If we can not find empty/old slot, the replaced entry
            // will be the entry with the lowest score.
            let entry_score = self.calc_score(entry);
            if entry_score < replace_score {
                replace_index = i;
                replace_score = entry_score;
            }
        }
        unsafe {
            cluster.get_unchecked_mut(replace_index).key = key ^ transmute::<EntryData, u64>(data);
            cluster.get_unchecked_mut(replace_index).data = data;
        }
    }

    // A helper method for `store`.
    //
    // Implements our replacement strategy. Should return higher
    // values for the entries that are move likely to save CPU work in
    // the future.
    #[inline(always)]
    fn calc_score(&self, entry: &Entry) -> u8 {
        // Positions from the current generation are always scored
        // higher than positions from older generations.
        (if entry.generation() == self.generation.get() {
            128
        } else {
            0
        })

        // Positions with higher search depth are scored higher.
        + entry.data.depth()

        // Positions with exact evaluation are given slight advantage.
        + (if entry.data.bound() == BOUND_EXACT {
            1
        } else {
            0
        })
    }

    // A helper method for `probe` and `store`.
    #[inline]
    unsafe fn cluster_mut(&self, key: u64) -> &mut [Entry; 4] {
        let cluster_index = (key & (self.cluster_count - 1) as u64) as usize;
        self.table.get().as_mut().unwrap().get_unchecked_mut(cluster_index)
    }
}

unsafe impl Sync for TranspositionTable {}

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

    #[test]
    fn test_cluster_size() {
        assert_eq!(std::mem::size_of::<[Entry; 4]>(), 64);
        assert_eq!(std::mem::size_of::<Entry>(), 16);
    }

    #[test]
    fn test_tt_resize() {
        let mut tt = TranspositionTable::new();
        assert_eq!(unsafe { &*tt.table.get() }.capacity(), 1);
        tt.resize(1);
        assert_eq!(tt.size(), 1);
        tt.clear();
    }

    #[test]
    fn test_store_and_probe() {
        let tt = TranspositionTable::new();
        assert!(tt.probe(1).is_none());
        let data = EntryData::new(0, 0, 100, 666, 0);
        assert_eq!(data.depth(), 100);
        assert_eq!(data.move16(), 666);
        tt.store(1, data);
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        tt.store(1, EntryData::new(0, 0, 100, 666, 0));
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(1).unwrap().move16(), 666);
        for i in 2..100 {
            tt.store(i, EntryData::new(i as i16, 0, i as u8, i as u16, i as i16));
        }
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(99).unwrap().depth(), 99);
        assert_eq!(tt.probe(98).unwrap().depth(), 98);
        assert_eq!(tt.probe(97).unwrap().depth(), 97);
        tt.clear();
        assert!(tt.probe(1).is_none());
        tt.store(1, data);
        tt.new_search();
        tt.probe(1);
        assert!(tt.probe(1).is_some());
    }

    #[test]
    fn test_new_search() {
        let tt = TranspositionTable::new();
        assert_eq!(tt.generation.get(), 0 << 2);
        tt.new_search();
        assert_eq!(tt.generation.get(), 1 << 2);
        for _ in 0..64 {
            tt.new_search();
        }
        assert_eq!(tt.generation.get(), 1 << 2);
    }
}
<commit_msg>set generation to 0 on TT clear<commit_after>//! Implements a database that stores results of previously performed
//! searches.
//!
//! Using such a database (called "transposition table") is a way to
//! greatly reduce the search space of a chess tree with little
//! negative impact. Chess programs, during their brute-force search,
//! encounter the same positions again and again, but from different
//! sequences of moves, which is called a transposition.
//!
//! When the search encounters a transposition, it is beneficial to
//! "remember" what was determined last time the position was
//! examined, rather than redoing the entire search again. For this
//! reason, chess programs have a transposition table, which is a
//! large hash table storing information about positions previously
//! searched, how deeply they were searched, and what we concluded
//! about them.

use std;
use std::cell::{UnsafeCell, Cell};
use std::mem::transmute;
use std::num::Wrapping;
use basetypes::Value;
use chess_move::MoveDigest;

/// `BOUND_EXACT`, `BOUND_LOWER`, `BOUND_UPPER`, or `BOUND_NONE`.
///
/// * `BOUND_EXACT` means that the evaluation is exact.
///
/// * `BOUND_LOWER` means that the real value is greater or equal to
///    the evaluation.
///
/// * `BOUND_UPPER` means that the real value is lesser or equal to
///   the evaluation.
///
/// * `BOUND_NONE` means that the real value might be lesser, equal,
///   or grater than the evaluation.
pub type BoundType = u8;

/// The evaluation is not bounded.
pub const BOUND_NONE: BoundType = 0;

/// The evaluation is an upper bound.
pub const BOUND_UPPER: BoundType = 0b10;

/// The evaluation is a lower bound.
pub const BOUND_LOWER: BoundType = 0b01;

/// The evaluation is exact.
pub const BOUND_EXACT: BoundType = BOUND_UPPER | BOUND_LOWER;

/// Stores information about a particular position.
#[derive(Copy, Clone)]
pub struct EntryData {
    move16: MoveDigest,
    value: Value,
    eval_value: Value,
    gen_bound: u8,
    depth: u8,
}

impl EntryData {
    /// Creates a new instance.
    ///
    /// * `value` -- the value assigned to the position;
    ///
    /// * `bound` -- the meaning of the assigned `value`;
    ///
    /// * `depth` -- the depth of search;
    ///
    /// * `move16` -- best or refutation move, or `0` if no move is
    /// available;
    ///
    /// * `eval_value` -- the calculated static evaluation for the
    ///   position.
    pub fn new(value: Value,
               bound: BoundType,
               depth: u8,
               move16: MoveDigest,
               eval_value: Value)
               -> EntryData {
        assert!(bound <= 0b11);
        assert!(depth < 127);
        EntryData {
            move16: move16,
            value: value,
            eval_value: eval_value,
            gen_bound: bound, // Stores the entry's generation and the bound.
            depth: depth,
        }
    }

    #[inline(always)]
    pub fn value(&self) -> Value {
        self.value
    }

    #[inline(always)]
    pub fn bound(&self) -> BoundType {
        self.gen_bound & 0b11
    }

    #[inline(always)]
    pub fn depth(&self) -> u8 {
        self.depth
    }

    #[inline(always)]
    pub fn move16(&self) -> MoveDigest {
        self.move16
    }

    #[inline(always)]
    pub fn eval_value(&self) -> Value {
        self.eval_value
    }
}

// Represents transposition table entry.
//
// It is 16 bytes, defined as below:
//
// * key        64 bit
// * move16     16 bit
// * value      16 bit
// * eval value 16 bit
// * generation  6 bit
// * bound type  2 bit
// * depth       8 bit
#[derive(Copy, Clone)]
struct Entry {
    key: u64,
    data: EntryData,
}

impl Default for Entry {
    fn default() -> Entry {
        Entry {
            key: 0,
            data: unsafe { transmute(0u64) },
        }
    }
}

impl Entry {
    // Returns the whole contained data as one `u64` value.
    //
    // This is needed for implementing the lock-less probing and
    // storing.
    #[inline(always)]
    fn data_u64(&self) -> u64 {
        unsafe { transmute(self.data) }
    }

    // Returns entry's generation.
    #[inline(always)]
    fn generation(&self) -> u8 {
        self.data.gen_bound & 0b11111100
    }

    // Updates entry's generation.
    //
    // Since the `key` is saved xored with the data, when we change
    // the data, we have to change the stored `key` as well.
    #[inline(always)]
    fn update_generation(&mut self, generation: u8) {
        assert_eq!(generation & 0b11, 0);
        let old_data_u64 = self.data_u64();
        self.data.gen_bound = generation | self.data.bound();
        self.key ^= old_data_u64 ^ self.data_u64();
    }
}

/// A large hash-table that stores results of previously performed
/// searches.
pub struct TranspositionTable {
    generation: Cell<u8>,
    cluster_count: usize,
    table: UnsafeCell<Vec<[Entry; 4]>>,
}

impl TranspositionTable {
    /// Creates a new transposition table.
    ///
    /// The newly created table has the minimum possible size. Before
    /// using the new table for anything, `resize()` should be called
    /// on it, specifying the desired size.
    pub fn new() -> TranspositionTable {
        TranspositionTable {
            generation: Cell::new(0),
            cluster_count: 1,
            table: UnsafeCell::new(vec![Default::default()]),
        }
    }

    /// Resizes the transpositon table. All entries in the table will
    /// be lost.
    ///
    /// `size_mb` is the desired new size in Mbytes. If `size_mb` is
    /// not in the form "2**n", the new size of the transposition
    /// table will be as close as possible, but less than `size_mb`.
    pub fn resize(&mut self, size_mb: usize) {
        // The cluster count should be in the form "2**n", so the best
        // we can do is to ensure that the new cluster count will be
        // as close as possible but no greater than the requested one.
        let requested_cluster_count = (size_mb * 1024 * 1024) / std::mem::size_of::<[Entry; 4]>();

        // First, make sure `requested_cluster_count` is exceeded.
        let mut new_cluster_count = 1;
        while requested_cluster_count >= new_cluster_count {
            new_cluster_count <<= 1;
        }

        // Then make one step back, being careful so that the new
        // cluster count is not zero.
        if new_cluster_count > 1 {
            new_cluster_count >>= 1;
        } else {
            new_cluster_count = 1;
        }

        // Finally, reallocate the vector of clusters.
        if new_cluster_count != self.cluster_count {
            self.cluster_count = new_cluster_count;
            self.table = UnsafeCell::new(vec![Default::default(); new_cluster_count]);
        }
    }

    /// Returns the size of the transposition table in Mbytes.
    pub fn size(&self) -> usize {
        unsafe { &*self.table.get() }.len() * std::mem::size_of::<[Entry; 4]>() / 1024 / 1024
    }

    /// Removes all entries in the table.
    pub fn clear(&self) {
        let table = unsafe { self.table.get().as_mut().unwrap() };
        for cluster in table {
            for entry in cluster.iter_mut() {
                *entry = Default::default();
            }
        }
        self.generation.set(0);
    }

    /// Signals that a new search is about to begin.
    ///
    /// Internally, the transposition table maintains a generation
    /// counter that is used to implement an efficient replacement
    /// strategy. This method increases this counter.
    pub fn new_search(&self) {
        // The lowest 2 bits of the `generation` field are used by
        // bound type.
        self.generation.set((Wrapping(self.generation.get()) + Wrapping(0b100)).0);
        assert_eq!(self.generation.get() & 0b11, 0);
    }

    /// Probes for data by a specific key.
    #[inline]
    pub fn probe(&self, key: u64) -> Option<EntryData> {
        let cluster = unsafe { self.cluster_mut(key) };
        for entry in cluster.iter_mut() {
            if entry.key ^ entry.data_u64() == key {
                // If `key` and `data` were written simultaneously by
                // different search instances with different keys,
                // this will yield in a mismatch of the above
                // comparison (except for the rare and inherent key
                // collisions).
                entry.update_generation(self.generation.get());
                return Some(entry.data);
            }
        }
        None
    }

    /// Stores data by a specific key.
    ///
    /// After being stored, the data might be retrieved by
    /// `probe(key)`. This is not guaranteed though, because in the
    /// meantime it might have been overwritten.
    pub fn store(&self, key: u64, mut data: EntryData) {
        // `store` and `probe` jointly implement a clever lock-less
        // hashing method. Rather than to store two disjoint items,
        // the key is stored xored with data, while data is stored
        // additionally as usual.

        data.gen_bound |= self.generation.get();  // Sets the generation.
        let mut cluster = unsafe { self.cluster_mut(key) };
        let mut replace_index = 0;
        let mut replace_score = 0xff;
        for (i, entry) in cluster.iter_mut().enumerate() {
            // Check if this is an empty slot, or an old entry for the
            // same key. If this this is the case we will use this
            // slot for the new entry.
            if entry.key == 0 || entry.key ^ entry.data_u64() == key {
                if data.move16 == 0 {
                    data.move16 = entry.data.move16;  // Preserve any existing move.
                }
                replace_index = i;
                break;
            }
            // If we can not find empty/old slot, the replaced entry
            // will be the entry with the lowest score.
            let entry_score = self.calc_score(entry);
            if entry_score < replace_score {
                replace_index = i;
                replace_score = entry_score;
            }
        }
        unsafe {
            cluster.get_unchecked_mut(replace_index).key = key ^ transmute::<EntryData, u64>(data);
            cluster.get_unchecked_mut(replace_index).data = data;
        }
    }

    // A helper method for `store`.
    //
    // Implements our replacement strategy. Should return higher
    // values for the entries that are move likely to save CPU work in
    // the future.
    #[inline(always)]
    fn calc_score(&self, entry: &Entry) -> u8 {
        // Positions from the current generation are always scored
        // higher than positions from older generations.
        (if entry.generation() == self.generation.get() {
            128
        } else {
            0
        })

        // Positions with higher search depth are scored higher.
        + entry.data.depth()

        // Positions with exact evaluation are given slight advantage.
        + (if entry.data.bound() == BOUND_EXACT {
            1
        } else {
            0
        })
    }

    // A helper method for `probe` and `store`.
    #[inline]
    unsafe fn cluster_mut(&self, key: u64) -> &mut [Entry; 4] {
        let cluster_index = (key & (self.cluster_count - 1) as u64) as usize;
        self.table.get().as_mut().unwrap().get_unchecked_mut(cluster_index)
    }
}

unsafe impl Sync for TranspositionTable {}

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

    #[test]
    fn test_cluster_size() {
        assert_eq!(std::mem::size_of::<[Entry; 4]>(), 64);
        assert_eq!(std::mem::size_of::<Entry>(), 16);
    }

    #[test]
    fn test_tt_resize() {
        let mut tt = TranspositionTable::new();
        assert_eq!(unsafe { &*tt.table.get() }.capacity(), 1);
        tt.resize(1);
        assert_eq!(tt.size(), 1);
        tt.clear();
    }

    #[test]
    fn test_store_and_probe() {
        let tt = TranspositionTable::new();
        assert!(tt.probe(1).is_none());
        let data = EntryData::new(0, 0, 100, 666, 0);
        assert_eq!(data.depth(), 100);
        assert_eq!(data.move16(), 666);
        tt.store(1, data);
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        tt.store(1, EntryData::new(0, 0, 100, 666, 0));
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(1).unwrap().move16(), 666);
        for i in 2..100 {
            tt.store(i, EntryData::new(i as i16, 0, i as u8, i as u16, i as i16));
        }
        assert_eq!(tt.probe(1).unwrap().depth(), 100);
        assert_eq!(tt.probe(99).unwrap().depth(), 99);
        assert_eq!(tt.probe(98).unwrap().depth(), 98);
        assert_eq!(tt.probe(97).unwrap().depth(), 97);
        tt.clear();
        assert!(tt.probe(1).is_none());
        tt.store(1, data);
        tt.new_search();
        tt.probe(1);
        assert!(tt.probe(1).is_some());
    }

    #[test]
    fn test_new_search() {
        let tt = TranspositionTable::new();
        assert_eq!(tt.generation.get(), 0 << 2);
        tt.new_search();
        assert_eq!(tt.generation.get(), 1 << 2);
        for _ in 0..64 {
            tt.new_search();
        }
        assert_eq!(tt.generation.get(), 1 << 2);
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ffi::CString;
use std::fmt::Display;
use std::str::Utf8Error;

use ffi::functions::*;
use ffi::utils::*;

/// Possible error codes.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u32)]
pub enum SioError {
    None = 0,
    /// Out of memory.
    NoMem = 1,
    /// The backend does not appear to be active or running.
    InitAudioBackend = 2,
    /// A system resource other than memory (Dummy) was not available.
    SystemResources = 3,
    /// Attempted to open a device and failed.
    OpeningDevice = 4,
    NoSuchDevice = 5,
    /// The programmer did not comply with the API.
    Invalid = 6,
    /// libsoundio was compiled without support for that backend.
    ///
    /// Currently there is no JACK support in Arch Linux until
    /// `jack2{,-dbus}1.9.10-4` is available. See [this](https://bugs.archlinux.org/task/47839)
    /// bug report for details.
    BackendUnavailable = 7,
    /// An open stream had an error that can only be recovered from by
    /// destroying the stream and creating it again.
    Streaming = 8,
    /// Attempted to use a device with parameters it cannot support.
    IncompatibleDevice = 9,
    /// When JACK returns `JackNoSuchClient`
    NoSuchClient = 10,
    /// Attempted to use parameters that the backend cannot support.
    IncompatibleBackend = 11,
    /// Backend server shutdown or became inactive.
    BackendDisconnected = 12,
    Interrupted = 13,
    /// Buffer underrun occurred.
    Underflow = 14,
    /// Unable to convert to or from UTF-8 to the native string format.
    EncodingString = 15,
}
impl Display for SioError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_strerror(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}

/// Specifies where a channel is physically located.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(u32)]
pub enum SioChannelId {
    Invalid = 0,
    /// First of the more commonly supported ids.
    FrontLeft = 1,
    FrontRight = 2,
    FrontCenter = 3,
    Lfe = 4,
    BackLeft = 5,
    BackRight = 6,
    FrontLeftCenter = 7,
    FrontRightCenter = 8,
    BackCenter = 9,
    SideLeft = 10,
    SideRight = 11,
    TopCenter = 12,
    TopFrontLeft = 13,
    TopFrontCenter = 14,
    TopFrontRight = 15,
    TopBackLeft = 16,
    TopBackCenter = 17,
    /// Last of the more commonly supported ids.
    TopBackRight = 18,
    /// First of the less commonly supported ids.
    BackLeftCenter = 19,
    BackRightCenter = 20,
    FrontLeftWide = 21,
    FrontRightWide = 22,
    FrontLeftHigh = 23,
    FrontCenterHigh = 24,
    FrontRightHigh = 25,
    TopFrontLeftCenter = 26,
    TopFrontRightCenter = 27,
    TopSideLeft = 28,
    TopSideRight = 29,
    LeftLfe = 30,
    RightLfe = 31,
    Lfe2 = 32,
    BottomCenter = 33,
    BottomLeftCenter = 34,
    BottomRightCenter = 35,
    /// Mid/side recording
    MsMid = 36,
    MsSide = 37,
    /// first order ambisonic channels
    AmbisonicW = 38,
    AmbisonicX = 39,
    AmbisonicY = 40,
    AmbisonicZ = 41,
    /// X-Y Recording
    XyX = 42,
    XyY = 43,
    /// First of the "other" channel ids
    HeadphonesLeft = 44,
    HeadphonesRight = 45,
    ClickTrack = 46,
    ForeignLanguage = 47,
    HearingImpaired = 48,
    Narration = 49,
    Haptic = 50,
    /// Last of the "other" channel ids
    DialogCentricMix = 51,
    Aux = 52,
    Aux0 = 53,
    Aux1 = 54,
    Aux2 = 55,
    Aux3 = 56,
    Aux4 = 57,
    Aux5 = 58,
    Aux6 = 59,
    Aux7 = 60,
    Aux8 = 61,
    Aux9 = 62,
    Aux10 = 63,
    Aux11 = 64,
    Aux12 = 65,
    Aux13 = 66,
    Aux14 = 67,
    Aux15 = 68,
}
impl Display for SioChannelId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_get_channel_name(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}
impl From<String> for SioChannelId {
    fn from(id: String) -> Self {
        let str_len = id.len() as i32;
        let cstr = CString::new(id).unwrap();
        unsafe { soundio_parse_channel_id(cstr.as_ptr(), str_len) }
    }
}

/// Built-in channel layouts for convenience.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum SioChannelLayoutId {
    Mono = 0,
    Stereo = 1,
    TwoPointOne = 2,
    ThreePointZero = 3,
    ThreePointZeroBack = 4,
    ThreePointOne = 5,
    FourPointZero = 6,
    Quad = 7,
    QuadSide = 8,
    FourPointOne = 9,
    FivePointZeroBack = 10,
    FivePointZeroSide = 11,
    FivePointOne = 12,
    FivePointOneBack = 13,
    SixPointZeroSide = 14,
    SixPointZeroFront = 15,
    Hexagonal = 16,
    SixPointOne = 17,
    SixPointOneBack = 18,
    SixPointOneFront = 19,
    SevenPointZero = 20,
    SevenPointZeroFront = 21,
    SevenPointOne = 22,
    SevenPointOneWide = 23,
    SevenPointOneWideBack = 24,
    Octagonal = 25,
}

#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u32)]
pub enum SioBackend {
    None = 0,
    Jack = 1,
    PulseAudio = 2,
    Alsa = 3,
    CoreAudio = 4,
    Wasapi = 5,
    Dummy = 6,
}
impl Display for SioBackend {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_backend_name(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}

#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum SioDeviceAim {
    /// capture/recording
    Input = 0,
    /// playback
    Output = 1,
}

/// Supported sound formats, each for little- and big-endian.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum SioFormat {
    Invalid = 0,
    /// Signed 8 bit
    S8 = 1,
    /// Unsigned 8 bit
    U8 = 2,
    /// Signed 16 bit little-endian
    S16LE = 3,
    /// Signed 16 bit big-endian
    S16BE = 4,
    /// Unsigned 16 bit little-endian
    U16LE = 5,
    /// Unsigned 16 bit big-endian
    U16BE = 6,
    /// The 24 bit types are not supported in rsoundio at the moment.
    /// Because there is no native number type that is 24 bits wide,
    /// (at least not in Rusts `std`) I had to use something like
    /// C unions in Rust to support them.
    /// This would probably be unsafe and working with
    /// 3 byte number types is also not too much fun.
    ///
    /// Signed 24 bit little-endian
    S24LE = 7,
    /// Signed 24 bit big-endian
    S24BE = 8,
    /// Unsigned 24 bit little-endian
    U24LE = 9,
    /// Unsigned 24 bit big-endian
    U24BE = 10,
    /// Signed 32 bit little-endian
    S32LE = 11,
    /// Signed 32 bit big-endian
    S32BE = 12,
    /// Unsigned 32 bit little-endian
    U32LE = 13,
    /// Unsigend 32 bit big-endian
    U32BE = 14,
    /// 32 bit float little-endian in [-1.0, 1.0]
    Float32LE = 15,
    /// 32 bit float big-endian in [-1.0, 1.0]
    Float32BE = 16,
    /// 64 bit float little-endian in [-1.0, 1.0]
    Float64LE = 17,
    /// 64 bit float big-endian in [-1.0, 1.0]
    Float64BE = 18,
}
impl Display for SioFormat {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_format_string(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}
impl SioFormat {
    /// Returns the number of bytes a sample takes in this format.
    pub fn bytes_per_sample(self) -> i32 {
        unsafe { soundio_get_bytes_per_sample(self) as i32 }
    }
}

// #[allow(dead_code,non_camel_case_types)]
// enum SoundIoRingBuffer { }
<commit_msg>Remove unused import<commit_after>use std::fmt;
use std::ffi::CString;
use std::fmt::Display;

use ffi::functions::*;
use ffi::utils::*;

/// Possible error codes.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u32)]
pub enum SioError {
    None = 0,
    /// Out of memory.
    NoMem = 1,
    /// The backend does not appear to be active or running.
    InitAudioBackend = 2,
    /// A system resource other than memory (Dummy) was not available.
    SystemResources = 3,
    /// Attempted to open a device and failed.
    OpeningDevice = 4,
    NoSuchDevice = 5,
    /// The programmer did not comply with the API.
    Invalid = 6,
    /// libsoundio was compiled without support for that backend.
    ///
    /// Currently there is no JACK support in Arch Linux until
    /// `jack2{,-dbus}1.9.10-4` is available. See [this](https://bugs.archlinux.org/task/47839)
    /// bug report for details.
    BackendUnavailable = 7,
    /// An open stream had an error that can only be recovered from by
    /// destroying the stream and creating it again.
    Streaming = 8,
    /// Attempted to use a device with parameters it cannot support.
    IncompatibleDevice = 9,
    /// When JACK returns `JackNoSuchClient`
    NoSuchClient = 10,
    /// Attempted to use parameters that the backend cannot support.
    IncompatibleBackend = 11,
    /// Backend server shutdown or became inactive.
    BackendDisconnected = 12,
    Interrupted = 13,
    /// Buffer underrun occurred.
    Underflow = 14,
    /// Unable to convert to or from UTF-8 to the native string format.
    EncodingString = 15,
}
impl Display for SioError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_strerror(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}

/// Specifies where a channel is physically located.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(u32)]
pub enum SioChannelId {
    Invalid = 0,
    /// First of the more commonly supported ids.
    FrontLeft = 1,
    FrontRight = 2,
    FrontCenter = 3,
    Lfe = 4,
    BackLeft = 5,
    BackRight = 6,
    FrontLeftCenter = 7,
    FrontRightCenter = 8,
    BackCenter = 9,
    SideLeft = 10,
    SideRight = 11,
    TopCenter = 12,
    TopFrontLeft = 13,
    TopFrontCenter = 14,
    TopFrontRight = 15,
    TopBackLeft = 16,
    TopBackCenter = 17,
    /// Last of the more commonly supported ids.
    TopBackRight = 18,
    /// First of the less commonly supported ids.
    BackLeftCenter = 19,
    BackRightCenter = 20,
    FrontLeftWide = 21,
    FrontRightWide = 22,
    FrontLeftHigh = 23,
    FrontCenterHigh = 24,
    FrontRightHigh = 25,
    TopFrontLeftCenter = 26,
    TopFrontRightCenter = 27,
    TopSideLeft = 28,
    TopSideRight = 29,
    LeftLfe = 30,
    RightLfe = 31,
    Lfe2 = 32,
    BottomCenter = 33,
    BottomLeftCenter = 34,
    BottomRightCenter = 35,
    /// Mid/side recording
    MsMid = 36,
    MsSide = 37,
    /// first order ambisonic channels
    AmbisonicW = 38,
    AmbisonicX = 39,
    AmbisonicY = 40,
    AmbisonicZ = 41,
    /// X-Y Recording
    XyX = 42,
    XyY = 43,
    /// First of the "other" channel ids
    HeadphonesLeft = 44,
    HeadphonesRight = 45,
    ClickTrack = 46,
    ForeignLanguage = 47,
    HearingImpaired = 48,
    Narration = 49,
    Haptic = 50,
    /// Last of the "other" channel ids
    DialogCentricMix = 51,
    Aux = 52,
    Aux0 = 53,
    Aux1 = 54,
    Aux2 = 55,
    Aux3 = 56,
    Aux4 = 57,
    Aux5 = 58,
    Aux6 = 59,
    Aux7 = 60,
    Aux8 = 61,
    Aux9 = 62,
    Aux10 = 63,
    Aux11 = 64,
    Aux12 = 65,
    Aux13 = 66,
    Aux14 = 67,
    Aux15 = 68,
}
impl Display for SioChannelId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_get_channel_name(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}
impl From<String> for SioChannelId {
    fn from(id: String) -> Self {
        let str_len = id.len() as i32;
        let cstr = CString::new(id).unwrap();
        unsafe { soundio_parse_channel_id(cstr.as_ptr(), str_len) }
    }
}

/// Built-in channel layouts for convenience.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum SioChannelLayoutId {
    Mono = 0,
    Stereo = 1,
    TwoPointOne = 2,
    ThreePointZero = 3,
    ThreePointZeroBack = 4,
    ThreePointOne = 5,
    FourPointZero = 6,
    Quad = 7,
    QuadSide = 8,
    FourPointOne = 9,
    FivePointZeroBack = 10,
    FivePointZeroSide = 11,
    FivePointOne = 12,
    FivePointOneBack = 13,
    SixPointZeroSide = 14,
    SixPointZeroFront = 15,
    Hexagonal = 16,
    SixPointOne = 17,
    SixPointOneBack = 18,
    SixPointOneFront = 19,
    SevenPointZero = 20,
    SevenPointZeroFront = 21,
    SevenPointOne = 22,
    SevenPointOneWide = 23,
    SevenPointOneWideBack = 24,
    Octagonal = 25,
}

#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u32)]
pub enum SioBackend {
    None = 0,
    Jack = 1,
    PulseAudio = 2,
    Alsa = 3,
    CoreAudio = 4,
    Wasapi = 5,
    Dummy = 6,
}
impl Display for SioBackend {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_backend_name(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}

#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum SioDeviceAim {
    /// capture/recording
    Input = 0,
    /// playback
    Output = 1,
}

/// Supported sound formats, each for little- and big-endian.
#[allow(dead_code,non_camel_case_types)]
#[derive(Clone, Copy)]
#[repr(u32)]
pub enum SioFormat {
    Invalid = 0,
    /// Signed 8 bit
    S8 = 1,
    /// Unsigned 8 bit
    U8 = 2,
    /// Signed 16 bit little-endian
    S16LE = 3,
    /// Signed 16 bit big-endian
    S16BE = 4,
    /// Unsigned 16 bit little-endian
    U16LE = 5,
    /// Unsigned 16 bit big-endian
    U16BE = 6,
    /// The 24 bit types are not supported in rsoundio at the moment.
    /// Because there is no native number type that is 24 bits wide,
    /// (at least not in Rusts `std`) I had to use something like
    /// C unions in Rust to support them.
    /// This would probably be unsafe and working with
    /// 3 byte number types is also not too much fun.
    ///
    /// Signed 24 bit little-endian
    S24LE = 7,
    /// Signed 24 bit big-endian
    S24BE = 8,
    /// Unsigned 24 bit little-endian
    U24LE = 9,
    /// Unsigned 24 bit big-endian
    U24BE = 10,
    /// Signed 32 bit little-endian
    S32LE = 11,
    /// Signed 32 bit big-endian
    S32BE = 12,
    /// Unsigned 32 bit little-endian
    U32LE = 13,
    /// Unsigend 32 bit big-endian
    U32BE = 14,
    /// 32 bit float little-endian in [-1.0, 1.0]
    Float32LE = 15,
    /// 32 bit float big-endian in [-1.0, 1.0]
    Float32BE = 16,
    /// 64 bit float little-endian in [-1.0, 1.0]
    Float64LE = 17,
    /// 64 bit float big-endian in [-1.0, 1.0]
    Float64BE = 18,
}
impl Display for SioFormat {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { soundio_format_string(*self) };
        write!(f, "{}", ptr_to_string(str_ptr).unwrap())
    }
}
impl SioFormat {
    /// Returns the number of bytes a sample takes in this format.
    pub fn bytes_per_sample(self) -> i32 {
        unsafe { soundio_get_bytes_per_sample(self) as i32 }
    }
}

// #[allow(dead_code,non_camel_case_types)]
// enum SoundIoRingBuffer { }
<|endoftext|>


<commit_before>//! System and Hardware Clocks

/// Internal Oscillator
pub const HSI: u32 = 8_000_000;
/// External clock
pub const HSE: u32 = 8_000_000;

use stm32f103xx::{Rcc, Flash, rcc};

/// Board clock speeds
pub struct ClockSpeeds{
    /// System Clock
    pub sysclk: u32,
    /// AHB peripheral clock
    pub hclk: u32,
    /// Low speed bus
    pub apb1: u32,
    /// high speed bus
    pub apb2: u32,
}

impl ClockSpeeds {
    /// Get clock speeds
    pub fn get(rcc: &Rcc) -> ClockSpeeds {
        let sysclk = match rcc.cfgr.read().sws(){
            rcc::cfgr::SwsR::Hse => HSE,
            rcc::cfgr::SwsR::Pll => Self::get_pll_speed(rcc),
            _ => HSI,
        };

        let hclk = match rcc.cfgr.read().hpre() {
            rcc::cfgr::HpreR::Div2 => sysclk / 2,
            rcc::cfgr::HpreR::Div4 => sysclk / 4,
            rcc::cfgr::HpreR::Div8 => sysclk / 8,
            rcc::cfgr::HpreR::Div16 => sysclk / 16,
            rcc::cfgr::HpreR::Div64 => sysclk / 64,
            rcc::cfgr::HpreR::Div128 => sysclk / 128,
            rcc::cfgr::HpreR::Div256 => sysclk / 256,
            rcc::cfgr::HpreR::Div512 => sysclk / 512,
            _ => sysclk,
        };

        let apb1 = match rcc.cfgr.read().ppre1() {
            rcc::cfgr::Ppre1R::Div2 => hclk / 2,
            rcc::cfgr::Ppre1R::Div4 => hclk / 4,
            rcc::cfgr::Ppre1R::Div8 => hclk / 8,
            rcc::cfgr::Ppre1R::Div16 => hclk / 16,
            _ => hclk,
        };

        let apb2 = match rcc.cfgr.read().ppre2() {
            rcc::cfgr::Ppre2R::Div2 => hclk / 2,
            rcc::cfgr::Ppre2R::Div4 => hclk / 4,
            rcc::cfgr::Ppre2R::Div8 => hclk / 8,
            rcc::cfgr::Ppre2R::Div16 => hclk / 16,
            _ => hclk,
        };

        ClockSpeeds{
            sysclk: sysclk,
            hclk: hclk,
            apb1: apb1,
            apb2: apb2,
        }
    }

    fn get_pll_speed(rcc: &Rcc) -> u32 {
        let hse_div = match rcc.cfgr.read().pllxtpre(){
            rcc::cfgr::PllxtpreR::Nodiv => 1,
            rcc::cfgr::PllxtpreR::Div2 => 2,
        };

        let src_spd = match rcc.cfgr.read().pllsrc(){
            rcc::cfgr::PllsrcR::Internal => HSI / 2,
            rcc::cfgr::PllsrcR::External => HSE / hse_div,
        };

        match rcc.cfgr.read().pllmul() {
            rcc::cfgr::PllmulR::Mul2 => src_spd * 2,
            rcc::cfgr::PllmulR::Mul3 => src_spd * 3,
            rcc::cfgr::PllmulR::Mul4 => src_spd * 4,
            rcc::cfgr::PllmulR::Mul5 => src_spd * 5,
            rcc::cfgr::PllmulR::Mul6 => src_spd * 6,
            rcc::cfgr::PllmulR::Mul7 => src_spd * 7,
            rcc::cfgr::PllmulR::Mul8 => src_spd * 8,
            rcc::cfgr::PllmulR::Mul9 => src_spd * 9,
            rcc::cfgr::PllmulR::Mul10 => src_spd * 10,
            rcc::cfgr::PllmulR::Mul11 => src_spd * 11,
            rcc::cfgr::PllmulR::Mul12 => src_spd * 12,
            rcc::cfgr::PllmulR::Mul13 => src_spd * 13,
            rcc::cfgr::PllmulR::Mul14 => src_spd * 14,
            rcc::cfgr::PllmulR::Mul15 => src_spd * 15,
            rcc::cfgr::PllmulR::Mul16 => src_spd * 16,
            _ => src_spd,
        }
    }
}

/// Preconfigured clock speed options
/// enum fields can't start with a number makes the names not look as good
pub enum Speed {
    /// 8Mhz
    S8Mhz,
    /// 16 Mhz
    S16Mhz,
    /// 32Mhz
    S32Mhz,
    /// 72 Mhz
    S72Mhz,}

/// Initializes SYSCLK to 72Mhz
pub fn init(rcc: &Rcc, flash: &Flash, speed: Speed) {
    // enable external clock
    rcc.cr.modify(|_,w| w.hseon().enabled());
    while rcc.cr.read().hserdy().is_notready() {}

    // configure pll to external clock
    rcc.cfgr.modify(|_,w| w.pllsrc().external());

    // enable flash prefetch buffer
    flash.acr.modify(|_,w| w.prftbe().enabled());

    match speed {
        Speed::S8Mhz => {},
        Speed::S16Mhz => {
            rcc.cfgr.modify(|_,w| w.pllmul().mul2());
            use_pll(rcc);
        }
        Speed::S32Mhz => {
            rcc.cfgr.modify(|_,w| w.pllmul().mul4());

            // set flash latency to one
            flash.acr.modify(|_,w| w.latency().one());
            use_pll(rcc);
        }
        Speed::S72Mhz => {
            rcc.cfgr.modify(|_,w| w.pllmul().mul9());

            // set apb1 to hclk / 2
            rcc.cfgr.modify(|_,w| w.ppre1().div2());

            // set flash latency to two
            flash.acr.modify(|_,w| w.latency().two());
            use_pll(rcc);
        }
    }
}

fn use_pll(rcc: &Rcc) {
    // enable pll
    rcc.cr.modify(|_,w| w.pllon().enabled());

    while rcc.cr.read().pllrdy().is_unlocked() {}

    // set system clock to pll
    rcc.cfgr.modify(|_,w| w.sw().pll());
}<commit_msg>change 8mhz to use external clock<commit_after>//! System and Hardware Clocks

/// Internal Oscillator
pub const HSI: u32 = 8_000_000;
/// External clock
pub const HSE: u32 = 8_000_000;

use stm32f103xx::{Rcc, Flash, rcc};

/// Board clock speeds
pub struct ClockSpeeds{
    /// System Clock
    pub sysclk: u32,
    /// AHB peripheral clock
    pub hclk: u32,
    /// Low speed bus
    pub apb1: u32,
    /// high speed bus
    pub apb2: u32,
}

impl ClockSpeeds {
    /// Get clock speeds
    pub fn get(rcc: &Rcc) -> ClockSpeeds {
        let sysclk = match rcc.cfgr.read().sws(){
            rcc::cfgr::SwsR::Hse => HSE,
            rcc::cfgr::SwsR::Pll => Self::get_pll_speed(rcc),
            _ => HSI,
        };

        let hclk = match rcc.cfgr.read().hpre() {
            rcc::cfgr::HpreR::Div2 => sysclk / 2,
            rcc::cfgr::HpreR::Div4 => sysclk / 4,
            rcc::cfgr::HpreR::Div8 => sysclk / 8,
            rcc::cfgr::HpreR::Div16 => sysclk / 16,
            rcc::cfgr::HpreR::Div64 => sysclk / 64,
            rcc::cfgr::HpreR::Div128 => sysclk / 128,
            rcc::cfgr::HpreR::Div256 => sysclk / 256,
            rcc::cfgr::HpreR::Div512 => sysclk / 512,
            _ => sysclk,
        };

        let apb1 = match rcc.cfgr.read().ppre1() {
            rcc::cfgr::Ppre1R::Div2 => hclk / 2,
            rcc::cfgr::Ppre1R::Div4 => hclk / 4,
            rcc::cfgr::Ppre1R::Div8 => hclk / 8,
            rcc::cfgr::Ppre1R::Div16 => hclk / 16,
            _ => hclk,
        };

        let apb2 = match rcc.cfgr.read().ppre2() {
            rcc::cfgr::Ppre2R::Div2 => hclk / 2,
            rcc::cfgr::Ppre2R::Div4 => hclk / 4,
            rcc::cfgr::Ppre2R::Div8 => hclk / 8,
            rcc::cfgr::Ppre2R::Div16 => hclk / 16,
            _ => hclk,
        };

        ClockSpeeds{
            sysclk: sysclk,
            hclk: hclk,
            apb1: apb1,
            apb2: apb2,
        }
    }

    fn get_pll_speed(rcc: &Rcc) -> u32 {
        let hse_div = match rcc.cfgr.read().pllxtpre(){
            rcc::cfgr::PllxtpreR::Nodiv => 1,
            rcc::cfgr::PllxtpreR::Div2 => 2,
        };

        let src_spd = match rcc.cfgr.read().pllsrc(){
            rcc::cfgr::PllsrcR::Internal => HSI / 2,
            rcc::cfgr::PllsrcR::External => HSE / hse_div,
        };

        match rcc.cfgr.read().pllmul() {
            rcc::cfgr::PllmulR::Mul2 => src_spd * 2,
            rcc::cfgr::PllmulR::Mul3 => src_spd * 3,
            rcc::cfgr::PllmulR::Mul4 => src_spd * 4,
            rcc::cfgr::PllmulR::Mul5 => src_spd * 5,
            rcc::cfgr::PllmulR::Mul6 => src_spd * 6,
            rcc::cfgr::PllmulR::Mul7 => src_spd * 7,
            rcc::cfgr::PllmulR::Mul8 => src_spd * 8,
            rcc::cfgr::PllmulR::Mul9 => src_spd * 9,
            rcc::cfgr::PllmulR::Mul10 => src_spd * 10,
            rcc::cfgr::PllmulR::Mul11 => src_spd * 11,
            rcc::cfgr::PllmulR::Mul12 => src_spd * 12,
            rcc::cfgr::PllmulR::Mul13 => src_spd * 13,
            rcc::cfgr::PllmulR::Mul14 => src_spd * 14,
            rcc::cfgr::PllmulR::Mul15 => src_spd * 15,
            rcc::cfgr::PllmulR::Mul16 => src_spd * 16,
            _ => src_spd,
        }
    }
}

/// Preconfigured clock speed options
/// enum fields can't start with a number makes the names not look as good
pub enum Speed {
    /// 8Mhz
    S8Mhz,
    /// 16 Mhz
    S16Mhz,
    /// 32Mhz
    S32Mhz,
    /// 72 Mhz
    S72Mhz,}

/// Initializes SYSCLK to 72Mhz
pub fn init(rcc: &Rcc, flash: &Flash, speed: Speed) {
    // enable external clock
    rcc.cr.modify(|_,w| w.hseon().enabled());
    while rcc.cr.read().hserdy().is_notready() {}

    // configure pll to external clock
    rcc.cfgr.modify(|_,w| w.pllsrc().external());

    // enable flash prefetch buffer
    flash.acr.modify(|_,w| w.prftbe().enabled());

    match speed {
        Speed::S8Mhz => rcc.cfgr.modify(|_,w| w.sw().hse()),
        Speed::S16Mhz => {
            rcc.cfgr.modify(|_,w| w.pllmul().mul2());
            use_pll(rcc);
        }
        Speed::S32Mhz => {
            rcc.cfgr.modify(|_,w| w.pllmul().mul4());

            // set flash latency to one
            flash.acr.modify(|_,w| w.latency().one());
            use_pll(rcc);
        }
        Speed::S72Mhz => {
            rcc.cfgr.modify(|_,w| w.pllmul().mul9());

            // set apb1 to hclk / 2
            rcc.cfgr.modify(|_,w| w.ppre1().div2());

            // set flash latency to two
            flash.acr.modify(|_,w| w.latency().two());
            use_pll(rcc);
        }
    }
}

fn use_pll(rcc: &Rcc) {
    // enable pll
    rcc.cr.modify(|_,w| w.pllon().enabled());

    while rcc.cr.read().pllrdy().is_unlocked() {}

    // set system clock to pll
    rcc.cfgr.modify(|_,w| w.sw().pll());
}<|endoftext|>


<commit_before>//! Linear Regression module
//!
//! Contains implementation of linear regression models.
//! Allows training and prediction of linear regression model
//! using least squares optimization.
//!
//! Currently only OLS solution - gradient descent not yet implemented.

use learning::SupModel;
use linalg::matrix::Matrix;
use linalg::vector::Vector;

/// Linear Regression Model.
///
/// Contains option for optimized parameter.
pub struct LinRegressor {
    /// The mle for the beta parameters.
    pub b: Option<Vector<f64>>,
}

impl SupModel<Matrix<f64>, Vector<f64>> for LinRegressor {
    /// Train the linear regression model.
    ///
    /// Takes training data and output values as input.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::lin_reg::LinRegressor;
    /// use rusty_machine::linalg::matrix::Matrix;
    /// use rusty_machine::linalg::vector::Vector;
    /// use rusty_machine::learning::SupModel;
    ///
    /// let mut lin_mod = LinRegressor::new();
    /// let inputs = Matrix::new(3,2, vec![1.0, 2.0, 1.0, 3.0, 1.0, 4.0]);
    /// let targets = Vector::new(vec![5.0, 6.0, 7.0]);
    ///
    /// lin_mod.train(&inputs, &targets);
    /// ```
    fn train(&mut self, inputs: &Matrix<f64>, targets: &Vector<f64>) {
        let xt = inputs.transpose();

        self.b = Some(((&xt * inputs).inverse() * &xt) * targets);
    }

    /// Predict output value from input data.
    ///
    /// Model must be trained before prediction can be made.
    fn predict(&self, inputs: &Matrix<f64>) -> Vector<f64> {
        match self.b {
            Some(ref v) => inputs * v,
            None => panic!("Model has not been trained."),
        }
    }
}

impl LinRegressor {
    /// Constructs untrained linear regression model.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::lin_reg::LinRegressor;
    ///
    /// let mut lin_mod = LinRegressor::new();
    /// ```
    pub fn new() -> LinRegressor {
        LinRegressor { b: None }
    }
}
<commit_msg>Making parameters private.<commit_after>//! Linear Regression module
//!
//! Contains implementation of linear regression models.
//! Allows training and prediction of linear regression model
//! using least squares optimization.
//!
//! Currently only OLS solution - gradient descent not yet implemented.

use learning::SupModel;
use linalg::matrix::Matrix;
use linalg::vector::Vector;

/// Linear Regression Model.
///
/// Contains option for optimized parameter.
pub struct LinRegressor {
    /// The parameters for the regression model.
    parameters: Option<Vector<f64>>,
}

impl SupModel<Matrix<f64>, Vector<f64>> for LinRegressor {
    /// Train the linear regression model.
    ///
    /// Takes training data and output values as input.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::lin_reg::LinRegressor;
    /// use rusty_machine::linalg::matrix::Matrix;
    /// use rusty_machine::linalg::vector::Vector;
    /// use rusty_machine::learning::SupModel;
    ///
    /// let mut lin_mod = LinRegressor::new();
    /// let inputs = Matrix::new(3,2, vec![1.0, 2.0, 1.0, 3.0, 1.0, 4.0]);
    /// let targets = Vector::new(vec![5.0, 6.0, 7.0]);
    ///
    /// lin_mod.train(&inputs, &targets);
    /// ```
    fn train(&mut self, inputs: &Matrix<f64>, targets: &Vector<f64>) {
        let xt = inputs.transpose();

        self.parameters = Some(((&xt * inputs).inverse() * &xt) * targets);
    }

    /// Predict output value from input data.
    ///
    /// Model must be trained before prediction can be made.
    fn predict(&self, inputs: &Matrix<f64>) -> Vector<f64> {
        match self.parameters {
            Some(ref v) => inputs * v,
            None => panic!("Model has not been trained."),
        }
    }
}

impl LinRegressor {
    /// Constructs untrained linear regression model.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::lin_reg::LinRegressor;
    ///
    /// let mut lin_mod = LinRegressor::new();
    /// ```
    pub fn new() -> LinRegressor {
        LinRegressor { parameters: None }
    }

    /// Get the parameters from the model.
    ///
    /// Returns an option that is None if the model has not been trained.
    pub fn parameters(&self) -> Option<Vector<f64>> {
        match self.parameters {
            None => None,
            Some(ref x) => Some(x.clone()),
        }
    }
}
<|endoftext|>


<commit_before>use collections::VecDeque;
// Temporary hack until libredox get hashmaps
use redox::*;

#[derive(Clone, PartialEq, Copy, Hash)]
pub enum InsertMode {
    Append,
    Insert,
    Replace,
}

#[derive(Clone, PartialEq, Copy, Hash)]
pub struct InsertOptions {
    mode: InsertMode,
}

/// A mode
#[derive(Clone, PartialEq, Copy, Hash)]
pub enum Mode {
    /// A primitive mode (no repeat, no delimiters, no preprocessing)
    Primitive(PrimitiveMode),
    /// Command mode
    Command(CommandMode),
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A command mode
pub enum CommandMode {
//    Visual(VisualOptions),
    /// Normal mode
    Normal,
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A primitive mode
pub enum PrimitiveMode {
    /// Insert mode
    Insert(InsertOptions),
}

#[derive(Clone, PartialEq, Hash)]
pub enum Unit {
    /// Single [repeated] instruction
    Inst(u16, char),
    /// Multiple instructions
    Block(u16, Vec<Unit>),
}

#[derive(Clone, PartialEq, Hash)]
/// The state of the editor
pub struct State {
    /// The current cursor
    pub current_cursor: u8,
    /// The cursors
    pub cursors: Vec<Cursor>,
    /// The text (document)
    pub text: VecDeque<VecDeque<char>>,
    /// The x coordinate of the scroll
    pub scroll_x: u32,
    /// The y coordinate of the scroll
    pub scroll_y: u32,
}

impl State {
    fn insert(&mut self, c: char) {

    }
    fn new() -> State {
        State {
            current_cursor: 0,
            cursors: Vec::new(),
            text: VecDeque::new(),
            scroll_x: 0,
            scroll_y: 0,
        }
    }
}

/// A command char
#[derive(Clone, Copy, Hash, PartialEq)]
pub enum CommandChar {
    /// A char
    Char(char),
    /// A wildcard
    Wildcard,
}

/// The editor
pub struct Editor {
    /// The state of the editor
    pub state: State,
}

impl Editor {
    pub fn new() -> Self {
        Editor {
            state: State::new(),
        }
    }

    pub fn exec(&mut self, cmd: &Unit) {

        match *cmd {
            Unit::Inst(n, ref c) => {
                // Execute commands
            },
            Unit::Block(n, ref units) => {
                for _ in 1..n {
                    for i in units {
                        self.exec(&i);
                    }
                }
            },
        }
    }
}

#[derive(Clone, PartialEq, Hash)]
/// A cursor
pub struct Cursor {
    /// The x coordinate of the cursor
    pub x: u32,
    /// The y coordinate of the cursor
    pub y: u32,
    /// The mode of the cursor
    pub mode: Mode,
    /// The history of the cursor
    pub history: Vec<Unit>,
}

/// An iterator over units
pub struct UnitIterator<'a, I: Iterator<Item = char> + 'a> {
    /// The iterator over the chars
    char_iter: &'a mut I,
    /// The state
    state: &'a mut State,
}

impl<'a, I: Iterator<Item = char> + 'a> Iterator for UnitIterator<'a, I> {
    type Item = Unit;

    fn next(&mut self) -> Option<Unit> {
        match self.state.cursors[self.state.current_cursor as usize].mode {
            Mode::Primitive(_) => Some(Unit::Inst(1, match self.char_iter.next() {
                Some(c) => c,
                None => return None,
            })),
            Mode::Command(_) => {
                let mut ch = self.char_iter.next().unwrap_or('\0');
                let mut n = 1;

                let mut unset = true;
                for c in self.char_iter {
                    n = match c {
                        '0' if n != 0 => n * 10,
                        '1'           => n * 10 + 1,
                        '2'           => n * 10 + 2,
                        '3'           => n * 10 + 3,
                        '4'           => n * 10 + 4,
                        '5'           => n * 10 + 5,
                        '6'           => n * 10 + 6,
                        '7'           => n * 10 + 7,
                        '8'           => n * 10 + 8,
                        '9'           => n * 10 + 9,
                        r             => {
                            ch = r;
                            break;
                        },
                    };

                    if unset {
                        unset = false;
                        n     = 0;
                    }
                }

                if ch == '(' {
                    let mut level = 0;
                    let mut vec = self.char_iter.take_while(|c| {
                        level = match *c {
                            '(' => level + 1,
                            ')' => level - 1,
                            ';' => 0,
                            _ => level,
                        };
                        level != 0
                    }).skip(1).collect::<Vec<_>>();
                    vec.pop();
                    Some(Unit::Block(n, vec.into_iter().unit_iter(&mut self.state).collect()))
                } else if let Some(ch) = self.char_iter.next() {
                    Some(Unit::Inst(n, ch))
                } else {
                    None
                }
            }
        }
    }
}

pub trait ToUnitIterator<'a>: Iterator<Item = char> + 'a {
    /// Create a iterator of the unit given by the chars
    fn unit_iter(&'a mut self, state: &'a mut State) -> UnitIterator<'a, Self>;
}

impl<'a, I: Iterator<Item = char> + 'a> ToUnitIterator<'a> for I {
    fn unit_iter(&'a mut self, state: &'a mut State) -> UnitIterator<'a, I> {
        UnitIterator {
            char_iter: self,
            state: state,
        }
    }
}
<commit_msg>Simplify structure<commit_after>use collections::VecDeque;
// Temporary hack until libredox get hashmaps
use redox::*;

#[derive(Clone, PartialEq, Copy, Hash)]
pub enum InsertMode {
    Append,
    Insert,
    Replace,
}

#[derive(Clone, PartialEq, Copy, Hash)]
pub struct InsertOptions {
    mode: InsertMode,
}

/// A mode
#[derive(Clone, PartialEq, Copy, Hash)]
pub enum Mode {
    /// A primitive mode (no repeat, no delimiters, no preprocessing)
    Primitive(PrimitiveMode),
    /// Command mode
    Command(CommandMode),
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A command mode
pub enum CommandMode {
//    Visual(VisualOptions),
    /// Normal mode
    Normal,
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A primitive mode
pub enum PrimitiveMode {
    /// Insert mode
    Insert(InsertOptions),
}

#[derive(Clone, PartialEq, Hash)]
/// The state of the editor
pub struct State {
    /// The current cursor
    pub current_cursor: u8,
    /// The cursors
    pub cursors: Vec<Cursor>,
    /// The text (document)
    pub text: VecDeque<VecDeque<char>>,
    /// The x coordinate of the scroll
    pub scroll_x: u32,
    /// The y coordinate of the scroll
    pub scroll_y: u32,
    /// Number of repeation entered
    pub n: u16,
}

impl State {
    fn insert(&mut self, c: char) {

    }
    fn new() -> State {
        State {
            current_cursor: 0,
            cursors: Vec::new(),
            text: VecDeque::new(),
            scroll_x: 0,
            scroll_y: 0,
        }
    }
}

/// A command char
#[derive(Clone, Copy, Hash, PartialEq)]
pub enum CommandChar {
    /// A char
    Char(char),
    /// A wildcard
    Wildcard,
}

/// The editor
pub struct Editor {
    /// The state of the editor
    pub state: State,
}

impl Editor {
    pub fn new() -> Self {
        Editor {
            state: State::new(),
        }
    }

    /// Execute a instruction n times
    pub fn exec(&mut self, n: u16, cmd: char) {

        match cmd {

        }
    }

    /// Feed a char to the editor (as input)
    fn feed(&mut self, c: char) {
        match self.state.cursors[self.state.current_cursor as usize].mode {
            Mode::Primitive(_) => {
                self.exec(0, c);
            },
            Mode::Command(_) => {
                self.n = match c {
                    '0' if self.n != 0 => self.n * 10,
                    '1'           => self.n * 10 + 1,
                    '2'           => self.n * 10 + 2,
                    '3'           => self.n * 10 + 3,
                    '4'           => self.n * 10 + 4,
                    '5'           => self.n * 10 + 5,
                    '6'           => self.n * 10 + 6,
                    '7'           => self.n * 10 + 7,
                    '8'           => self.n * 10 + 8,
                    '9'           => self.n * 10 + 9,
                    _             => {
                        self.exec(if self.n == 0 { 1 } else { self.n }, c);
                        self.n
                    }
                }

            }
        }
    }
}

#[derive(Clone, PartialEq, Hash)]
/// A cursor
pub struct Cursor {
    /// The x coordinate of the cursor
    pub x: u32,
    /// The y coordinate of the cursor
    pub y: u32,
    /// The mode of the cursor
    pub mode: Mode,
    /// The history of the cursor
    pub history: Vec<Unit>,

<|endoftext|>


<commit_before>//! # generator
//!
//! generator trait
//!

use std::any::Any;
use gen_impl::GeneratorImpl;

/// generator trait
pub trait Generator<A> {
    /// Output type
    type Output;

    /// raw send
    fn raw_send(&mut self, para: Option<A>) -> Option<Self::Output>;

    /// send interface
    fn send(&mut self, para: A) -> Self::Output {
        let ret = self.raw_send(Some(para));
        ret.unwrap()
    }

    /// cancel generator
    fn cancel(&mut self);

    /// is finished
    fn is_done(&self) -> bool;

    /// get stack total size and used size in word
    fn stack_usage(&self) -> (usize, usize);
}

#[allow(dead_code)]
/// Generator helper
/// this is equal with GeneratorImpl::<A, _, _>
/// but save some typing
pub struct Gn<A> {
    dummy: A,
}

impl <A: Any> Gn<A> {
    /// create a new generator with default stack size
    pub fn new<'a, T: Any, F>(f: F) -> Box<Generator<A, Output = T> + 'a>
        where F: FnOnce() -> T + 'a
    {
        GeneratorImpl::<A, T, F>::new_opt(f, 0)
    }

    /// create a new generator with specified stack size
    pub fn new_opt<'a, T: Any, F>(f: F, size: usize) -> Box<Generator<A, Output = T> + 'a>
        where F: FnOnce() -> T + 'a
    {
        GeneratorImpl::<A, T, F>::new_opt(f, size)
    }
}

impl<'a, A, T> Iterator for Generator<A, Output=T> + 'a {
    type Item = T;
    // The 'Iterator' trait only requires the 'next' method to be defined. The
    // return type is 'Option<T>', 'None' is returned when the 'Iterator' is
    // over, otherwise the next value is returned wrapped in 'Some'
    fn next(&mut self) -> Option<T> {
        self.raw_send(None)
    }
}

/// create generator
#[macro_export]
macro_rules! generator {
    // `(func, <type>)`
    // func: the expression for unsafe async function which contains yiled
    // para: default send para type to the generator
    ($func:expr, <$para:ty>) => (
        generator::Gn::<$para>::new(move|| {$func})
    );

    ($func:expr) => (generator!($func, <()>));
}
<commit_msg>use PhantomData as dummy<commit_after>//! # generator
//!
//! generator trait
//!

use std::any::Any;
use std::marker::PhantomData;
use gen_impl::GeneratorImpl;

/// generator trait
pub trait Generator<A> {
    /// Output type
    type Output;

    /// raw send
    fn raw_send(&mut self, para: Option<A>) -> Option<Self::Output>;

    /// send interface
    fn send(&mut self, para: A) -> Self::Output {
        let ret = self.raw_send(Some(para));
        ret.unwrap()
    }

    /// cancel generator
    fn cancel(&mut self);

    /// is finished
    fn is_done(&self) -> bool;

    /// get stack total size and used size in word
    fn stack_usage(&self) -> (usize, usize);
}

/// Generator helper
/// this is equal with GeneratorImpl::<A, _, _>
/// but save some typing
pub struct Gn<A> {
    dummy: PhantomData<A>,
}

impl <A: Any> Gn<A> {
    /// create a new generator with default stack size
    pub fn new<'a, T: Any, F>(f: F) -> Box<Generator<A, Output = T> + 'a>
        where F: FnOnce() -> T + 'a
    {
        GeneratorImpl::<A, T, F>::new_opt(f, 0)
    }

    /// create a new generator with specified stack size
    pub fn new_opt<'a, T: Any, F>(f: F, size: usize) -> Box<Generator<A, Output = T> + 'a>
        where F: FnOnce() -> T + 'a
    {
        GeneratorImpl::<A, T, F>::new_opt(f, size)
    }
}

impl<'a, A, T> Iterator for Generator<A, Output=T> + 'a {
    type Item = T;
    // The 'Iterator' trait only requires the 'next' method to be defined. The
    // return type is 'Option<T>', 'None' is returned when the 'Iterator' is
    // over, otherwise the next value is returned wrapped in 'Some'
    fn next(&mut self) -> Option<T> {
        self.raw_send(None)
    }
}

/// create generator
#[macro_export]
macro_rules! generator {
    // `(func, <type>)`
    // func: the expression for unsafe async function which contains yiled
    // para: default send para type to the generator
    ($func:expr, <$para:ty>) => (
        generator::Gn::<$para>::new(move|| {$func})
    );

    ($func:expr) => (generator!($func, <()>));
}
<|endoftext|>


<commit_before>use commands::{Command, CommandExecutor};
use std::error;
use std::sync::Arc;
use errors::anoncreds::AnoncredsError;

pub struct AnoncredsAPI {
    command_executor: Arc<CommandExecutor>,
}

impl AnoncredsAPI {
    pub fn new(command_executor: Arc<CommandExecutor>) -> AnoncredsAPI {
        AnoncredsAPI { command_executor: command_executor }
    }

    /// Creates master secret key for prover.
    ///
    /// #Params
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Master secret key as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_master_secret(cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates public/private keys pair for issuer.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of
    /// (Public primary key, Secret Key, Public non-revocation key, Secret non-revocation key)
    /// as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_key_pair(schema: &[&u8],
                       cb: Box<Fn(
                           Result<((String, String, String, String)), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Issues accumulator.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// accumulator_id: accumulator id as a byte array.
    /// max_claims: maximum number of claims within accumulator as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of (Accumulator, Tails, Accumulator public key, Accumulator secret key) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn issue_accumulator(schema: &[&u8], accumulator_id: &[&u8], max_claims: &[&u8],
                             public_key_non_revocation: &[&u8],
                             cb: Box<Fn(
                                 Result<((String, String, String, String)),
                                     AnoncredsError>
                             ) + Send>) {
        unimplemented!();
    }

    /// Issues claim.
    ///
    /// #Params
    /// attributes:  all names of attributes as a byte array.
    /// accumulator: accumulator as a byte array.
    /// sequence_number: claim's sequence number within accumulator as a byte array.
    /// claim_request:
    ///     A claim request containing prover ID and prover-generated values as a byte array.
    /// public_key: issuer's public_key as a byte array.
    /// secret_key: issuer's secret_key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// secret_key_non_revocation: issuer's non-revocation secret key as a byte array.
    /// tails: tails as a byte array.
    /// secret_key_accumulator: accumulator's secret key as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// The claim (both primary and non-revocation) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn issue_claim(attributes: &[&u8], accumulator: &[&u8], sequence_number: &[&u8],
                       claim_request: &[&u8], public_key: &[&u8],
                       secret_key: &[&u8], public_key_non_revocation: &[&u8],
                       secret_key_non_revocation: &[&u8], tails: &[&u8],
                       secret_key_accumulator: &[&u8],
                       cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates claim request.
    ///
    /// #Params
    /// master_secret: prover's master secret as a byte array.
    /// public_key: issuer's public_key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// request_non_revocation: whether to request non-revocation claim as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Claim request as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_claim_request(master_secret: &[&u8], public_key: &[&u8],
                                public_key_non_revocation: &[&u8], request_non_revocation: &[&u8],
                                cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates proof.
    ///
    /// #Params
    /// proof_input: description of a proof to be presented
    ///     (revealed attributes, predicates, timestamps for non-revocation) as a byte array.
    /// nonce: verifier's nonce as a byte array.
    /// claims: necessary claims for proof as a byte array.
    /// master_secret: prover's master secret key as a byte array.
    /// public_key: issuer's public key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// accumulator: accumulator as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Typle of (
    ///         Proof (both primary and non-revocation),
    ///         Revealed attributes (initial non-encoded values)
    ///     ) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_proof(proof_input: &[&u8], nonce: &[&u8], claims: &[&u8],
                        public_key_non_revocation: &[&u8], accumulator: &[&u8], public_key: &[&u8],
                        master_secret: &[&u8],
                        cb: Box<Fn(Result<(String, String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Verifies proof.
    ///
    /// #Params
    /// proof_input: description of a proof to be presented
    ///     (revealed attributes, predicates, timestamps for non-revocation) as a byte array.
    /// proof: a proof as a byte array.
    /// revealed_attributes:
    ///     values of revealed attributes (initial values, non-encoded) as a byte array.
    /// nonce: verifier's nonce as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// accumulator: accumulator as a byte array.
    /// public_key_accumulator: accumulator's public key as a byte array.
    /// public_key: issuer's public key as a byte array.
    /// attributes:  all names of attributes as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// True if verified successfully and false otherwise as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn verify_proof(proof_input: &[&u8], proof: &[&u8], revealed_attributes: &[&u8],
                        nonce: &[&u8], public_key_non_revocation: &[&u8],
                        accumulator: &[&u8], public_key_accumulator: &[&u8],
                        public_key: &[&u8], attributes: &[&u8],
                        cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates verifier's nonce.
    ///
    /// #Params
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Nonce as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_nonce(cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }
}

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

    #[test]
    fn anoncreds_api_can_be_created() {
        let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        assert! (true, "No crashes on AnoncredsAPI::new");
    }

    #[test]
    fn anoncredsn_api_can_be_dropped() {
        fn drop_test() {
            let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        }

        drop_test();
        assert! (true, "No crashes on AnoncredsAPI::drop");
    }
}<commit_msg>minor changes<commit_after>use commands::{Command, CommandExecutor};
use std::error;
use std::sync::Arc;
use errors::anoncreds::AnoncredsError;

pub struct AnoncredsAPI {
    command_executor: Arc<CommandExecutor>,
}

impl AnoncredsAPI {
    pub fn new(command_executor: Arc<CommandExecutor>) -> AnoncredsAPI {
        AnoncredsAPI { command_executor: command_executor }
    }

    /// Creates master secret key for prover.
    ///
    /// #Params
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Master secret key as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_master_secret(cb: Box<Fn(Result<String, AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates public/private keys pair for issuer.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of
    /// (Public primary key, Secret Key, Public non-revocation key, Secret non-revocation key)
    /// as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_key_pair(schema: &[&u8],
                       cb: Box<Fn(
                           Result<((String, String, String, String)), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Issues accumulator.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// accumulator_id: accumulator id as a byte array.
    /// max_claims: maximum number of claims within accumulator as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of (Accumulator, Tails, Accumulator public key, Accumulator secret key) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn issue_accumulator(schema: &[&u8], accumulator_id: &[&u8], max_claims: &[&u8],
                             public_key_non_revocation: &[&u8],
                             cb: Box<Fn(
                                 Result<((String, String, String, String)),
                                     AnoncredsError>
                             ) + Send>) {
        unimplemented!();
    }

    /// Issues claim.
    ///
    /// #Params
    /// attributes:  all names of attributes as a byte array.
    /// accumulator: accumulator as a byte array.
    /// sequence_number: claim's sequence number within accumulator as a byte array.
    /// claim_request:
    ///     A claim request containing prover ID and prover-generated values as a byte array.
    /// public_key: issuer's public_key as a byte array.
    /// secret_key: issuer's secret_key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// secret_key_non_revocation: issuer's non-revocation secret key as a byte array.
    /// tails: tails as a byte array.
    /// secret_key_accumulator: accumulator's secret key as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// The claim (both primary and non-revocation) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn issue_claim(attributes: &[&u8], accumulator: &[&u8], sequence_number: &[&u8],
                       claim_request: &[&u8], public_key: &[&u8],
                       secret_key: &[&u8], public_key_non_revocation: &[&u8],
                       secret_key_non_revocation: &[&u8], tails: &[&u8],
                       secret_key_accumulator: &[&u8],
                       cb: Box<Fn(Result<String, AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates claim request.
    ///
    /// #Params
    /// master_secret: prover's master secret as a byte array.
    /// public_key: issuer's public_key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// request_non_revocation: whether to request non-revocation claim as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Claim request as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_claim_request(master_secret: &[&u8], public_key: &[&u8],
                                public_key_non_revocation: &[&u8], request_non_revocation: &[&u8],
                                cb: Box<Fn(Result<String, AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates proof.
    ///
    /// #Params
    /// proof_input: description of a proof to be presented
    ///     (revealed attributes, predicates, timestamps for non-revocation) as a byte array.
    /// nonce: verifier's nonce as a byte array.
    /// claims: necessary claims for proof as a byte array.
    /// master_secret: prover's master secret key as a byte array.
    /// public_key: issuer's public key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// accumulator: accumulator as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Typle of (
    ///         Proof (both primary and non-revocation),
    ///         Revealed attributes (initial non-encoded values)
    ///     ) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_proof(proof_input: &[&u8], nonce: &[&u8], claims: &[&u8],
                        public_key_non_revocation: &[&u8], accumulator: &[&u8], public_key: &[&u8],
                        master_secret: &[&u8],
                        cb: Box<Fn(Result<(String, String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Verifies proof.
    ///
    /// #Params
    /// proof_input: description of a proof to be presented
    ///     (revealed attributes, predicates, timestamps for non-revocation) as a byte array.
    /// proof: a proof as a byte array.
    /// revealed_attributes:
    ///     values of revealed attributes (initial values, non-encoded) as a byte array.
    /// nonce: verifier's nonce as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// accumulator: accumulator as a byte array.
    /// public_key_accumulator: accumulator's public key as a byte array.
    /// public_key: issuer's public key as a byte array.
    /// attributes:  all names of attributes as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// True if verified successfully and false otherwise as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn verify_proof(proof_input: &[&u8], proof: &[&u8], revealed_attributes: &[&u8],
                        nonce: &[&u8], public_key_non_revocation: &[&u8],
                        accumulator: &[&u8], public_key_accumulator: &[&u8],
                        public_key: &[&u8], attributes: &[&u8],
                        cb: Box<Fn(Result<String, AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates verifier's nonce.
    ///
    /// #Params
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Nonce as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_nonce(cb: Box<Fn(Result<String, AnoncredsError>) + Send>) {
        unimplemented!();
    }
}

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

    #[test]
    fn anoncreds_api_can_be_created() {
        let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        assert! (true, "No crashes on AnoncredsAPI::new");
    }

    #[test]
    fn anoncredsn_api_can_be_dropped() {
        fn drop_test() {
            let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        }

        drop_test();
        assert! (true, "No crashes on AnoncredsAPI::drop");
    }
}<|endoftext|>