<commit_before>//! # What is Validator
//! It useful for Form and Model validation.
//! Implementation for Validation via BTreeMap structure.
//! It consist basic validations rule, validatior, and
//! validation Result and validation Errors.
//!
//! ## How to use
//! Most common examples you can find at src/admin/models/*
pub use rustc_serialize::json::{self, Json, ToJson};
pub use rustc_serialize::json::DecoderError::*;
pub use rustc_serialize::Decodable;
use params::{Value, FromValue};
use super::render::{BaseDataMap, BaseDataMapDecoder};
use std::collections::BTreeMap;
use std::string::String;

/// Base Validator struct
#[derive(RustcDecodable, Debug)]
pub struct Validator<T> {
    /// Type of validator
    /// For example: string, bool, i64 etc.
    pub vtype: String,
    pub requiered: Option<bool>,
    pub not_empty: Option<bool>,
    pub min: Option<i64>,
    pub max: Option<u64>,
    pub default: Option<T>,
    errors: Option<ErrorValidator>,
}

/// Validation result enum.
/// Consist Values and Errors
#[derive(Debug)]
pub struct ValidateResult(BaseDataMap, ErrorValidator);
/// Array of Validatopn Results for all validatior
#[derive(Debug)]
pub struct ValidateResults(pub Vec<ValidateResult>);
// Error result aggregator
pub type ErrorsResult = Option<Vec<ErrorValidator>>;

/// Validation results methods
impl ValidateResults {
    /// Get Validation Errors result
    pub fn get_errors(&self) -> ErrorsResult {
        let &ValidateResults(ref results) = self;
        let mut errors = vec!();
        for &ValidateResult(_, ref err) in results {
            if err.errors_count.is_some() {
                errors.push(err.to_owned());
            }
        }
        if errors.len() > 0 { Some(errors) } else { None }
    }

    /// Get Validation Values result
    pub fn get_values(&self) -> BaseDataMap {
        let &ValidateResults(ref results) = self;
        let mut values: BaseDataMap = BTreeMap::new();
        for &ValidateResult(ref val, _) in results {
            values.append(&mut val.clone());
        }
        values
    }
}

/// Convert Validation Results to Json
impl ToJson for ValidateResults {
    fn to_json(&self) -> Json {
        let mut data: Vec<Json> = vec!();
        let &ValidateResults(ref results) = self;
        let mut i = 0;
        for &ValidateResult(ref val, ref err) in results {
            let mut d = BTreeMap::new();
            // Set `field` attribute
            d.insert("field".to_string(), err.field.to_json());
            // Set `errors` attribute
            d.insert("errors".to_string(), err.errors.to_json());
            // Set `values` attribute
            d.insert("values".to_string(), val.to_json());

            data.push(d.to_json());

            //data.append(&mut d);
            i = i + 1;
        }
        Json::Array(data)
    }
}

/// Validator methods
/// It depends from various additional **traits**.
impl<T: FromValue + ToJson + Decodable> Validator<T> {
    /// Init Validation rule
    pub fn new(validator_rules: BaseDataMap) -> Validator<T> {
        validator_rules.decode()
    }

    /// Main validor for all validations rules
    pub fn validate(&mut self, field: String, value: Option<&Value>) -> ValidateResult {
        let mut value: Option<Value> = if let Some(val) = value {
            Some(val.to_owned())
        } else { None };
        // Init Errors
        self.errors = Some(ErrorValidator::new(&field));

        // Invoke validators
        self.requiered(&value);
        self.not_empty(&value);
        self.max(&value);
        self.min(&value);
        value = self.default(&value);

        let json_value: Json = match self.type_cast(&value) {
            Some(ref json_value) => json_value.to_owned(),
            None => {
                if let Some(ref mut error) = self.errors {
                    if value.is_some() {
                        let msg = format!("Field wrong type: {}", error.field);
                        error.add(msg);
                    }
                }
                Json::Null
            }
        };

        let mut err = ErrorValidator::new(&field);
        if let Some(ref err_results) = self.errors {
            err = err_results.to_owned();
        }

        ValidateResult(btreemap! {
            field.to_owned() => json_value
        }, err)
    }

    /// Requered validator
    fn requiered(&mut self, value: &Option<Value>) {
        if self.requiered.is_some() {
            if value.is_some() {
                let check_value = match *value {
                    Some(Value::String(ref value)) => {
                        !value.trim().is_empty()
                    },
                    _ => true
                };
                if check_value {
                    return ()
                }
            }
            if let Some(ref mut error) = self.errors {
                let msg = format!("Field requiered: {}", error.field);
                error.add(msg);
            }
        }
    }

    /// Not Empty validator
    fn not_empty(&mut self, value: &Option<Value>) {
        // We apply validarot onlu if values is set
        // Requered validator analize if value was set
        if self.not_empty.is_some() && value.is_some() {
            let is_empty = match *value {
                // We check only strings
                Some(Value::String(ref value)) => {
                    value.trim().is_empty()
                },
                _ => false
            };
            if is_empty {
                if let Some(ref mut error) = self.errors {
                    let msg = format!("Field can't be empty: {}", error.field);
                    error.add(msg);
                }
            }
        }
    }

    /// Max value validator
    /// Multitype
    fn max(&mut self, value: &Option<Value>) {
        if self.max.is_some() && value.is_some() {
            let mut requiered_value: u64 = 0;
            if let Some(max) = self.max {
                if max == 0 {
                    if let Some(ref mut error) = self.errors {
                        let msg = format!("Validation value can't be equal: {}", max);
                        error.add(msg);
                    }
                    return ()
                }
                requiered_value = max;
            }
            let is_valid = match *value {
                Some(Value::String(ref value)) => {
                    value.chars().count() as u64 <= requiered_value
                },
                Some(Value::U64(value)) => {
                    value <= requiered_value
                },
                Some(Value::I64(value)) => {
                    value as u64 <= requiered_value
                },
                Some(Value::F64(value)) => {
                    value as u64 <= requiered_value
                },
                Some(Value::Boolean(value)) => {
                    value as u64 <= requiered_value
                },
                _ => false
            };
            if is_valid {
                if let Some(ref mut error) = self.errors {
                    let msg = format!("Field can't be max then: {}", error.field);
                    error.add(msg);
                }
            }
        }
    }

    /// Min value validator
    /// Multitype
    fn min(&mut self, value: &Option<Value>) {
        if self.min.is_some() && value.is_some() {
            let mut requiered_value: i64 = 0;
            if let Some(min) = self.min {
                if let Some(max) = self.max {
                    if min >= max as i64 {
                        if let Some(ref mut error) = self.errors {
                            let msg = format!("Validation rule {} can't be greater or equal max rule: {}", min, max);
                            error.add(msg);
                        }
                        return ()
                    }
                }
                requiered_value = min;
            }
            let is_valid = match *value {
                Some(Value::String(ref value)) => {
                    value.chars().count() as i64 >= requiered_value
                },
                Some(Value::U64(value)) => {
                    value as i64>= requiered_value
                },
                Some(Value::I64(value)) => {
                    value >= requiered_value
                },
                Some(Value::F64(value)) => {
                    value as i64 >= requiered_value
                },
                Some(Value::Boolean(value)) => {
                    value as i64 >= requiered_value
                },
                _ => false
            };
            if !is_valid {
                if let Some(ref mut error) = self.errors {
                    let msg = format!("Field {} can't be min then: {}", error.field, requiered_value);
                    error.add(msg);
                }
            }
        }
    }

    /// Default value validator
    /// Validate by type and default field
    fn default(&mut self, value: &Option<Value>) -> Option<Value> {
        if let Some(ref default_value) = self.default {
            if value.is_none() {
                return self.to_value(default_value.to_json());
            }
        }
        value.to_owned()
    }

    /// Convert value based ot specific type to Value
    pub fn to_value(&self, json_value: Json) -> Option<Value> {
        match json_value {
            Json::I64(value) => Some(Value::I64(value)),
            Json::U64(value) => Some(Value::U64(value)),
            Json::F64(value) => Some(Value::F64(value)),
            Json::String( ref value) => Some(Value::String(value.clone())),
            Json::Boolean(value) => Some(Value::Boolean(value)),
            Json::Null => Some(Value::Null),
            _ => None,
        }
    }

    // Type cast for Value.
    // Returned as Json
    fn type_cast(&self, value: &Option<Value>) -> Option<Json> {
        let val: Value;
        if let Some(name) = value.as_ref() {
            val = name.to_owned();
        } else {
            return None
        }
        match &self.vtype.as_ref() as &str {
            "array" | "vec" => {
                if let Some(val) = <Vec<String> as FromValue>::from_value(&val) {
                    Some(val.to_json())
                } else {
                    None
                }
            },
            "bool" | "boolean" => {
                if let Some(val) = <bool as FromValue>::from_value(&val) {
                    Some(Json::Boolean(val))
                } else {
                    return None;
                }
            },
            "string" | "str" => {
                if let Some(val) = <String as FromValue>::from_value(&val) {
                    Some(Json::String(val))
                } else {
                    None
                }
            },
            "u8" | "u16" | "u32" | "u64" | "usize" => {
                if let Some(val) = <u64 as FromValue>::from_value(&val) {
                    Some(Json::U64(val))
                } else {
                    None
                }
            },
            "i8" | "i16" | "i32" | "i64" | "isize" => {
                if let Some(val) = <i64 as FromValue>::from_value(&val) {
                    Some(Json::I64(val))
                } else {
                    None
                }
            },
            "f32" | "f64" => {
                if let Some(val) = <f64 as FromValue>::from_value(&val) {
                    Some(Json::F64(val))
                } else {
                    return None;
                }
            },
            _ => None,
        }
    }
}

/// Validator Errors
#[derive(RustcDecodable, Debug, Clone)]
pub struct ErrorValidator {
    pub errors: Vec<String>,
    pub errors_count: Option<u32>,
    pub field : String,
}

/// Validator Errors methods
impl ErrorValidator {
    /// Init error
    fn new(field: &String) -> Self {
        ErrorValidator {
            field: field.to_owned(),
            errors: vec!(),
            errors_count: None,
        }
    }

    /// Add error
    fn add(&mut self, error: String) {
        if self.errors_count.is_none() {
            self.errors = vec!(error);
            self.errors_count = Some(1);
        } else {
            if let Some(count) = self.errors_count {
                self.errors.push(error);
                self.errors_count = Some(count + 1);
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn new_test() {
        // Test for requiered equal
        let val_req = Validator::<String>::new(btreemap! {
            "requiered".to_string() => true.to_json(),
            "vtype".to_string() => "bool".to_json(),
        });
        assert_eq!(val_req.requiered, Some(true));

        // Test for non-panic
        Validator::<bool>::new(btreemap! {
            "default".to_string() => false.to_json(),
            "vtype".to_string() => "bool".to_json(),
        });
    }

    #[test]
    #[should_panic]
    fn new_with_wrong_type_test() {
        // It should be: Validator::<bool>
        Validator::<String>::new(btreemap! {
            "default".to_string() => false.to_json(),
            "vtype".to_string() => "bool".to_json(),
        });
    }
}
<commit_msg>Fix validator: max<commit_after>//! # What is Validator
//! It useful for Form and Model validation.
//! Implementation for Validation via BTreeMap structure.
//! It consist basic validations rule, validatior, and
//! validation Result and validation Errors.
//!
//! ## How to use
//! Most common examples you can find at src/admin/models/*
pub use rustc_serialize::json::{self, Json, ToJson};
pub use rustc_serialize::json::DecoderError::*;
pub use rustc_serialize::Decodable;
use params::{Value, FromValue};
use super::render::{BaseDataMap, BaseDataMapDecoder};
use std::collections::BTreeMap;
use std::string::String;

/// Base Validator struct
#[derive(RustcDecodable, Debug)]
pub struct Validator<T> {
    /// Type of validator
    /// For example: string, bool, i64 etc.
    pub vtype: String,
    pub requiered: Option<bool>,
    pub not_empty: Option<bool>,
    pub min: Option<i64>,
    pub max: Option<u64>,
    pub default: Option<T>,
    errors: Option<ErrorValidator>,
}

/// Validation result enum.
/// Consist Values and Errors
#[derive(Debug)]
pub struct ValidateResult(BaseDataMap, ErrorValidator);
/// Array of Validatopn Results for all validatior
#[derive(Debug)]
pub struct ValidateResults(pub Vec<ValidateResult>);
// Error result aggregator
pub type ErrorsResult = Option<Vec<ErrorValidator>>;

/// Validation results methods
impl ValidateResults {
    /// Get Validation Errors result
    pub fn get_errors(&self) -> ErrorsResult {
        let &ValidateResults(ref results) = self;
        let mut errors = vec!();
        for &ValidateResult(_, ref err) in results {
            if err.errors_count.is_some() {
                errors.push(err.to_owned());
            }
        }
        if errors.len() > 0 { Some(errors) } else { None }
    }

    /// Get Validation Values result
    pub fn get_values(&self) -> BaseDataMap {
        let &ValidateResults(ref results) = self;
        let mut values: BaseDataMap = BTreeMap::new();
        for &ValidateResult(ref val, _) in results {
            values.append(&mut val.clone());
        }
        values
    }
}

/// Convert Validation Results to Json
impl ToJson for ValidateResults {
    fn to_json(&self) -> Json {
        let mut data: Vec<Json> = vec!();
        let &ValidateResults(ref results) = self;
        let mut i = 0;
        for &ValidateResult(ref val, ref err) in results {
            let mut d = BTreeMap::new();
            // Set `field` attribute
            d.insert("field".to_string(), err.field.to_json());
            // Set `errors` attribute
            d.insert("errors".to_string(), err.errors.to_json());
            // Set `values` attribute
            d.insert("values".to_string(), val.to_json());

            data.push(d.to_json());

            //data.append(&mut d);
            i = i + 1;
        }
        Json::Array(data)
    }
}

/// Validator methods
/// It depends from various additional **traits**.
impl<T: FromValue + ToJson + Decodable> Validator<T> {
    /// Init Validation rule
    pub fn new(validator_rules: BaseDataMap) -> Validator<T> {
        validator_rules.decode()
    }

    /// Main validor for all validations rules
    pub fn validate(&mut self, field: String, value: Option<&Value>) -> ValidateResult {
        let mut value: Option<Value> = if let Some(val) = value {
            Some(val.to_owned())
        } else { None };
        // Init Errors
        self.errors = Some(ErrorValidator::new(&field));

        // Invoke validators
        self.requiered(&value);
        self.not_empty(&value);
        self.max(&value);
        self.min(&value);
        value = self.default(&value);

        let json_value: Json = match self.type_cast(&value) {
            Some(ref json_value) => json_value.to_owned(),
            None => {
                if let Some(ref mut error) = self.errors {
                    if value.is_some() {
                        let msg = format!("Field wrong type: {}", error.field);
                        error.add(msg);
                    }
                }
                Json::Null
            }
        };

        let mut err = ErrorValidator::new(&field);
        if let Some(ref err_results) = self.errors {
            err = err_results.to_owned();
        }

        ValidateResult(btreemap! {
            field.to_owned() => json_value
        }, err)
    }

    /// Requered validator
    fn requiered(&mut self, value: &Option<Value>) {
        if self.requiered.is_some() {
            if value.is_some() {
                let check_value = match *value {
                    Some(Value::String(ref value)) => {
                        !value.trim().is_empty()
                    },
                    _ => true
                };
                if check_value {
                    return ()
                }
            }
            if let Some(ref mut error) = self.errors {
                let msg = format!("Field requiered: {}", error.field);
                error.add(msg);
            }
        }
    }

    /// Not Empty validator
    fn not_empty(&mut self, value: &Option<Value>) {
        // We apply validarot onlu if values is set
        // Requered validator analize if value was set
        if self.not_empty.is_some() && value.is_some() {
            let is_empty = match *value {
                // We check only strings
                Some(Value::String(ref value)) => {
                    value.trim().is_empty()
                },
                _ => false
            };
            if is_empty {
                if let Some(ref mut error) = self.errors {
                    let msg = format!("Field can't be empty: {}", error.field);
                    error.add(msg);
                }
            }
        }
    }

    /// Max value validator
    /// Multitype
    fn max(&mut self, value: &Option<Value>) {
        if self.max.is_some() && value.is_some() {
            let mut requiered_value: u64 = 0;
            if let Some(max) = self.max {
                if max == 0 {
                    if let Some(ref mut error) = self.errors {
                        let msg = format!("Validation value can't be equal: {}", max);
                        error.add(msg);
                    }
                    return ()
                }
                requiered_value = max;
            }
            let is_valid = match *value {
                Some(Value::String(ref value)) => {
                    value.chars().count() as u64 <= requiered_value
                },
                Some(Value::U64(value)) => {
                    value <= requiered_value
                },
                Some(Value::I64(value)) => {
                    value as u64 <= requiered_value
                },
                Some(Value::F64(value)) => {
                    value as u64 <= requiered_value
                },
                Some(Value::Boolean(value)) => {
                    value as u64 <= requiered_value
                },
                _ => false
            };
            if !is_valid {
                if let Some(ref mut error) = self.errors {
                    let msg = format!("Field {} can't be min then: {}", error.field, requiered_value);
                    error.add(msg);
                }
            }
        }
    }

    /// Min value validator
    /// Multitype
    fn min(&mut self, value: &Option<Value>) {
        if self.min.is_some() && value.is_some() {
            let mut requiered_value: i64 = 0;
            if let Some(min) = self.min {
                if let Some(max) = self.max {
                    if min >= max as i64 {
                        if let Some(ref mut error) = self.errors {
                            let msg = format!("Validation rule {} can't be greater or equal max rule: {}", min, max);
                            error.add(msg);
                        }
                        return ()
                    }
                }
                requiered_value = min;
            }
            let is_valid = match *value {
                Some(Value::String(ref value)) => {
                    value.chars().count() as i64 >= requiered_value
                },
                Some(Value::U64(value)) => {
                    value as i64>= requiered_value
                },
                Some(Value::I64(value)) => {
                    value >= requiered_value
                },
                Some(Value::F64(value)) => {
                    value as i64 >= requiered_value
                },
                Some(Value::Boolean(value)) => {
                    value as i64 >= requiered_value
                },
                _ => false
            };
            if !is_valid {
                if let Some(ref mut error) = self.errors {
                    let msg = format!("Field {} can't be min then: {}", error.field, requiered_value);
                    error.add(msg);
                }
            }
        }
    }

    /// Default value validator
    /// Validate by type and default field
    fn default(&mut self, value: &Option<Value>) -> Option<Value> {
        if let Some(ref default_value) = self.default {
            if value.is_none() {
                return self.to_value(default_value.to_json());
            }
        }
        value.to_owned()
    }

    /// Convert value based ot specific type to Value
    pub fn to_value(&self, json_value: Json) -> Option<Value> {
        match json_value {
            Json::I64(value) => Some(Value::I64(value)),
            Json::U64(value) => Some(Value::U64(value)),
            Json::F64(value) => Some(Value::F64(value)),
            Json::String( ref value) => Some(Value::String(value.clone())),
            Json::Boolean(value) => Some(Value::Boolean(value)),
            Json::Null => Some(Value::Null),
            _ => None,
        }
    }

    // Type cast for Value.
    // Returned as Json
    fn type_cast(&self, value: &Option<Value>) -> Option<Json> {
        let val: Value;
        if let Some(name) = value.as_ref() {
            val = name.to_owned();
        } else {
            return None
        }
        match &self.vtype.as_ref() as &str {
            "array" | "vec" => {
                if let Some(val) = <Vec<String> as FromValue>::from_value(&val) {
                    Some(val.to_json())
                } else {
                    None
                }
            },
            "bool" | "boolean" => {
                if let Some(val) = <bool as FromValue>::from_value(&val) {
                    Some(Json::Boolean(val))
                } else {
                    return None;
                }
            },
            "string" | "str" => {
                if let Some(val) = <String as FromValue>::from_value(&val) {
                    Some(Json::String(val))
                } else {
                    None
                }
            },
            "u8" | "u16" | "u32" | "u64" | "usize" => {
                if let Some(val) = <u64 as FromValue>::from_value(&val) {
                    Some(Json::U64(val))
                } else {
                    None
                }
            },
            "i8" | "i16" | "i32" | "i64" | "isize" => {
                if let Some(val) = <i64 as FromValue>::from_value(&val) {
                    Some(Json::I64(val))
                } else {
                    None
                }
            },
            "f32" | "f64" => {
                if let Some(val) = <f64 as FromValue>::from_value(&val) {
                    Some(Json::F64(val))
                } else {
                    return None;
                }
            },
            _ => None,
        }
    }
}

/// Validator Errors
#[derive(RustcDecodable, Debug, Clone)]
pub struct ErrorValidator {
    pub errors: Vec<String>,
    pub errors_count: Option<u32>,
    pub field : String,
}

/// Validator Errors methods
impl ErrorValidator {
    /// Init error
    fn new(field: &String) -> Self {
        ErrorValidator {
            field: field.to_owned(),
            errors: vec!(),
            errors_count: None,
        }
    }

    /// Add error
    fn add(&mut self, error: String) {
        if self.errors_count.is_none() {
            self.errors = vec!(error);
            self.errors_count = Some(1);
        } else {
            if let Some(count) = self.errors_count {
                self.errors.push(error);
                self.errors_count = Some(count + 1);
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn new_test() {
        // Test for requiered equal
        let val_req = Validator::<String>::new(btreemap! {
            "requiered".to_string() => true.to_json(),
            "vtype".to_string() => "bool".to_json(),
        });
        assert_eq!(val_req.requiered, Some(true));

        // Test for non-panic
        Validator::<bool>::new(btreemap! {
            "default".to_string() => false.to_json(),
            "vtype".to_string() => "bool".to_json(),
        });
    }

    #[test]
    #[should_panic]
    fn new_with_wrong_type_test() {
        // It should be: Validator::<bool>
        Validator::<String>::new(btreemap! {
            "default".to_string() => false.to_json(),
            "vtype".to_string() => "bool".to_json(),
        });
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use rand::{thread_rng, Rng};

fn dot_product(a: &[f64; 4], b: &[f64; 4]) -> f64 {
    a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}

fn J(theta: &[f64; 4], x: &[[f64; 4]], y: &[f64]) -> f64 {
    let predictions = x.iter().map(|xi| dot_product(theta, xi));
    let error: f64 = predictions
        .zip(y.iter())
        .map(|(ti, yi)| (ti - yi).powi(2))
        .sum();
    1.0 / ((2 * x.len()) as f64) * error
}

fn main() {
    let mut rng = thread_rng();

    // Initialize the feature matrix.
    let mut x = [[0.0; 4]; 1000];
    for i in 0..x.len() {
        let xi = [
            1.0,
            rng.gen_range(-1000.0, 1000.0),
            rng.gen_range(-1000.0, 1000.0),
            rng.gen_range(-1000.0, 1000.0),
        ];
        x[i] = xi;
    }

    // Initialize the target vector according the the formula:
    //  3x^0 + 2x^1 + 8^x2 + 4x^3
    let mut y = [0.0; 1000];
    for i in 0..y.len() {
        y[i] = 3.0 + 2.0 * x[i][1] + 8.0 * x[i][2] + 4.0 * x[i][3];
    }

    // Run the gradient descent.
    let mut theta = [0.0; 4];
    let mut update = [0.0; 4];
    let mut alpha = 1.0;
    let mut error = J(&theta, &x, &y);
    for count in 0..100000000 {
        for j in 0..4 {
            let mut sum = 0.0;
            for i in 0..x.len() {
                let prediction: f64 = dot_product(&theta, &x[i]);
                sum += (prediction - y[i]) * x[i][j];
            }
            update[j] = theta[j] - alpha * (1.0 / (x.len() as f64)) * sum;
        }
        if theta == update {
            println!("Converged at iteration {:?} with alpha {:?}", count, alpha);
            break;
        }
        let new_error = J(&update, &x, &y);
        if new_error > error {
            alpha /= 3.0;
            println!("Reducing alpha to: {:?} at iteration {:?}", alpha, count);
        } else {
            theta = update;
            error = new_error;
        }
    }
    println!("{:?}", theta);
}
<commit_msg>Added some additional diagnostics<commit_after>extern crate rand;

use rand::{thread_rng, Rng};

fn dot_product(a: &[f64; 4], b: &[f64; 4]) -> f64 {
    a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}

fn J(theta: &[f64; 4], x: &[[f64; 4]], y: &[f64]) -> f64 {
    let predictions = x.iter().map(|xi| dot_product(theta, xi));
    let error: f64 = predictions
        .zip(y.iter())
        .map(|(ti, yi)| (ti - yi).powi(2))
        .sum();
    1.0 / ((2 * x.len()) as f64) * error
}

fn main() {
    let mut rng = thread_rng();

    // Initialize the feature matrix.
    let mut x = [[0.0; 4]; 1000];
    for i in 0..x.len() {
        let xi = [
            1.0,
            rng.gen_range(-1000.0, 1000.0),
            rng.gen_range(-1000.0, 1000.0),
            rng.gen_range(-1000.0, 1000.0),
        ];
        x[i] = xi;
    }

    // Initialize the target vector according the the formula:
    //  3x^0 + 2x^1 + 8^x2 + 4x^3
    let mut y = [0.0; 1000];
    for i in 0..y.len() {
        y[i] = 3.0 + 2.0 * x[i][1] + 8.0 * x[i][2] + 4.0 * x[i][3];
    }

    // Run the gradient descent.
    let mut theta = [0.0; 4];
    let mut update = [0.0; 4];
    let mut alpha = 1.0;
    let mut error = J(&theta, &x, &y);
    for count in 0..100000000 {
        for j in 0..4 {
            let mut sum = 0.0;
            for i in 0..x.len() {
                let prediction: f64 = dot_product(&theta, &x[i]);
                sum += (prediction - y[i]) * x[i][j];
            }
            update[j] = theta[j] - alpha * (1.0 / (x.len() as f64)) * sum;
        }
        if theta == update {
            println!("Converged at iteration {:?} with alpha {:?}", count, alpha);
            break;
        }
        let new_error = J(&update, &x, &y);
        if new_error > error {
            alpha /= 3.0;
            println!("Reducing alpha to: {:?} at iteration {:?} [theta: {:?}]",
                alpha, count, theta);
        } else {
            theta = update;
            error = new_error;
        }
    }
    println!("{:?}", theta);
}
<|endoftext|>


<commit_before>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

#[macro_use]
extern crate prometheus;

use mimir::rubber::Rubber;
use slog_scope::debug;
use std::time::Duration;
use structopt::StructOpt;

mod extractors;
mod model;
pub mod prometheus_middleware;
pub(crate) mod query;
mod query_settings;
mod routes;
pub mod server;

pub use query_settings::QuerySettings;

lazy_static::lazy_static! {
    static ref BRAGI_NB_THREADS: String = (8 * ::num_cpus::get()).to_string();
}

#[derive(StructOpt, Debug, Clone, Default)]
pub struct Args {
    /// Address to bind.
    #[structopt(short = "b", long = "bind", default_value = "127.0.0.1:4000")]
    pub bind: String,
    /// Elasticsearch parameters, override BRAGI_ES environment variable.
    #[structopt(
        short = "c",
        long = "connection-string",
        default_value = "http://localhost:9200/munin",
        env = "BRAGI_ES"
    )]
    pub connection_string: String,
    /// Number of threads used to serve http requests, override BRAGI_NB_THREADS environment variable.
    #[structopt(
        short = "t",
        long = "nb-threads",
        default_value = &BRAGI_NB_THREADS,
        env = "BRAGI_NB_THREADS"
    )]
    pub nb_threads: usize,
    /// Default Max timeout in ms on ES connection.
    /// This timeout is both a network timeout and a timeout given to ES.
    #[structopt(short = "e", long = "max-es-timeout", env = "BRAGI_MAX_ES_TIMEOUT")]
    pub max_es_timeout: Option<u64>,

    /// Custom timeout for the /reverse
    /// this is bounded by `max_es_timeout` and is used because for the moment we cannot easily change the timeout of a given rubber
    #[structopt(long = "max-es-reverse-timeout", env = "BRAGI_MAX_ES_REVERSE_TIMEOUT")]
    pub max_es_reverse_timeout: Option<u64>,
    /// Custom timeout for the /autocomplete
    /// this is bounded by `max_es_timeout` and is used because for the moment we cannot easily change the timeout of a given rubber
    #[structopt(
        long = "max-es-autocomplete-timeout",
        env = "BRAGI_MAX_ES_AUTOCOMPLETE_TIMEOUT"
    )]
    pub max_es_autocomplete_timeout: Option<u64>,
    /// Custom timeout for the /features
    /// this is bounded by `max_es_timeout` and is used because for the moment we cannot easily change the timeout of a given rubber
    #[structopt(
        long = "max-es-features-timeout",
        env = "BRAGI_MAX_ES_FEATURES_TIMEOUT"
    )]
    pub max_es_features_timeout: Option<u64>,

    /// Cache duration for http response served by bragi
    /// This only set the Cache-control Header, it doesn't enable cache on bragi side
    /// The duration is in seconds
    #[structopt(
        long = "http-cache-duration",
        env = "BRAGI_HTTP_CACHE_DURATION",
        default_value = "3600"
    )]
    pub http_cache_duration: u32,
}

#[derive(Clone, Debug)]
pub struct Context {
    reverse_rubber: Rubber,
    features_rubber: Rubber,
    autocomplete_rubber: Rubber,
    pub cnx_string: String,
    pub http_cache_duration: u32,
    // pub rubber: Rubber,
    query_settings: QuerySettings,
}

impl From<&Args> for Context {
    fn from(args: &Args) -> Self {
        let max_es_timeout = args.max_es_timeout.map(Duration::from_millis);

        // the timeout is the min between the timeout set at startup time and at query time
        let bounded_timeout = |specific_timeout: Option<u64>| {
            specific_timeout
                .map(Duration::from_millis)
                .map(|t| match max_es_timeout {
                    Some(dt) => t.min(dt),
                    None => t,
                })
                .or_else(|| max_es_timeout.clone())
        };

        Self {
            reverse_rubber: Rubber::new_with_timeout(
                &args.connection_string,
                bounded_timeout(args.max_es_reverse_timeout),
            ),
            features_rubber: Rubber::new_with_timeout(
                &args.connection_string,
                bounded_timeout(args.max_es_features_timeout),
            ),
            autocomplete_rubber: Rubber::new_with_timeout(
                &args.connection_string,
                bounded_timeout(args.max_es_autocomplete_timeout),
            ),
            cnx_string: args.connection_string.clone(),
            http_cache_duration: args.http_cache_duration.clone(),
            query_settings: QuerySettings::new(include_str!("../../../json/bragi-settings.json"))
                .expect("failed to build query settings"),
        }
    }
}

impl Context {
    pub fn get_rubber_for_reverse(&self, timeout: Option<Duration>) -> Rubber {
        clone_or_create(&self.reverse_rubber, timeout)
    }
    pub fn get_rubber_for_features(&self, timeout: Option<Duration>) -> Rubber {
        clone_or_create(&self.features_rubber, timeout)
    }
    pub fn get_rubber_for_autocomplete(&self, timeout: Option<Duration>) -> Rubber {
        clone_or_create(&self.autocomplete_rubber, timeout)
    }
    pub fn get_query_settings(&self) -> &QuerySettings {
        &self.query_settings
    }
}

fn clone_or_create(rubber: &Rubber, timeout: Option<Duration>) -> Rubber {
    if rubber.timeout == timeout {
        // we clone the rs_es_client, reusing the reqwest connection pool
        rubber.clone()
    } else {
        // if the timeout is different, since there as no easy way to change the timeout for the moment
        // we build a new Rubber (and thus a new connection)
        debug!("creating a new rubber for timeout {:?}", &timeout);
        Rubber::new_with_timeout(&rubber.cnx_string, timeout)
    }
}
<commit_msg>Add option to pass weight settings file<commit_after>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

#[macro_use]
extern crate prometheus;

use mimir::rubber::Rubber;
use slog_scope::debug;
use std::time::Duration;
use structopt::StructOpt;

use std::fs::read_to_string;

mod extractors;
mod model;
pub mod prometheus_middleware;
pub(crate) mod query;
mod query_settings;
mod routes;
pub mod server;

pub use query_settings::QuerySettings;

lazy_static::lazy_static! {
    static ref BRAGI_NB_THREADS: String = (8 * ::num_cpus::get()).to_string();
}

#[derive(StructOpt, Debug, Clone, Default)]
pub struct Args {
    /// Address to bind.
    #[structopt(short = "b", long = "bind", default_value = "127.0.0.1:4000")]
    pub bind: String,
    /// Elasticsearch parameters, override BRAGI_ES environment variable.
    #[structopt(
        short = "c",
        long = "connection-string",
        default_value = "http://localhost:9200/munin",
        env = "BRAGI_ES"
    )]
    pub connection_string: String,
    /// Number of threads used to serve http requests, override BRAGI_NB_THREADS environment variable.
    #[structopt(
        short = "t",
        long = "nb-threads",
        default_value = &BRAGI_NB_THREADS,
        env = "BRAGI_NB_THREADS"
    )]
    pub nb_threads: usize,
    /// Default Max timeout in ms on ES connection.
    /// This timeout is both a network timeout and a timeout given to ES.
    #[structopt(short = "e", long = "max-es-timeout", env = "BRAGI_MAX_ES_TIMEOUT")]
    pub max_es_timeout: Option<u64>,

    /// Custom timeout for the /reverse
    /// this is bounded by `max_es_timeout` and is used because for the moment we cannot easily change the timeout of a given rubber
    #[structopt(long = "max-es-reverse-timeout", env = "BRAGI_MAX_ES_REVERSE_TIMEOUT")]
    pub max_es_reverse_timeout: Option<u64>,
    /// Custom timeout for the /autocomplete
    /// this is bounded by `max_es_timeout` and is used because for the moment we cannot easily change the timeout of a given rubber
    #[structopt(
        long = "max-es-autocomplete-timeout",
        env = "BRAGI_MAX_ES_AUTOCOMPLETE_TIMEOUT"
    )]
    pub max_es_autocomplete_timeout: Option<u64>,
    /// Custom timeout for the /features
    /// this is bounded by `max_es_timeout` and is used because for the moment we cannot easily change the timeout of a given rubber
    #[structopt(
        long = "max-es-features-timeout",
        env = "BRAGI_MAX_ES_FEATURES_TIMEOUT"
    )]
    pub max_es_features_timeout: Option<u64>,

    /// Cache duration for http response served by bragi
    /// This only set the Cache-control Header, it doesn't enable cache on bragi side
    /// The duration is in seconds
    #[structopt(
        long = "http-cache-duration",
        env = "BRAGI_HTTP_CACHE_DURATION",
        default_value = "3600"
    )]
    pub http_cache_duration: u32,
    #[structopt(
        long = "weight-config-file",
        default_value = "json/bragi-settings.json")]
    pub weight_config_file: String,
}

#[derive(Clone, Debug)]
pub struct Context {
    reverse_rubber: Rubber,
    features_rubber: Rubber,
    autocomplete_rubber: Rubber,
    pub cnx_string: String,
    pub http_cache_duration: u32,
    // pub rubber: Rubber,
    query_settings: QuerySettings,
}

impl From<&Args> for Context {
    fn from(args: &Args) -> Self {
        let max_es_timeout = args.max_es_timeout.map(Duration::from_millis);

        // the timeout is the min between the timeout set at startup time and at query time
        let bounded_timeout = |specific_timeout: Option<u64>| {
            specific_timeout
                .map(Duration::from_millis)
                .map(|t| match max_es_timeout {
                    Some(dt) => t.min(dt),
                    None => t,
                })
                .or_else(|| max_es_timeout.clone())
        };

        let content = read_to_string(&args.weight_config_file).expect("cannot read file");
        Self {
            reverse_rubber: Rubber::new_with_timeout(
                &args.connection_string,
                bounded_timeout(args.max_es_reverse_timeout),
            ),
            features_rubber: Rubber::new_with_timeout(
                &args.connection_string,
                bounded_timeout(args.max_es_features_timeout),
            ),
            autocomplete_rubber: Rubber::new_with_timeout(
                &args.connection_string,
                bounded_timeout(args.max_es_autocomplete_timeout),
            ),
            cnx_string: args.connection_string.clone(),
            http_cache_duration: args.http_cache_duration.clone(),
            query_settings: QuerySettings::new(&content).expect("failed to build query settings"),
        }
    }
}

impl Context {
    pub fn get_rubber_for_reverse(&self, timeout: Option<Duration>) -> Rubber {
        clone_or_create(&self.reverse_rubber, timeout)
    }
    pub fn get_rubber_for_features(&self, timeout: Option<Duration>) -> Rubber {
        clone_or_create(&self.features_rubber, timeout)
    }
    pub fn get_rubber_for_autocomplete(&self, timeout: Option<Duration>) -> Rubber {
        clone_or_create(&self.autocomplete_rubber, timeout)
    }
    pub fn get_query_settings(&self) -> &QuerySettings {
        &self.query_settings
    }
}

fn clone_or_create(rubber: &Rubber, timeout: Option<Duration>) -> Rubber {
    if rubber.timeout == timeout {
        // we clone the rs_es_client, reusing the reqwest connection pool
        rubber.clone()
    } else {
        // if the timeout is different, since there as no easy way to change the timeout for the moment
        // we build a new Rubber (and thus a new connection)
        debug!("creating a new rubber for timeout {:?}", &timeout);
        Rubber::new_with_timeout(&rubber.cnx_string, timeout)
    }
}
<|endoftext|>


<commit_before>use hir::{self, ModPath};
use ra_syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SmolStr, SyntaxNode};

use crate::{
    utils::{find_insert_use_container, insert_use_statement},
    AssistContext, AssistId, Assists,
};

// Assist: replace_qualified_name_with_use
//
// Adds a use statement for a given fully-qualified name.
//
// ```
// fn process(map: std::collections::<|>HashMap<String, String>) {}
// ```
// ->
// ```
// use std::collections::HashMap;
//
// fn process(map: HashMap<String, String>) {}
// ```
pub(crate) fn replace_qualified_name_with_use(
    acc: &mut Assists,
    ctx: &AssistContext,
) -> Option<()> {
    let path: ast::Path = ctx.find_node_at_offset()?;
    // We don't want to mess with use statements
    if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() {
        return None;
    }

    let hir_path = ctx.sema.lower_path(&path)?;
    let segments = collect_hir_path_segments(&hir_path)?;
    if segments.len() < 2 {
        return None;
    }

    let target = path.syntax().text_range();
    acc.add(
        AssistId("replace_qualified_name_with_use"),
        "Replace qualified path with use",
        target,
        |builder| {
            let path_to_import = hir_path.mod_path().clone();
            let container = match find_insert_use_container(path.syntax(), ctx) {
                Some(c) => c,
                None => return,
            };
            insert_use_statement(path.syntax(), &path_to_import, ctx, builder.text_edit_builder());

            // Now that we've brought the name into scope, re-qualify all paths that could be
            // affected (that is, all paths inside the node we added the `use` to).
            let hir_path = match hir::Path::from_ast(path.clone()) {
                Some(p) => p,
                None => return,
            };
            let mut rewriter = SyntaxRewriter::default();
            let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone());
            shorten_paths(&mut rewriter, syntax, hir_path.mod_path());
            builder.rewrite(rewriter);
        },
    )
}

fn collect_hir_path_segments(path: &hir::Path) -> Option<Vec<SmolStr>> {
    let mut ps = Vec::<SmolStr>::with_capacity(10);
    match path.kind() {
        hir::PathKind::Abs => ps.push("".into()),
        hir::PathKind::Crate => ps.push("crate".into()),
        hir::PathKind::Plain => {}
        hir::PathKind::Super(0) => ps.push("self".into()),
        hir::PathKind::Super(lvl) => {
            let mut chain = "super".to_string();
            for _ in 0..*lvl {
                chain += "::super";
            }
            ps.push(chain.into());
        }
        hir::PathKind::DollarCrate(_) => return None,
    }
    ps.extend(path.segments().iter().map(|it| it.name.to_string().into()));
    Some(ps)
}

/// Adds replacements to `re` that shorten `path` in all descendants of `node`.
fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: &ModPath) {
    for child in node.children() {
        match_ast! {
            match child {
                // Don't modify `use` items, as this can break the `use` item when injecting a new
                // import into the use tree.
                ast::UseItem(_it) => continue,
                // Don't descend into submodules, they don't have the same `use` items in scope.
                ast::Module(_it) => continue,

                ast::Path(p) => {
                    match maybe_replace_path(rewriter, &p, path) {
                        Some(()) => {},
                        None => shorten_paths(rewriter, p.syntax().clone(), path),
                    }
                },
                _ => shorten_paths(rewriter, child, path),
            }
        }
    }
}

fn maybe_replace_path(
    re: &mut SyntaxRewriter<'static>,
    p: &ast::Path,
    path: &ModPath,
) -> Option<()> {
    let hir_path = hir::Path::from_ast(p.clone())?;

    if hir_path.mod_path() != path {
        return None;
    }

    // Replace path with its last "plain" segment.
    let mut mod_path = hir_path.mod_path().clone();
    let last = mod_path.segments.len() - 1;
    mod_path.segments.swap(0, last);
    mod_path.segments.truncate(1);
    mod_path.kind = hir::PathKind::Plain;

    let mut new_path = crate::ast_transform::path_to_ast(mod_path);

    let type_args = p.segment().and_then(|s| s.type_arg_list());
    if let Some(type_args) = type_args {
        let last_segment = new_path.segment().unwrap();
        new_path = new_path.with_segment(last_segment.with_type_args(type_args));
    }

    re.replace(p.syntax(), new_path.syntax());
    Some(())
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn test_replace_add_use_no_anchor() {
        check_assist(
            replace_qualified_name_with_use,
            r"
std::fmt::Debug<|>
    ",
            r"
use std::fmt::Debug;

Debug
    ",
        );
    }
    #[test]
    fn test_replace_add_use_no_anchor_with_item_below() {
        check_assist(
            replace_qualified_name_with_use,
            r"
std::fmt::Debug<|>

fn main() {
}
    ",
            r"
use std::fmt::Debug;

Debug

fn main() {
}
    ",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_with_item_above() {
        check_assist(
            replace_qualified_name_with_use,
            r"
fn main() {
}

std::fmt::Debug<|>
    ",
            r"
use std::fmt::Debug;

fn main() {
}

Debug
    ",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_2seg() {
        check_assist(
            replace_qualified_name_with_use,
            r"
std::fmt<|>::Debug
    ",
            r"
use std::fmt;

fmt::Debug
    ",
        );
    }

    #[test]
    fn test_replace_add_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use stdx;

impl std::fmt::Debug<|> for Foo {
}
    ",
            r"
use stdx;
use std::fmt::Debug;

impl Debug for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_file_use_other_anchor() {
        check_assist(
            replace_qualified_name_with_use,
            r"
impl std::fmt::Debug<|> for Foo {
}
    ",
            r"
use std::fmt::Debug;

impl Debug for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_add_use_other_anchor_indent() {
        check_assist(
            replace_qualified_name_with_use,
            r"
    impl std::fmt::Debug<|> for Foo {
    }
    ",
            r"
    use std::fmt::Debug;

    impl Debug for Foo {
    }
    ",
        );
    }

    #[test]
    fn test_replace_split_different() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt;

impl std::io<|> for Foo {
}
    ",
            r"
use std::{io, fmt};

impl io for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_split_self_for_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt;

impl std::fmt::Debug<|> for Foo {
}
    ",
            r"
use std::fmt::{self, Debug, };

impl Debug for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_split_self_for_target() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::Debug;

impl std::fmt<|> for Foo {
}
    ",
            r"
use std::fmt::{self, Debug};

impl fmt for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_add_to_nested_self_nested() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::{Debug, nested::{Display}};

impl std::fmt::nested<|> for Foo {
}
",
            r"
use std::fmt::{Debug, nested::{Display, self}};

impl nested for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_add_to_nested_self_already_included() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::{Debug, nested::{self, Display}};

impl std::fmt::nested<|> for Foo {
}
",
            r"
use std::fmt::{Debug, nested::{self, Display}};

impl nested for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_add_to_nested_nested() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::{Debug, nested::{Display}};

impl std::fmt::nested::Debug<|> for Foo {
}
",
            r"
use std::fmt::{Debug, nested::{Display, Debug}};

impl Debug for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_split_common_target_longer() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::Debug;

impl std::fmt::nested::Display<|> for Foo {
}
",
            r"
use std::fmt::{nested::Display, Debug};

impl Display for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_split_common_use_longer() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::nested::Debug;

impl std::fmt::Display<|> for Foo {
}
",
            r"
use std::fmt::{Display, nested::Debug};

impl Display for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_use_nested_import() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use crate::{
    ty::{Substs, Ty},
    AssocItem,
};

fn foo() { crate::ty::lower<|>::trait_env() }
",
            r"
use crate::{
    ty::{Substs, Ty, lower},
    AssocItem,
};

fn foo() { lower::trait_env() }
",
        );
    }

    #[test]
    fn test_replace_alias() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt as foo;

impl foo::Debug<|> for Foo {
}
",
            r"
use std::fmt as foo;

impl Debug for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_not_applicable_one_segment() {
        check_assist_not_applicable(
            replace_qualified_name_with_use,
            r"
impl foo<|> for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_not_applicable_in_use() {
        check_assist_not_applicable(
            replace_qualified_name_with_use,
            r"
use std::fmt<|>;
",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_in_mod_mod() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod foo {
    mod bar {
        std::fmt::Debug<|>
    }
}
    ",
            r"
mod foo {
    mod bar {
        use std::fmt::Debug;

        Debug
    }
}
    ",
        );
    }

    #[test]
    fn inserts_imports_after_inner_attributes() {
        check_assist(
            replace_qualified_name_with_use,
            r"
#![allow(dead_code)]

fn main() {
    std::fmt::Debug<|>
}
    ",
            r"
#![allow(dead_code)]
use std::fmt::Debug;

fn main() {
    Debug
}
    ",
        );
    }

    #[test]
    fn replaces_all_affected_paths() {
        check_assist(
            replace_qualified_name_with_use,
            r"
fn main() {
    std::fmt::Debug<|>;
    let x: std::fmt::Debug = std::fmt::Debug;
}
    ",
            r"
use std::fmt::Debug;

fn main() {
    Debug;
    let x: Debug = Debug;
}
    ",
        );
    }

    #[test]
    fn replaces_all_affected_paths_mod() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod m {
    fn f() {
        std::fmt::Debug<|>;
        let x: std::fmt::Debug = std::fmt::Debug;
    }
    fn g() {
        std::fmt::Debug;
    }
}

fn f() {
    std::fmt::Debug;
}
    ",
            r"
mod m {
    use std::fmt::Debug;

    fn f() {
        Debug;
        let x: Debug = Debug;
    }
    fn g() {
        Debug;
    }
}

fn f() {
    std::fmt::Debug;
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_submodules() {
        check_assist(
            replace_qualified_name_with_use,
            r"
fn main() {
    std::fmt::Debug<|>;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
            r"
use std::fmt::Debug;

fn main() {
    Debug;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::Display;

fn main() {
    std::fmt<|>;
}
    ",
            r"
use std::fmt::{self, Display};

fn main() {
    fmt;
}
    ",
        );
    }
}
<commit_msg>Operate only on AST paths instead of HIR<commit_after>use hir;
use ra_syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SmolStr, SyntaxNode};

use crate::{
    utils::{find_insert_use_container, insert_use_statement},
    AssistContext, AssistId, Assists,
};

// Assist: replace_qualified_name_with_use
//
// Adds a use statement for a given fully-qualified name.
//
// ```
// fn process(map: std::collections::<|>HashMap<String, String>) {}
// ```
// ->
// ```
// use std::collections::HashMap;
//
// fn process(map: HashMap<String, String>) {}
// ```
pub(crate) fn replace_qualified_name_with_use(
    acc: &mut Assists,
    ctx: &AssistContext,
) -> Option<()> {
    let path: ast::Path = ctx.find_node_at_offset()?;
    // We don't want to mess with use statements
    if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() {
        return None;
    }

    let hir_path = ctx.sema.lower_path(&path)?;
    let segments = collect_hir_path_segments(&hir_path)?;
    if segments.len() < 2 {
        return None;
    }

    let target = path.syntax().text_range();
    acc.add(
        AssistId("replace_qualified_name_with_use"),
        "Replace qualified path with use",
        target,
        |builder| {
            let path_to_import = hir_path.mod_path().clone();
            let container = match find_insert_use_container(path.syntax(), ctx) {
                Some(c) => c,
                None => return,
            };
            insert_use_statement(path.syntax(), &path_to_import, ctx, builder.text_edit_builder());

            // Now that we've brought the name into scope, re-qualify all paths that could be
            // affected (that is, all paths inside the node we added the `use` to).
            let mut rewriter = SyntaxRewriter::default();
            let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone());
            shorten_paths(&mut rewriter, syntax, path);
            builder.rewrite(rewriter);
        },
    )
}

fn collect_hir_path_segments(path: &hir::Path) -> Option<Vec<SmolStr>> {
    let mut ps = Vec::<SmolStr>::with_capacity(10);
    match path.kind() {
        hir::PathKind::Abs => ps.push("".into()),
        hir::PathKind::Crate => ps.push("crate".into()),
        hir::PathKind::Plain => {}
        hir::PathKind::Super(0) => ps.push("self".into()),
        hir::PathKind::Super(lvl) => {
            let mut chain = "super".to_string();
            for _ in 0..*lvl {
                chain += "::super";
            }
            ps.push(chain.into());
        }
        hir::PathKind::DollarCrate(_) => return None,
    }
    ps.extend(path.segments().iter().map(|it| it.name.to_string().into()));
    Some(ps)
}

/// Adds replacements to `re` that shorten `path` in all descendants of `node`.
fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: ast::Path) {
    for child in node.children() {
        match_ast! {
            match child {
                // Don't modify `use` items, as this can break the `use` item when injecting a new
                // import into the use tree.
                ast::UseItem(_it) => continue,
                // Don't descend into submodules, they don't have the same `use` items in scope.
                ast::Module(_it) => continue,

                ast::Path(p) => {
                    match maybe_replace_path(rewriter, p.clone(), path.clone()) {
                        Some(()) => {},
                        None => shorten_paths(rewriter, p.syntax().clone(), path.clone()),
                    }
                },
                _ => shorten_paths(rewriter, child, path.clone()),
            }
        }
    }
}

fn maybe_replace_path(
    rewriter: &mut SyntaxRewriter<'static>,
    path: ast::Path,
    target: ast::Path,
) -> Option<()> {
    if !path_eq(path.clone(), target.clone()) {
        return None;
    }

    // Shorten `path`, leaving only its last segment.
    if let Some(parent) = path.qualifier() {
        rewriter.delete(parent.syntax());
    }
    if let Some(double_colon) = path.coloncolon_token() {
        rewriter.delete(&double_colon);
    }

    Some(())
}

fn path_eq(lhs: ast::Path, rhs: ast::Path) -> bool {
    let mut lhs_curr = lhs;
    let mut rhs_curr = rhs;
    loop {
        match (lhs_curr.segment(), rhs_curr.segment()) {
            (Some(lhs), Some(rhs)) if lhs.syntax().text() == rhs.syntax().text() => (),
            _ => return false,
        }

        match (lhs_curr.qualifier(), rhs_curr.qualifier()) {
            (Some(lhs), Some(rhs)) => {
                lhs_curr = lhs;
                rhs_curr = rhs;
            }
            (None, None) => return true,
            _ => return false,
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn test_replace_add_use_no_anchor() {
        check_assist(
            replace_qualified_name_with_use,
            r"
std::fmt::Debug<|>
    ",
            r"
use std::fmt::Debug;

Debug
    ",
        );
    }
    #[test]
    fn test_replace_add_use_no_anchor_with_item_below() {
        check_assist(
            replace_qualified_name_with_use,
            r"
std::fmt::Debug<|>

fn main() {
}
    ",
            r"
use std::fmt::Debug;

Debug

fn main() {
}
    ",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_with_item_above() {
        check_assist(
            replace_qualified_name_with_use,
            r"
fn main() {
}

std::fmt::Debug<|>
    ",
            r"
use std::fmt::Debug;

fn main() {
}

Debug
    ",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_2seg() {
        check_assist(
            replace_qualified_name_with_use,
            r"
std::fmt<|>::Debug
    ",
            r"
use std::fmt;

fmt::Debug
    ",
        );
    }

    #[test]
    fn test_replace_add_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use stdx;

impl std::fmt::Debug<|> for Foo {
}
    ",
            r"
use stdx;
use std::fmt::Debug;

impl Debug for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_file_use_other_anchor() {
        check_assist(
            replace_qualified_name_with_use,
            r"
impl std::fmt::Debug<|> for Foo {
}
    ",
            r"
use std::fmt::Debug;

impl Debug for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_add_use_other_anchor_indent() {
        check_assist(
            replace_qualified_name_with_use,
            r"
    impl std::fmt::Debug<|> for Foo {
    }
    ",
            r"
    use std::fmt::Debug;

    impl Debug for Foo {
    }
    ",
        );
    }

    #[test]
    fn test_replace_split_different() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt;

impl std::io<|> for Foo {
}
    ",
            r"
use std::{io, fmt};

impl io for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_split_self_for_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt;

impl std::fmt::Debug<|> for Foo {
}
    ",
            r"
use std::fmt::{self, Debug, };

impl Debug for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_split_self_for_target() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::Debug;

impl std::fmt<|> for Foo {
}
    ",
            r"
use std::fmt::{self, Debug};

impl fmt for Foo {
}
    ",
        );
    }

    #[test]
    fn test_replace_add_to_nested_self_nested() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::{Debug, nested::{Display}};

impl std::fmt::nested<|> for Foo {
}
",
            r"
use std::fmt::{Debug, nested::{Display, self}};

impl nested for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_add_to_nested_self_already_included() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::{Debug, nested::{self, Display}};

impl std::fmt::nested<|> for Foo {
}
",
            r"
use std::fmt::{Debug, nested::{self, Display}};

impl nested for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_add_to_nested_nested() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::{Debug, nested::{Display}};

impl std::fmt::nested::Debug<|> for Foo {
}
",
            r"
use std::fmt::{Debug, nested::{Display, Debug}};

impl Debug for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_split_common_target_longer() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::Debug;

impl std::fmt::nested::Display<|> for Foo {
}
",
            r"
use std::fmt::{nested::Display, Debug};

impl Display for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_split_common_use_longer() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::nested::Debug;

impl std::fmt::Display<|> for Foo {
}
",
            r"
use std::fmt::{Display, nested::Debug};

impl Display for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_use_nested_import() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use crate::{
    ty::{Substs, Ty},
    AssocItem,
};

fn foo() { crate::ty::lower<|>::trait_env() }
",
            r"
use crate::{
    ty::{Substs, Ty, lower},
    AssocItem,
};

fn foo() { lower::trait_env() }
",
        );
    }

    #[test]
    fn test_replace_alias() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt as foo;

impl foo::Debug<|> for Foo {
}
",
            r"
use std::fmt as foo;

impl Debug for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_not_applicable_one_segment() {
        check_assist_not_applicable(
            replace_qualified_name_with_use,
            r"
impl foo<|> for Foo {
}
",
        );
    }

    #[test]
    fn test_replace_not_applicable_in_use() {
        check_assist_not_applicable(
            replace_qualified_name_with_use,
            r"
use std::fmt<|>;
",
        );
    }

    #[test]
    fn test_replace_add_use_no_anchor_in_mod_mod() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod foo {
    mod bar {
        std::fmt::Debug<|>
    }
}
    ",
            r"
mod foo {
    mod bar {
        use std::fmt::Debug;

        Debug
    }
}
    ",
        );
    }

    #[test]
    fn inserts_imports_after_inner_attributes() {
        check_assist(
            replace_qualified_name_with_use,
            r"
#![allow(dead_code)]

fn main() {
    std::fmt::Debug<|>
}
    ",
            r"
#![allow(dead_code)]
use std::fmt::Debug;

fn main() {
    Debug
}
    ",
        );
    }

    #[test]
    fn replaces_all_affected_paths() {
        check_assist(
            replace_qualified_name_with_use,
            r"
fn main() {
    std::fmt::Debug<|>;
    let x: std::fmt::Debug = std::fmt::Debug;
}
    ",
            r"
use std::fmt::Debug;

fn main() {
    Debug;
    let x: Debug = Debug;
}
    ",
        );
    }

    #[test]
    fn replaces_all_affected_paths_mod() {
        check_assist(
            replace_qualified_name_with_use,
            r"
mod m {
    fn f() {
        std::fmt::Debug<|>;
        let x: std::fmt::Debug = std::fmt::Debug;
    }
    fn g() {
        std::fmt::Debug;
    }
}

fn f() {
    std::fmt::Debug;
}
    ",
            r"
mod m {
    use std::fmt::Debug;

    fn f() {
        Debug;
        let x: Debug = Debug;
    }
    fn g() {
        Debug;
    }
}

fn f() {
    std::fmt::Debug;
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_submodules() {
        check_assist(
            replace_qualified_name_with_use,
            r"
fn main() {
    std::fmt::Debug<|>;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
            r"
use std::fmt::Debug;

fn main() {
    Debug;
}

mod sub {
    fn f() {
        std::fmt::Debug;
    }
}
    ",
        );
    }

    #[test]
    fn does_not_replace_in_use() {
        check_assist(
            replace_qualified_name_with_use,
            r"
use std::fmt::Display;

fn main() {
    std::fmt<|>;
}
    ",
            r"
use std::fmt::{self, Display};

fn main() {
    fmt;
}
    ",
        );
    }
}
<|endoftext|>


<commit_before>extern crate core;
extern crate libc;
extern crate minifb;
extern crate prodbg_api;
extern crate bgfx_rs;
extern crate imgui_sys;

pub mod windows;
pub mod menu;

use bgfx_rs::Bgfx;
use core::session::Sessions;
use windows::Windows;
use core::{DynamicReload, Search};
use core::view_plugins::{ViewPlugins};
use core::backend_plugin::{BackendPlugins};
use std::cell::RefCell;
use std::rc::Rc;

use core::plugins::*;

fn main() {
    let bgfx = Bgfx::new();
    let mut sessions = Sessions::new();
    let mut windows = Windows::new();

    let mut lib_handler = DynamicReload::new(None, Some("t2-output"), Search::Backwards);
    let mut plugins = Plugins::new();

    let view_plugins = Rc::new(RefCell::new(ViewPlugins::new()));
    let backend_plugins = Rc::new(RefCell::new(BackendPlugins::new()));

    let session = sessions.create_instance();

    plugins.add_handler(&view_plugins);
    plugins.add_handler(&backend_plugins);

    plugins.add_plugin(&mut lib_handler, "dummy_backend_plugin");
    plugins.add_plugin(&mut lib_handler, "bitmap_memory");
    plugins.add_plugin(&mut lib_handler, "registers_plugin");
    plugins.add_plugin(&mut lib_handler, "hex_memory_plugin");

    windows.create_default();

    // test code, we set dummy backend as active

    if let Some(backend) = backend_plugins.borrow_mut().create_instance(&"Dummy Backend".to_owned()) {
        if let Some(session) = sessions.get_session(session) {
            session.set_backend(Some(backend));
        }
    }

    loop {
        bgfx.pre_update();

        plugins.update(&mut lib_handler);
        sessions.update(&mut backend_plugins.borrow_mut());
        windows.update(&mut sessions, &mut view_plugins.borrow_mut(), &mut backend_plugins.borrow_mut());

        if windows.should_exit() {
            break;
        }

        bgfx.post_update();
    }
}

// dummy
#[no_mangle]
pub fn init_plugin() {
}
<commit_msg>Load UAE plugin and removed dummy_backend creation<commit_after>extern crate core;
extern crate libc;
extern crate minifb;
extern crate prodbg_api;
extern crate bgfx_rs;
extern crate imgui_sys;

pub mod windows;
pub mod menu;

use bgfx_rs::Bgfx;
use core::session::Sessions;
use windows::Windows;
use core::{DynamicReload, Search};
use core::view_plugins::{ViewPlugins};
use core::backend_plugin::{BackendPlugins};
use std::cell::RefCell;
use std::rc::Rc;

use core::plugins::*;

fn main() {
    let bgfx = Bgfx::new();
    let mut sessions = Sessions::new();
    let mut windows = Windows::new();

    let mut lib_handler = DynamicReload::new(None, Some("t2-output"), Search::Backwards);
    let mut plugins = Plugins::new();

    let view_plugins = Rc::new(RefCell::new(ViewPlugins::new()));
    let backend_plugins = Rc::new(RefCell::new(BackendPlugins::new()));

    let _ = sessions.create_instance();

    plugins.add_handler(&view_plugins);
    plugins.add_handler(&backend_plugins);

    plugins.add_plugin(&mut lib_handler, "dummy_backend_plugin");
    plugins.add_plugin(&mut lib_handler, "amiga_uae_plugin");
    plugins.add_plugin(&mut lib_handler, "bitmap_memory");
    plugins.add_plugin(&mut lib_handler, "registers_plugin");
    plugins.add_plugin(&mut lib_handler, "hex_memory_plugin");

    windows.create_default();

    loop {
        bgfx.pre_update();

        plugins.update(&mut lib_handler);
        sessions.update(&mut backend_plugins.borrow_mut());
        windows.update(&mut sessions, &mut view_plugins.borrow_mut(), &mut backend_plugins.borrow_mut());

        if windows.should_exit() {
            break;
        }

        bgfx.post_update();
    }
}

// dummy
#[no_mangle]
pub fn init_plugin() {
}
<|endoftext|>


<commit_before>extern crate minifb;

use minifb::{Key, MENU_KEY_CTRL, MENU_KEY_COMMAND};
use minifb::Menu as MinifbMenu;

const MENU_FILE_OPEN_AND_RUN_EXE: usize = 1;
const MENU_FILE_OPEN_SOURCE: usize = 1;
const MENU_DEBUG_ATTACH_TO_REMOTE: usize = 50;
const MENU_DEBUG_START: usize = 51;
const MENU_DEBUG_STEP_IN: usize = 52;
const MENU_DEBUG_STEP_OVER: usize = 53;
const MENU_DEBUG_TOGGLE_BREAKPOINT: usize = 54;

pub struct Menu<'a> {
    pub file_menu: Vec<MinifbMenu<'a>>,
    pub debug_menu: Vec<MinifbMenu<'a>>,
}

impl<'a> Menu<'a> {
    pub fn new() -> Menu<'a> {
        Menu {
            file_menu: Self::create_file_menu(),
            debug_menu: Self::create_debug_menu(),
        }
    }

    pub fn create_file_menu() -> Vec<MinifbMenu<'a>> {
        vec![
            MinifbMenu {
                name: "Open and run executable...",
                key: Key::D,
                id: MENU_FILE_OPEN_AND_RUN_EXE,
                modifier: MENU_KEY_CTRL,
                mac_mod: MENU_KEY_COMMAND,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Open Source...",
                key: Key::O,
                id: MENU_FILE_OPEN_SOURCE,
                modifier: MENU_KEY_CTRL,
                mac_mod: MENU_KEY_COMMAND,
                ..MinifbMenu::default()
            }
        ]
    }

    pub fn create_debug_menu() -> Vec<MinifbMenu<'a>> {
        vec![
            MinifbMenu {
                name: "Attach to Remote...",
                key: Key::F6,
                id: MENU_DEBUG_ATTACH_TO_REMOTE ,
                ..MinifbMenu::default()
            },
            MinifbMenu  {
                name: "Start",
                key: Key::S,
                id: MENU_DEBUG_START,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Step In",
                key: Key::F11,
                id: MENU_DEBUG_STEP_IN,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Step Over",
                key: Key::F10,
                id: MENU_DEBUG_STEP_OVER,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Toggle Breakpoint",
                key: Key::F9,
                id: MENU_DEBUG_TOGGLE_BREAKPOINT,
                ..MinifbMenu::default()
            }
        ]
    }
}

<commit_msg>Use F5 for start<commit_after>extern crate minifb;

use minifb::{Key, MENU_KEY_CTRL, MENU_KEY_COMMAND};
use minifb::Menu as MinifbMenu;

const MENU_FILE_OPEN_AND_RUN_EXE: usize = 1;
const MENU_FILE_OPEN_SOURCE: usize = 1;
const MENU_DEBUG_ATTACH_TO_REMOTE: usize = 50;
const MENU_DEBUG_START: usize = 51;
const MENU_DEBUG_STEP_IN: usize = 52;
const MENU_DEBUG_STEP_OVER: usize = 53;
const MENU_DEBUG_TOGGLE_BREAKPOINT: usize = 54;

pub struct Menu<'a> {
    pub file_menu: Vec<MinifbMenu<'a>>,
    pub debug_menu: Vec<MinifbMenu<'a>>,
}

impl<'a> Menu<'a> {
    pub fn new() -> Menu<'a> {
        Menu {
            file_menu: Self::create_file_menu(),
            debug_menu: Self::create_debug_menu(),
        }
    }

    pub fn create_file_menu() -> Vec<MinifbMenu<'a>> {
        vec![
            MinifbMenu {
                name: "Open and run executable...",
                key: Key::D,
                id: MENU_FILE_OPEN_AND_RUN_EXE,
                modifier: MENU_KEY_CTRL,
                mac_mod: MENU_KEY_COMMAND,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Open Source...",
                key: Key::O,
                id: MENU_FILE_OPEN_SOURCE,
                modifier: MENU_KEY_CTRL,
                mac_mod: MENU_KEY_COMMAND,
                ..MinifbMenu::default()
            }
        ]
    }

    pub fn create_debug_menu() -> Vec<MinifbMenu<'a>> {
        vec![
            MinifbMenu {
                name: "Attach to Remote...",
                key: Key::F6,
                id: MENU_DEBUG_ATTACH_TO_REMOTE ,
                ..MinifbMenu::default()
            },
            MinifbMenu  {
                name: "Start",
                key: Key::F5,
                id: MENU_DEBUG_START,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Step In",
                key: Key::F11,
                id: MENU_DEBUG_STEP_IN,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Step Over",
                key: Key::F10,
                id: MENU_DEBUG_STEP_OVER,
                ..MinifbMenu::default()
            },
            MinifbMenu {
                name: "Toggle Breakpoint",
                key: Key::F9,
                id: MENU_DEBUG_TOGGLE_BREAKPOINT,
                ..MinifbMenu::default()
            }
        ]
    }
}

<|endoftext|>


<commit_before>//! Camera.

use glium::Display;
use cgmath::Matrix4;
use transform::Transform;
use Mat;

/// Camera types.
pub trait Camera
{
    /// Returns a camera matrix.
    fn matrix(&self) -> Mat;

    fn array(&self) -> [[f32; 4]; 4] { self.matrix().into() }
}

/// 2D Camera generator.
///
/// Converts screen coordinate to OpenGL world coordinate.
pub struct Camera2D
{
    display: Display,
    transform: Transform,
}

impl Camera2D
{
    pub fn new(display: &Display) -> Camera2D
    {
        Camera2D
        {
            display: display.clone(),
            transform: Transform::new(),
        }
    }
}

impl Camera for Camera2D
{
    fn matrix(&self) -> Matrix4<f32>
    {
        let factor = self.display.get_window().unwrap().hidpi_factor();
        let (w, h) = self.display.get_framebuffer_dimensions();
        let (w, h) = (w as f32, h as f32);
        let f = factor * 2.0;
        Mat::new(
             f/w,  0.0,  0.0, 0.0,
             0.0, -f/h,  0.0, 0.0,
             0.0,  0.0, -1.0, 0.0,
            -1.0,  1.0,  0.0, 1.0,
        ) * self.transform.matrix()
    }
}
<commit_msg>Replace `Matrix4<f32>` with `Mat`.<commit_after>//! Camera.

use glium::Display;
use cgmath::Matrix4;
use transform::Transform;
use Mat;

/// Camera types.
pub trait Camera
{
    /// Returns a camera matrix.
    fn matrix(&self) -> Mat;

    fn array(&self) -> [[f32; 4]; 4] { self.matrix().into() }
}

/// 2D Camera generator.
///
/// Converts screen coordinate to OpenGL world coordinate.
pub struct Camera2D
{
    display: Display,
    transform: Transform,
}

impl Camera2D
{
    pub fn new(display: &Display) -> Camera2D
    {
        Camera2D
        {
            display: display.clone(),
            transform: Transform::new(),
        }
    }
}

impl Camera for Camera2D
{
    fn matrix(&self) -> Mat
    {
        let factor = self.display.get_window().unwrap().hidpi_factor();
        let (w, h) = self.display.get_framebuffer_dimensions();
        let (w, h) = (w as f32, h as f32);
        let f = factor * 2.0;
        Mat::new(
             f/w,  0.0,  0.0, 0.0,
             0.0, -f/h,  0.0, 0.0,
             0.0,  0.0, -1.0, 0.0,
            -1.0,  1.0,  0.0, 1.0,
        ) * self.transform.matrix()
    }
}
<|endoftext|>


<commit_before>//! The `style` element.

use cssparser::Parser;
use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::error::*;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::{Parse, ParseValue};
use crate::property_bag::PropertyBag;

/// Represents the syntax used in the <style> node.
///
/// Currently only "text/css" is supported.
///
/// https://www.w3.org/TR/SVG11/styling.html#StyleElementTypeAttribute
/// https://www.w3.org/TR/SVG11/styling.html#ContentStyleTypeAttribute
#[derive(Copy, Clone, PartialEq)]
pub enum StyleType {
    TextCss,
}

impl Parse for StyleType {
    fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<StyleType, ParseError<'i>> {
        parser.expect_ident_matching("text/css")?;
        Ok(StyleType::TextCss)
    }
}

/// Represents a <style> node.
///
/// It does not render itself, and just holds CSS stylesheet information for the rest of
/// the code to use.
#[derive(Default)]
pub struct Style {
    type_: Option<StyleType>,
}

impl Style {
    pub fn style_type(&self) -> Option<StyleType> {
        self.type_
    }
}

impl NodeTrait for Style {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            if attr.expanded() == expanded_name!("", "type") {
                self.type_ = Some(attr.parse(value)?);
            }
        }

        Ok(())
    }
}
<commit_msg>Parse the "type" attribute of the style element without cssparser<commit_after>//! The `style` element.

use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::error::*;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::property_bag::PropertyBag;

/// Represents the syntax used in the <style> node.
///
/// Currently only "text/css" is supported.
///
/// https://www.w3.org/TR/SVG11/styling.html#StyleElementTypeAttribute
/// https://www.w3.org/TR/SVG11/styling.html#ContentStyleTypeAttribute
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum StyleType {
    TextCss,
}

impl StyleType {
    fn parse(value: &str) -> Result<StyleType, ValueErrorKind> {
        // https://html.spec.whatwg.org/multipage/semantics.html#the-style-element
        //
        // 4. If element's type attribute is present and its value is
        // neither the empty string nor an ASCII case-insensitive
        // match for "text/css", then return.

        if value.eq_ignore_ascii_case("text/css") {
            Ok(StyleType::TextCss)
        } else {
            Err(ValueErrorKind::parse_error(
                "invalid value for type attribute in style element",
            ))
        }
    }
}

/// Represents a <style> node.
///
/// It does not render itself, and just holds CSS stylesheet information for the rest of
/// the code to use.
#[derive(Default)]
pub struct Style {
    type_: Option<StyleType>,
}

impl Style {
    pub fn style_type(&self) -> Option<StyleType> {
        self.type_
    }
}

impl NodeTrait for Style {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            if attr.expanded() == expanded_name!("", "type") {
                self.type_ = Some(StyleType::parse(value).attribute(attr)?);
            }
        }

        Ok(())
    }
}

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

    #[test]
    fn parses_style_type() {
        assert_eq!(StyleType::parse("text/css"), Ok(StyleType::TextCss));
    }

    #[test]
    fn invalid_style_type_yields_error() {
        assert!(StyleType::parse("").is_err());
        assert!(StyleType::parse("some-other-stylesheet-language").is_err());
    }
}
<|endoftext|>


<commit_before>use rustc_serialize::hex::{ToHex, FromHex};
use rustc_serialize::base64::{ToBase64, FromBase64, STANDARD};
use std::str;
use std::io::BufReader;
use std::io::BufWriter;
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::cmp;
use std::fs::OpenOptions;
use std::fs;

pub struct CipherText(Vec<u8>);

impl CipherText {
    pub fn new(bytes: &[u8]) -> CipherText {
        CipherText(bytes.to_vec())
    }

    pub fn from_hex(hex: &str) -> Result<CipherText, Error> {
        let cipher_bytes: Vec<u8> = try!(hex.from_hex()
            .map_err(|e| Error::Hex(e.to_string())));
        Ok(CipherText(cipher_bytes))
    }

    pub fn to_hex(&self) -> String {
        let &CipherText(ref vec_bytes) = self;
        vec_bytes.to_hex()
    }

    pub fn from_b64(b64: &str) -> Result<CipherText, Error> {
        let cipher_bytes: Vec<u8> = try!(b64.from_base64()
            .map_err(|e| Error::Base64(e.to_string())));
        Ok(CipherText(cipher_bytes))
    }

    pub fn to_b64(&self) -> String {
        let &CipherText(ref vec_bytes) = self;
        vec_bytes.to_base64(STANDARD)
    }

    pub fn from_file(path: &str) -> Result<CipherText, Error> {
        let mut text = String::new();
        let file = try!(File::open(Path::new(path)).map_err(|e| Error::File(e.to_string())));
        let in_file = BufReader::new(file);
        for line in in_file.lines() {
            text.push_str(&line.unwrap());
        }
        CipherText::from_b64(&text)
    }

    pub fn to_file(&self, path: &str) -> Result<(), Error> {

        let text_b64 = self.to_b64();

        if file_exists(path) {
            try!(fs::remove_file(path).map_err(|e| Error::File(e.to_string())));
        }

        let mut file = try!(OpenOptions::new()
            .write(true)
            .append(true)
            .create(true)
            .open(path)
            .map_err(|e| Error::File(e.to_string())));

        let mut i = 0;
        let mut j = cmp::min(text_b64.len(), 80);
        while i != j {
            try!(file.write_all(&text_b64[i..j].as_bytes())
                .map_err(|e| Error::File(e.to_string())));

            try!(file.write_all("\n".as_bytes()).map_err(|e| Error::File(e.to_string())));

            i = j;
            j = cmp::min(text_b64.len(), j + 80);
        }
        Ok(())
    }
}

fn file_exists(path: &str) -> bool {
    fs::metadata(path).is_ok()
}

pub struct PlainText(Vec<u8>);

impl PlainText {
    pub fn from_string(string: &str) -> PlainText {
        PlainText(string.as_bytes().to_vec())
    }

    pub fn from_bytes(bytes: &[u8]) -> PlainText {
        PlainText(bytes.to_vec())
    }

    pub fn from_file(path: &str) -> Result<PlainText, Error> {
        let file = try!(File::open(Path::new(path)).map_err(|e| Error::File(e.to_string())));
        let mut in_file = BufReader::new(file);
        let mut text = String::new();
        try!(in_file.read_to_string(&mut text)
            .map_err(|e| Error::File(e.to_string())));
        Ok(PlainText::from_string(&text))

    }

    pub fn to_file(&self, path: &str) -> Result<(), Error> {
        let &PlainText(ref vec_bytes) = self;
        let file = try!(OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open(path)
            .map_err(|e| Error::File(e.to_string())));

        let mut out_file = BufWriter::new(file);
        try!(out_file.write_all(&vec_bytes).map_err(|e| Error::File(e.to_string())));

        Ok(())
    }

    pub fn to_utf8(&self) -> Result<String, Error> {
        let &PlainText(ref vec_bytes) = self;
        let plain = try!(str::from_utf8(&vec_bytes).map_err(|e| Error::UTF8(e.to_string())));
        Ok(plain.to_string())
    }
}

pub fn encrypt(text: &PlainText, key: &str) -> CipherText {
    let &PlainText(ref bytes) = text;
    let xored: Vec<u8> = repeating_xor(bytes, key.as_bytes());
    CipherText::new(&xored)
}

pub fn decrypt(cipher_text: &CipherText, key: &str) -> Result<PlainText, Error> {
    let &CipherText(ref bytes) = cipher_text;
    let xored: Vec<u8> = repeating_xor(bytes, key.as_bytes());
    Ok(PlainText::from_bytes(&xored))
}

pub fn decrypt_file(input_path: &str, output_path: &str, key: &str) -> Result<(), Error> {
    let cipher = try!(CipherText::from_file(input_path));
    let plain = try!(decrypt(&cipher, key));
    try!(plain.to_file(output_path));
    Ok(())
}

pub fn encrypt_file(input_path: &str, output_path: &str, key: &str) -> Result<(), Error> {
    let plain = try!(PlainText::from_file(input_path));
    let cipher = encrypt(&plain, key);
    try!(cipher.to_file(output_path));
    Ok(())
}

#[derive(Debug)]
pub enum Error {
    Hex(String),
    Base64(String),
    UTF8(String),
    File(String),
}

fn repeating_xor(input: &[u8], key: &[u8]) -> Vec<u8> {
    let mut out: Vec<u8> = Vec::with_capacity(input.len());
    unsafe {
        out.set_len(input.len());
    }
    for (i, in_val) in input.iter().enumerate() {
        out[i] = in_val ^ key[i % key.len()];
    }
    out
}

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

    #[test]
    fn test_encrypt_and_decrypt() {
        check_text("This is the plain text\n");
        check_text("123, 456");
        check_text("!£$%^&*@~:");
        check_text("日本語");
    }

    #[test]
    fn test_encrypt_and_decrypt_files() {
        check_text_file("This is the plain text\n");
        check_text_file("123, 456");
        check_text_file("!£$%^&*@~:");
        check_text_file("日本語");
        check_text_file("This is the plain text\nThis is the plain text\nThis is the plain text\n");
    }

    #[test]
    fn test_wrong_key() {
        let text = "This is the plain text";
        let plain_text = PlainText::from_string(text);
        let key: &str = "toy";
        let decoded_text = decrypt(&encrypt(&plain_text, key), "wrong_key").unwrap();
        assert!(text != decoded_text.to_utf8().unwrap());
    }

    fn check_text(text: &str) {
        let plain_text = PlainText::from_string(text);
        let key: &str = "toy";
        let decoded_text = decrypt(&encrypt(&plain_text, key), key).unwrap();
        assert_eq!(text, decoded_text.to_utf8().unwrap());
    }

    fn check_text_file(text: &str) {
        let plain_text = PlainText::from_string(text);
        let key: &str = "toy";
        let plain_path = "./target/test-plain.txt";
        let cipher_path = "./target/test-cipher.txt";
        let decoded_path = "./target/test-decoded.txt";

        plain_text.to_file(plain_path).unwrap();
        encrypt_file(plain_path, cipher_path, key).unwrap();
        decrypt_file(cipher_path, decoded_path, key).unwrap();
        let decoded_text = PlainText::from_file(decoded_path).unwrap();

        assert_eq!(text, decoded_text.to_utf8().unwrap());
    }

}
<commit_msg>File Optimizations<commit_after>use rustc_serialize::hex::{ToHex, FromHex};
use rustc_serialize::base64::{ToBase64, FromBase64, STANDARD};
use std::str;
use std::io::BufWriter;
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::cmp;
use std::fs::OpenOptions;
use std::fs;

pub struct CipherText(Vec<u8>);

impl CipherText {
    pub fn new(bytes: &[u8]) -> CipherText {
        CipherText(bytes.to_vec())
    }

    pub fn from_hex(hex: &str) -> Result<CipherText, Error> {
        let cipher_bytes: Vec<u8> = try!(hex.from_hex()
            .map_err(|e| Error::Hex(e.to_string())));
        Ok(CipherText(cipher_bytes))
    }

    pub fn to_hex(&self) -> String {
        let &CipherText(ref vec_bytes) = self;
        vec_bytes.to_hex()
    }

    pub fn from_b64(b64: &str) -> Result<CipherText, Error> {
        let cipher_bytes: Vec<u8> = try!(b64.from_base64()
            .map_err(|e| Error::Base64(e.to_string())));
        Ok(CipherText(cipher_bytes))
    }

    pub fn to_b64(&self) -> String {
        let &CipherText(ref vec_bytes) = self;
        vec_bytes.to_base64(STANDARD)
    }

    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<CipherText, Error> {
        let path = path.as_ref();
        let mut file = try!(File::open(Path::new(path)).map_err(|e| Error::File(e.to_string())));
        let capacity = file.metadata().ok().map_or(0, |x| x.len());
        let mut buffer = String::with_capacity(capacity as usize);
        try!(file.read_to_string(&mut buffer).map_err(|e| Error::File(e.to_string())));
        CipherText::from_b64(&buffer)
    }

    pub fn to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
        let path = path.as_ref();
        let text_b64 = self.to_b64();
        if path.exists() {
            try!(fs::remove_file(path).map_err(|e| Error::File(e.to_string())));
        }

        let mut file = try!(OpenOptions::new()
            .write(true)
            .append(true)
            .create(true)
            .open(path)
            .map_err(|e| Error::File(e.to_string())));

        let mut i = 0;
        let mut j = cmp::min(text_b64.len(), 80);
        while i != j {
            try!(file.write_all(&text_b64[i..j].as_bytes())
                .map_err(|e| Error::File(e.to_string())));

            try!(file.write_all("\n".as_bytes()).map_err(|e| Error::File(e.to_string())));

            i = j;
            j = cmp::min(text_b64.len(), j + 80);
        }
        Ok(())
    }
}
pub struct PlainText(Vec<u8>);

impl PlainText {
    pub fn from_string(string: &str) -> PlainText {
        PlainText(string.as_bytes().to_vec())
    }

    pub fn from_bytes(bytes: &[u8]) -> PlainText {
        PlainText(bytes.to_vec())
    }

    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<PlainText, Error> {
        let path = path.as_ref();
        let mut file = try!(File::open(Path::new(path)).map_err(|e| Error::File(e.to_string())));
        let capacity = file.metadata().ok().map_or(0, |x| x.len());
        let mut buffer = String::with_capacity(capacity as usize);
        try!(file.read_to_string(&mut buffer).map_err(|e| Error::File(e.to_string())));
        Ok(PlainText::from_string(&buffer))

    }

    pub fn to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
        let path = path.as_ref();
        let &PlainText(ref vec_bytes) = self;
        let file = try!(OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open(path)
            .map_err(|e| Error::File(e.to_string())));

        let mut out_file = BufWriter::new(file);
        try!(out_file.write_all(&vec_bytes).map_err(|e| Error::File(e.to_string())));

        Ok(())
    }

    pub fn to_utf8(&self) -> Result<String, Error> {
        let &PlainText(ref vec_bytes) = self;
        let plain = try!(str::from_utf8(&vec_bytes).map_err(|e| Error::UTF8(e.to_string())));
        Ok(plain.to_string())
    }
}

pub fn encrypt(text: &PlainText, key: &str) -> CipherText {
    let &PlainText(ref bytes) = text;
    let xored: Vec<u8> = repeating_xor(bytes, key.as_bytes());
    CipherText::new(&xored)
}

pub fn decrypt(cipher_text: &CipherText, key: &str) -> Result<PlainText, Error> {
    let &CipherText(ref bytes) = cipher_text;
    let xored: Vec<u8> = repeating_xor(bytes, key.as_bytes());
    Ok(PlainText::from_bytes(&xored))
}

pub fn decrypt_file(input_path: &str, output_path: &str, key: &str) -> Result<(), Error> {
    let cipher = try!(CipherText::from_file(input_path));
    let plain = try!(decrypt(&cipher, key));
    try!(plain.to_file(output_path));
    Ok(())
}

pub fn encrypt_file(input_path: &str, output_path: &str, key: &str) -> Result<(), Error> {
    let plain = try!(PlainText::from_file(input_path));
    let cipher = encrypt(&plain, key);
    try!(cipher.to_file(output_path));
    Ok(())
}

#[derive(Debug)]
pub enum Error {
    Hex(String),
    Base64(String),
    UTF8(String),
    File(String),
}

fn repeating_xor(input: &[u8], key: &[u8]) -> Vec<u8> {
    let mut out: Vec<u8> = Vec::with_capacity(input.len());
    unsafe {
        out.set_len(input.len());
    }
    for (i, in_val) in input.iter().enumerate() {
        out[i] = in_val ^ key[i % key.len()];
    }
    out
}

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

    #[test]
    fn test_encrypt_and_decrypt() {
        check_text("This is the plain text\n");
        check_text("123, 456");
        check_text("!£$%^&*@~:");
        check_text("日本語");
    }

    #[test]
    fn test_encrypt_and_decrypt_files() {
        check_text_file("This is the plain text\n");
        check_text_file("123, 456");
        check_text_file("!£$%^&*@~:");
        check_text_file("日本語");
        check_text_file("This is the plain text\nThis is the plain text\nThis is the plain text\n");
    }

    #[test]
    fn test_wrong_key() {
        let text = "This is the plain text";
        let plain_text = PlainText::from_string(text);
        let key: &str = "toy";
        let decoded_text = decrypt(&encrypt(&plain_text, key), "wrong_key").unwrap();
        assert!(text != decoded_text.to_utf8().unwrap());
    }

    fn check_text(text: &str) {
        let plain_text = PlainText::from_string(text);
        let key: &str = "toy";
        let decoded_text = decrypt(&encrypt(&plain_text, key), key).unwrap();
        assert_eq!(text, decoded_text.to_utf8().unwrap());
    }

    fn check_text_file(text: &str) {
        let plain_text = PlainText::from_string(text);
        let key: &str = "toy";
        let plain_path = "./target/test-plain.txt";
        let cipher_path = "./target/test-cipher.txt";
        let decoded_path = "./target/test-decoded.txt";

        plain_text.to_file(plain_path).unwrap();
        encrypt_file(plain_path, cipher_path, key).unwrap();
        decrypt_file(cipher_path, decoded_path, key).unwrap();
        let decoded_text = PlainText::from_file(decoded_path).unwrap();

        assert_eq!(text, decoded_text.to_utf8().unwrap());
    }
}
<|endoftext|>