<commit_before>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use ast::*;

pub fn optimize(rules: Vec<Rule>) -> Vec<Rule> {
    rules.into_iter().map(|rule| {
        let rotate_right = |expr| {
            // TODO: Use box syntax when it gets stabilized.
            match expr {
                Expr::Seq(lhs, rhs) => {
                    let lhs = *lhs;
                    match lhs {
                        Expr::Seq(ll, lr) => {
                            Expr::Seq(
                                ll,
                                Box::new(Expr::Seq(lr, rhs))
                            )
                        }
                        lhs => Expr::Seq(Box::new(lhs), rhs)
                    }
                }
                Expr::Choice(lhs, rhs) => {
                    let lhs = *lhs;
                    match lhs {
                        Expr::Choice(ll, lr) => {
                            Expr::Choice(
                                ll,
                                Box::new(Expr::Choice(lr, rhs))
                            )
                        }
                        lhs => Expr::Choice(Box::new(lhs), rhs)
                    }
                }
                expr => expr
            }
        };

        let unpack_repetitions = |expr| {
            match expr {
                Expr::RepOnce(expr) => {
                    Expr::Seq(
                        expr.clone(),
                        Box::new(Expr::Rep(expr))
                    )
                }
                Expr::RepExact(expr, num) => {
                    (1..num + 1).map(|_| {
                                    *expr.clone()
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                Expr::RepMin(expr, min) => {
                    (1..min + 2).map(|i| {
                                    if i <= min {
                                        *expr.clone()
                                    } else {
                                        Expr::Rep(expr.clone())
                                    }
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                Expr::RepMax(expr, max) => {
                    (1..max + 1).map(|_| {
                                    Expr::Opt(expr.clone())
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                Expr::RepMinMax(expr, min, max) => {
                    (1..max + 1).map(|i| {
                                    if i <= min {
                                        *expr.clone()
                                    } else {
                                        Expr::Opt(expr.clone())
                                    }
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                expr => expr
            }
        };

        match rule {
            Rule { name, ty, expr } => Rule {
                name,
                ty,
                expr: expr.map_bottom_up(rotate_right)
                          .map_bottom_up(unpack_repetitions)
                          .map_bottom_up(|expr| {
                              if ty == RuleType::Atomic {
                                  // TODO: Use box syntax when it gets stabilized.
                                  match expr {
                                      Expr::Seq(lhs, rhs) => {
                                          match (*lhs, *rhs) {
                                              (Expr::Str(lhs), Expr::Str(rhs)) => {
                                                  Expr::Str(lhs + &rhs)
                                              }
                                              (Expr::Insens(lhs), Expr::Insens(rhs)) => {
                                                  Expr::Insens(lhs + &rhs)
                                              }
                                              (lhs, rhs) => Expr::Seq(Box::new(lhs), Box::new(rhs))
                                          }
                                      }
                                      expr => expr
                                  }
                              } else {
                                  expr
                              }
                          })
                          .map_top_down(|expr| {
                              // TODO: Use box syntax when it gets stabilized.
                              match expr {
                                  Expr::Choice(lhs, rhs) => {
                                      match (*lhs, *rhs) {
                                          (Expr::Seq(l1, r1), Expr::Seq(l2, r2)) => {
                                              if l1 == l2 {
                                                  Expr::Seq(
                                                      l1,
                                                      Box::new(Expr::Choice(
                                                          r1,
                                                          r2
                                                      ))
                                                  )
                                              } else {
                                                  Expr::Choice(
                                                      Box::new(Expr::Seq(l1, r1)),
                                                      Box::new(Expr::Seq(l2, r2))
                                                  )
                                              }
                                          }
                                          (lhs, rhs) => Expr::Choice(Box::new(lhs), Box::new(rhs))
                                      }
                                  }
                                  expr => expr
                              }
                          })
            }
        }
    }).collect()
}

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

    use quote::Ident;

    #[test]
    fn concat_strings() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Seq(
                        Box::new(Expr::Str("a".to_owned())),
                        Box::new(Expr::Str("b".to_owned()))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Str("c".to_owned())),
                        Box::new(Expr::Str("d".to_owned()))
                    ))
                )
            }
        ];
        let concatenated = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Str("abcd".to_owned())
            }
        ];

        assert_eq!(optimize(rules), concatenated);
    }

    #[test]
    fn concat_insensitive_strings() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Seq(
                        Box::new(Expr::Insens("a".to_owned())),
                        Box::new(Expr::Insens("b".to_owned()))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Insens("c".to_owned())),
                        Box::new(Expr::Insens("d".to_owned()))
                    ))
                )
            }
        ];
        let concatenated = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Insens("abcd".to_owned())
            }
        ];

        assert_eq!(optimize(rules), concatenated);
    }

    #[test]
    fn long_common_sequence() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Silent,
                expr: Expr::Choice(
                    Box::new(Expr::Seq(
                        Box::new(Expr::Ident(Ident::new("a"))),
                        Box::new(Expr::Seq(
                            Box::new(Expr::Ident(Ident::new("b"))),
                            Box::new(Expr::Ident(Ident::new("c")))
                        ))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Seq(
                            Box::new(Expr::Ident(Ident::new("a"))),
                            Box::new(Expr::Ident(Ident::new("b")))
                        )),
                        Box::new(Expr::Ident(Ident::new("d")))
                    ))
                )
            }
        ];
        let optimized = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Silent,
                expr: Expr::Seq(
                    Box::new(Expr::Ident(Ident::new("a"))),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Ident(Ident::new("b"))),
                        Box::new(Expr::Choice(
                            Box::new(Expr::Ident(Ident::new("c"))),
                            Box::new(Expr::Ident(Ident::new("d")))
                        ))
                    ))
                )
            }
        ];

        assert_eq!(optimize(rules), optimized);
    }
}
<commit_msg>Add tests for loop unrolling.<commit_after>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use ast::*;

pub fn optimize(rules: Vec<Rule>) -> Vec<Rule> {
    rules.into_iter().map(|rule| {
        let rotate_right = |expr| {
            // TODO: Use box syntax when it gets stabilized.
            match expr {
                Expr::Seq(lhs, rhs) => {
                    let lhs = *lhs;
                    match lhs {
                        Expr::Seq(ll, lr) => {
                            Expr::Seq(
                                ll,
                                Box::new(Expr::Seq(lr, rhs))
                            )
                        }
                        lhs => Expr::Seq(Box::new(lhs), rhs)
                    }
                }
                Expr::Choice(lhs, rhs) => {
                    let lhs = *lhs;
                    match lhs {
                        Expr::Choice(ll, lr) => {
                            Expr::Choice(
                                ll,
                                Box::new(Expr::Choice(lr, rhs))
                            )
                        }
                        lhs => Expr::Choice(Box::new(lhs), rhs)
                    }
                }
                expr => expr
            }
        };

        let unpack_repetitions = |expr| {
            match expr {
                Expr::RepOnce(expr) => {
                    Expr::Seq(
                        expr.clone(),
                        Box::new(Expr::Rep(expr))
                    )
                }
                Expr::RepExact(expr, num) => {
                    (1..num + 1).map(|_| {
                                    *expr.clone()
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                Expr::RepMin(expr, min) => {
                    (1..min + 2).map(|i| {
                                    if i <= min {
                                        *expr.clone()
                                    } else {
                                        Expr::Rep(expr.clone())
                                    }
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                Expr::RepMax(expr, max) => {
                    (1..max + 1).map(|_| {
                                    Expr::Opt(expr.clone())
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                Expr::RepMinMax(expr, min, max) => {
                    (1..max + 1).map(|i| {
                                    if i <= min {
                                        *expr.clone()
                                    } else {
                                        Expr::Opt(expr.clone())
                                    }
                                })
                                .rev()
                                .fold(None, |rep, expr| {
                                    match rep {
                                        None => Some(expr),
                                        Some(rep) => {
                                            Some(
                                                Expr::Seq(
                                                    Box::new(expr),
                                                    Box::new(rep)
                                                )
                                            )
                                        }
                                    }
                                })
                                .unwrap()
                }
                expr => expr
            }
        };

        match rule {
            Rule { name, ty, expr } => Rule {
                name,
                ty,
                expr: expr.map_bottom_up(rotate_right)
                          .map_bottom_up(unpack_repetitions)
                          .map_bottom_up(|expr| {
                              if ty == RuleType::Atomic {
                                  // TODO: Use box syntax when it gets stabilized.
                                  match expr {
                                      Expr::Seq(lhs, rhs) => {
                                          match (*lhs, *rhs) {
                                              (Expr::Str(lhs), Expr::Str(rhs)) => {
                                                  Expr::Str(lhs + &rhs)
                                              }
                                              (Expr::Insens(lhs), Expr::Insens(rhs)) => {
                                                  Expr::Insens(lhs + &rhs)
                                              }
                                              (lhs, rhs) => Expr::Seq(Box::new(lhs), Box::new(rhs))
                                          }
                                      }
                                      expr => expr
                                  }
                              } else {
                                  expr
                              }
                          })
                          .map_top_down(|expr| {
                              // TODO: Use box syntax when it gets stabilized.
                              match expr {
                                  Expr::Choice(lhs, rhs) => {
                                      match (*lhs, *rhs) {
                                          (Expr::Seq(l1, r1), Expr::Seq(l2, r2)) => {
                                              if l1 == l2 {
                                                  Expr::Seq(
                                                      l1,
                                                      Box::new(Expr::Choice(
                                                          r1,
                                                          r2
                                                      ))
                                                  )
                                              } else {
                                                  Expr::Choice(
                                                      Box::new(Expr::Seq(l1, r1)),
                                                      Box::new(Expr::Seq(l2, r2))
                                                  )
                                              }
                                          }
                                          (lhs, rhs) => Expr::Choice(Box::new(lhs), Box::new(rhs))
                                      }
                                  }
                                  expr => expr
                              }
                          })
            }
        }
    }).collect()
}

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

    use quote::Ident;

    #[test]
    fn concat_strings() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Seq(
                        Box::new(Expr::Str("a".to_owned())),
                        Box::new(Expr::Str("b".to_owned()))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Str("c".to_owned())),
                        Box::new(Expr::Str("d".to_owned()))
                    ))
                )
            }
        ];
        let concatenated = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Str("abcd".to_owned())
            }
        ];

        assert_eq!(optimize(rules), concatenated);
    }

    #[test]
    fn unroll_loop_exact() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::RepExact(
                    Box::new(Expr::Ident(Ident::new("a"))),
                    3
                )
            }
        ];
        let unrolled = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Ident(Ident::new("a"))),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Ident(Ident::new("a"))),
                        Box::new(Expr::Ident(Ident::new("a")))
                    ))
                )
            }
        ];

        assert_eq!(optimize(rules), unrolled);
    }

    #[test]
    fn unroll_loop_max() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::RepMax(
                    Box::new(Expr::Str("a".to_owned())),
                    3
                )
            }
        ];
        let unrolled = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Opt(
                        Box::new(Expr::Str("a".to_owned()))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Opt(
                            Box::new(Expr::Str("a".to_owned()))
                        )),
                        Box::new(Expr::Opt(
                            Box::new(Expr::Str("a".to_owned()))
                        ))
                    ))
                )
            }
        ];

        assert_eq!(optimize(rules), unrolled);
    }

    #[test]
    fn unroll_loop_min() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::RepMin(
                    Box::new(Expr::Str("a".to_owned())),
                    2
                )
            }
        ];
        let unrolled = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Str("a".to_owned())),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Str("a".to_owned())),
                        Box::new(Expr::Rep(
                            Box::new(Expr::Str("a".to_owned()))
                        ))
                    ))
                )
            }
        ];

        assert_eq!(optimize(rules), unrolled);
    }

    #[test]
    fn unroll_loop_min_max() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::RepMinMax(
                    Box::new(Expr::Str("a".to_owned())),
                    2,
                    3
                )
            }
        ];
        let unrolled = vec![
            Rule {
                name: Ident::new("rule"),
                ty: RuleType::Atomic,
                expr: Expr::Seq(
                    /* TODO possible room for improvement here:
                     * not sure what rationale behind reversing
                     * the unroll on min/max was, but it seems
                     * to eliminate the possiblity of concatenating
                     * repeated strings at the beginning of
                     * repetitions
                    Box::new(Expr::Str("aa".to_owned())),
                    Box::new(Expr::Opt(
                        Box::new(Expr::Str("a".to_owned()))
                    ))
                    */
                    Box::new(Expr::Str("a".to_owned())),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Str("a".to_owned())),
                        Box::new(Expr::Opt(
                            Box::new(Expr::Str("a".to_owned())),
                        ))
                    ))
                )
            }
        ];

        assert_eq!(optimize(rules), unrolled);
    }

    #[test]
    fn concat_insensitive_strings() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Seq(
                    Box::new(Expr::Seq(
                        Box::new(Expr::Insens("a".to_owned())),
                        Box::new(Expr::Insens("b".to_owned()))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Insens("c".to_owned())),
                        Box::new(Expr::Insens("d".to_owned()))
                    ))
                )
            }
        ];
        let concatenated = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Atomic,
                expr: Expr::Insens("abcd".to_owned())
            }
        ];

        assert_eq!(optimize(rules), concatenated);
    }

    #[test]
    fn long_common_sequence() {
        let rules = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Silent,
                expr: Expr::Choice(
                    Box::new(Expr::Seq(
                        Box::new(Expr::Ident(Ident::new("a"))),
                        Box::new(Expr::Seq(
                            Box::new(Expr::Ident(Ident::new("b"))),
                            Box::new(Expr::Ident(Ident::new("c")))
                        ))
                    )),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Seq(
                            Box::new(Expr::Ident(Ident::new("a"))),
                            Box::new(Expr::Ident(Ident::new("b")))
                        )),
                        Box::new(Expr::Ident(Ident::new("d")))
                    ))
                )
            }
        ];
        let optimized = vec![
            Rule {
                name: Ident::new("rule"),
                ty:   RuleType::Silent,
                expr: Expr::Seq(
                    Box::new(Expr::Ident(Ident::new("a"))),
                    Box::new(Expr::Seq(
                        Box::new(Expr::Ident(Ident::new("b"))),
                        Box::new(Expr::Choice(
                            Box::new(Expr::Ident(Ident::new("c"))),
                            Box::new(Expr::Ident(Ident::new("d")))
                        ))
                    ))
                )
            }
        ];

        assert_eq!(optimize(rules), optimized);
    }
}
<|endoftext|>


<commit_before>/*!
 * Just make sure that the regular expression accepts the sorts of things we want to
 * accept. Don't test what this grammar parses just yet.
 */

rusty_peg! {
    parser Parser<'input> {
        StrHi: &'input str = "Hi";
        StrHi1: &'input str = ("Hi");
        StrHiHo: (&'input str, &'input str) = ("Hi" "Ho");

        IntHi: u32 = "Hi" => 1;
        IntHi1: u32 = ("Hi") => 1;
        IntHiHo: (u32, u32) = ("Hi" "Ho") => (1,1);

        VecHi: Vec<&'input str> = {"Hi"};
        VecHiHo: Vec<(&'input str, &'input str)> = {"Hi" "Ho"};

        OptHi: Option<&'input str> = ["Hi"];
        OptHiHo: Option<(&'input str, &'input str)> = ["Hi" "Ho"];
    }
}

<commit_msg>Add some more more combos.<commit_after>/*!
 * Just make sure that the regular expression accepts the sorts of things we want to
 * accept. Don't test what this grammar parses just yet.
 */

rusty_peg! {
    parser Parser<'input> {
        StrHi: &'input str = "Hi";
        StrHi1: &'input str = ("Hi");
        StrHiHo: (&'input str, &'input str) = ("Hi" "Ho");

        IntHi: u32 = "Hi" => 1;
        IntHi1: u32 = ("Hi") => 1;
        IntHiHo: (u32, u32) = ("Hi" "Ho") => (1,1);

        VecHi: Vec<&'input str> = {"Hi"};
        VecHiHo: Vec<(&'input str, &'input str)> = {"Hi" "Ho"};

        OptHi: Option<&'input str> = ["Hi"];
        OptHiHo: Option<(&'input str, &'input str)> = ["Hi" "Ho"];

        MapHi: &'input str = (<n:"Hi">) => n;
        MapHi1: &'input str = (<n:("Hi")>) => n;
        MapHiHo: (&'input str, &'input str) = (<n:("Hi" "Ho")>) => n;
    }
}

<|endoftext|>


<commit_before>fn split_num(s: &str) -> Vec<i32> {
    let a = s.chars();
    let result = a.map(|x| x.to_string().parse::<i32>().unwrap())
        .collect::<Vec<i32>>();
    result
}

fn main() {
    let mut a = "123";
    let b = split_num(a);

    println!("{:?}", b);

    for c in a.chars() {
        println!("{:?}", c.to_string().parse::<i32>().unwrap());
    }
}
<commit_msg>finish rust version<commit_after>fn split_num(s: &str) -> Vec<i32> {
    let a = s.chars();
    let result = a.map(|x| x.to_string().parse::<i32>().unwrap())
        .collect::<Vec<i32>>();
    result
}

fn is_happy(s: &str) -> bool {
    let num_vec: i32 = split_num(s).iter().sum();
    if num_vec < 1 {
        return false;
    }
    if num_vec == 1 {
        return true;
    }

    return is_happy(&num_vec.to_string());
}

fn main() {
    println!("{}", is_happy("19"));
    println!("{}", is_happy("1"));
}
<|endoftext|>


<commit_before>//! A module to handle all errors

/// An error enum
#[derive(Debug)]
pub enum Error {
    /// Io error
    #[cfg(feature = "std")]
    Io(std::io::Error),
    /// Utf8 Error
    Utf8(::core::str::Utf8Error),
    /// Deprecated feature (in protocol buffer specification)
    Deprecated(&'static str),
    /// Unknown wire type
    UnknownWireType(u8),
    /// Varint decoding error
    Varint,
    /// Error while parsing protocol buffer message
    #[cfg(feature = "std")]
    Message(String),
    /// Unexpected map tag
    Map(u8),
    /// Out of data when reading from or writing to a byte buffer
    UnexpectedEndOfBuffer,
    /// The supplied output buffer is not large enough to serialize the message
    OutputBufferTooSmall,
}

/// A wrapper for `Result<T, Error>`
pub type Result<T> = ::core::result::Result<T, Error>;

#[cfg(feature = "std")]
impl Into<std::io::Error> for Error {
    fn into(self) -> ::std::io::Error {
        match self {
            Error::Io(x) => x,
            Error::Utf8(x) => std::io::Error::new(std::io::ErrorKind::InvalidData, x),
            x => std::io::Error::new(std::io::ErrorKind::Other, x),
        }
    }
}

#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Error {
        Error::Io(e)
    }
}

impl From<::core::str::Utf8Error> for Error {
    fn from(e: ::core::str::Utf8Error) -> Error {
        Error::Utf8(e)
    }
}

#[cfg(feature = "std")]
impl std::error::Error for Error {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Error::Io(e) => Some(e),
            Error::Utf8(e) => Some(e),
            _ => None,
        }
    }
}

impl core::fmt::Display for Error {
    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
        match self {
            #[cfg(feature = "std")]
            Error::Io(e) => write!(f, "{}", e),
            Error::Utf8(e) => write!(f, "{}", e),
            Error::Deprecated(feature) => write!(f, "Feature '{}' has been deprecated", feature),
            Error::UnknownWireType(e) => {
                write!(f, "Unknown wire type '{}', must be less than 6", e)
            }
            Error::Varint => write!(f, "Cannot decode varint"),
            #[cfg(feature = "std")]
            Error::Message(msg) => write!(f, "Error while parsing message: {}", msg),
            Error::Map(tag) => write!(f, "Unexpected map tag: '{}', expecting 1 or 2", tag),
            Error::UnexpectedEndOfBuffer => write!(f, "Unexpected end of buffer"),
            Error::OutputBufferTooSmall => write!(f, "Output buffer too small"),
        }
    }
}
<commit_msg>Add Error::Io for `no_std`<commit_after>//! A module to handle all errors

/// An error enum
#[derive(Debug)]
pub enum Error {
    /// Io error
    #[cfg(feature = "std")]
    Io(std::io::Error),
    /// Io error
    #[cfg(not(feature = "std"))]
    Io,
    /// Utf8 Error
    Utf8(::core::str::Utf8Error),
    /// Deprecated feature (in protocol buffer specification)
    Deprecated(&'static str),
    /// Unknown wire type
    UnknownWireType(u8),
    /// Varint decoding error
    Varint,
    /// Error while parsing protocol buffer message
    #[cfg(feature = "std")]
    Message(String),
    /// Unexpected map tag
    Map(u8),
    /// Out of data when reading from or writing to a byte buffer
    UnexpectedEndOfBuffer,
    /// The supplied output buffer is not large enough to serialize the message
    OutputBufferTooSmall,
}

/// A wrapper for `Result<T, Error>`
pub type Result<T> = ::core::result::Result<T, Error>;

#[cfg(feature = "std")]
impl Into<std::io::Error> for Error {
    fn into(self) -> ::std::io::Error {
        match self {
            Error::Io(x) => x,
            Error::Utf8(x) => std::io::Error::new(std::io::ErrorKind::InvalidData, x),
            x => std::io::Error::new(std::io::ErrorKind::Other, x),
        }
    }
}

#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Error {
        Error::Io(e)
    }
}

impl From<::core::str::Utf8Error> for Error {
    fn from(e: ::core::str::Utf8Error) -> Error {
        Error::Utf8(e)
    }
}

#[cfg(feature = "std")]
impl std::error::Error for Error {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Error::Io(e) => Some(e),
            Error::Utf8(e) => Some(e),
            _ => None,
        }
    }
}

impl core::fmt::Display for Error {
    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
        match self {
            #[cfg(feature = "std")]
            Error::Io(e) => write!(f, "{}", e),
            #[cfg(not(feature = "std"))]
            Error::Io => write!(f, "IO error"),
            Error::Utf8(e) => write!(f, "{}", e),
            Error::Deprecated(feature) => write!(f, "Feature '{}' has been deprecated", feature),
            Error::UnknownWireType(e) => {
                write!(f, "Unknown wire type '{}', must be less than 6", e)
            }
            Error::Varint => write!(f, "Cannot decode varint"),
            #[cfg(feature = "std")]
            Error::Message(msg) => write!(f, "Error while parsing message: {}", msg),
            Error::Map(tag) => write!(f, "Unexpected map tag: '{}', expecting 1 or 2", tag),
            Error::UnexpectedEndOfBuffer => write!(f, "Unexpected end of buffer"),
            Error::OutputBufferTooSmall => write!(f, "Output buffer too small"),
        }
    }
}
<|endoftext|>


<commit_before>extern crate mumble;

use mumble::Connection;

use std::{thread, time};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

#[test]
fn test_connection() {
    // Connect to a local murmur server
    let client = Connection::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), mumble::DEFAULT_PORT, "mumble-rs", "nil").unwrap();
    loop {
        thread::sleep(time::Duration::from_secs(1));
    }
}
<commit_msg>Update test<commit_after>extern crate mumble;

use mumble::{Client, ClientOptions};

use std::{thread, time};

#[test]
fn test_connection() {
    // Connect to a local murmur server
    let client = Client::new(ClientOptions::default()).unwrap();
    loop {
        thread::sleep(time::Duration::from_secs(1));
    }
}
<|endoftext|>


<commit_before>extern crate mtl;

use mtl::{CommandQueue, Device};

#[test]
fn get_device() {
    let device = Device::system_default_device();
    assert!(device.is_ok());
}

#[test]
fn get_device_name() {
    let device = Device::system_default_device().unwrap();
    assert!(!device.get_name().into_owned().is_empty());
}

#[test]
fn set_get_command_queue_label() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = CommandQueue::new(&mut device).unwrap();

    let dummy_command_queue_name = "foo";
    command_queue.set_label(dummy_command_queue_name);

    assert_eq!(command_queue.get_label().into_owned(), dummy_command_queue_name.to_string());
}

#[test]
fn insert_debug_capture_boundary_on_command_queue() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = CommandQueue::new(&mut device).unwrap();
    command_queue.insert_debug_capture_boundary();

    // if nothing panics/fails here, everything is okay
}
<commit_msg>Add some from/into_raw construction tests for device<commit_after>extern crate mtl;
extern crate cocoa;

use mtl::{CommandQueue, Device, DeviceError};
use cocoa::base::nil;
use cocoa::foundation::NSString;

#[test]
fn get_device() {
    let device = Device::system_default_device();
    assert!(device.is_ok());
}

#[test]
fn get_device_name() {
    let device = Device::system_default_device().unwrap();
    assert!(!device.get_name().into_owned().is_empty());
}

#[test]
fn set_get_command_queue_label() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = CommandQueue::new(&mut device).unwrap();

    let dummy_command_queue_name = "foo";
    command_queue.set_label(dummy_command_queue_name);

    assert_eq!(command_queue.get_label().into_owned(), dummy_command_queue_name.to_string());
}

#[test]
fn insert_debug_capture_boundary_on_command_queue() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = CommandQueue::new(&mut device).unwrap();
    command_queue.insert_debug_capture_boundary();

    // if nothing panics/fails here, everything is okay
}

#[test]
fn device_from_to_raw() {
    let device = Device::system_default_device().unwrap();
    let raw = unsafe { device.into_raw() };
    let device = Device::from_raw(raw);
    assert!(device.is_ok());
}

#[test]
fn device_from_wrong_type() {
    let some_string = unsafe { NSString::alloc(nil).init_str("Hello") };
    let device_result = Device::from_raw(some_string);
    match device_result {
        Result::Err(DeviceError::ConstructedFromWrongPointerType) => {
            // pass
        }
        _ => {
            assert!(false)
        }
    }
}

#[test]
fn device_from_nullptr() {
    let device_result = Device::from_raw(nil);
    match device_result {
        Result::Err(DeviceError::ConstructedFromNil) => {
            // pass
        }
        _ => {
            assert!(false)
        }
    }
}
<|endoftext|>


<commit_before>// Farbfeld filter that applies a cool blurring effect over images
// Usage: png2ff < greyscale.png | blur | ff2png > false-colored.png

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::BufWriter;

extern crate byteorder;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};

#[derive (Clone, Copy)]
struct FfPixel {
	pub r: u16,
	pub g: u16,
	pub b: u16,
	pub a: u16,
}

#[derive (Clone, Copy, Debug, PartialEq)]
struct PlaneCoord {
	pub x: i32,
	pub y: i32,
}

impl PlaneCoord {
	pub fn contains_x (&self, x: i32) -> bool {
		x >= 0 && x < self.x
	}

	pub fn contains_y (&self, y: i32) -> bool {
		y >= 0 && y < self.y
	}

	pub fn contains (&self, x: i32, y: i32) -> bool {
		self.contains_x (x) &&
		self.contains_y (y)
	}

	pub fn clamp_x (&self, x: i32) -> i32 {
		return if x < 0 {
			0
		}
		else if x >= self.x {
			self.x - 1
		}
		else {
			x
		}
	}

	pub fn clamp_y (&self, y: i32) -> i32 {
		return if y < 0 {
			0
		}
		else if y >= self.y {
			self.y - 1
		}
		else {
			y
		}
	}

	pub fn clamp (&self, pc: &PlaneCoord) -> PlaneCoord {
		PlaneCoord {
			x: self.clamp_x (pc.x),
			y: self.clamp_y (pc.y),
		}
	}

	pub fn index (&self, pc: &PlaneCoord) -> i32 {
		let pc = self.clamp (pc);

		pc.y * self.x + pc.x
	}

	pub fn clamped_index (&self, pc: &PlaneCoord) -> i32 {
		self.index (&self.clamp (pc))
	}
}

struct HdrPlane {
	pub size: PlaneCoord,
	pub pixels: Vec <f64>,
}

impl HdrPlane {
	pub fn new (size: PlaneCoord) -> HdrPlane {
		HdrPlane {
			size: size,
			pixels: vec! [0.0; (size.x * size.y) as usize],
		}
	}
}

fn read_pixel <T> (reader: &mut T) -> FfPixel where T: ReadBytesExt {
	FfPixel {
		r: reader.read_u16::<BigEndian> ().unwrap (),
		g: reader.read_u16::<BigEndian> ().unwrap (),
		b: reader.read_u16::<BigEndian> ().unwrap (),
		a: reader.read_u16::<BigEndian> ().unwrap (),
	}
}

fn write_pixel <T> (writer: &mut T, pix: &FfPixel) where T: WriteBytesExt {
	writer.write_u16::<BigEndian> (pix.r).unwrap ();
	writer.write_u16::<BigEndian> (pix.g).unwrap ();
	writer.write_u16::<BigEndian> (pix.b).unwrap ();
	writer.write_u16::<BigEndian> (pix.a).unwrap ();
}

fn pascal (n: u32) -> Vec <u64> {
	match n {
		0 => {
			vec! []
		}
		1 => {
			vec! [1]
		},
		2 => {
			vec! [1, 1]
		},
		3 => {
			vec! [1, 2, 1]
		},
		4 => {
			vec! [1, 3, 3, 1]
		}
		5 => {
			vec! [1, 4, 6, 4, 1]
		},
		_ => {
			let step = 5;
			let prev_row = pascal (n - step + 1);
			let step_row = pascal (step);

			let mut output = vec! [];
			for _ in 0..n {
				output.push (0);
			}

			for a in 0..prev_row.len () {
				for b in 0..step_row.len () {
					output [a + b] += prev_row [a] * step_row [b];
				}
			}

			output
		}
	}
}

fn blur_hor (input_plane: &HdrPlane, filter: &Vec <u64>) -> HdrPlane {
	let offset = -(filter.len () as i32 - 1) / 2;
	let filter_sum: u64 = filter.iter ().sum ();
	// Rust plz
	let filter_sum = filter_sum as f64;
	let filter_f: Vec <f64> = filter.iter ().map (|x| *x as f64 / filter_sum).collect ();

	let sz = input_plane.size;

	let mut pixels = vec![];
	for y in 0..sz.y {
		for x in 0..sz.x {
			let dest_index = sz.clamped_index (&PlaneCoord {
				x: x,
				y: y
			});

			pixels.push (0.0f64);

			for src_x in sz.clamp_x (x + 0 + offset)..sz.clamp_x (x + filter_f.len () as i32 - 1 + offset)
			{
				let src_index = sz.clamped_index (&PlaneCoord {
					x: src_x,
					y: y
				});

				pixels [dest_index as usize] += filter_f [(src_x - x - offset) as usize] * input_plane.pixels [src_index as usize];
			}
		}
	}

	HdrPlane {
		size: sz,
		pixels: pixels,
	}
}

fn blur_vert (input_plane: &HdrPlane, filter: &Vec <u64>) -> HdrPlane {
	let offset = -(filter.len () as i32 - 1) / 2;
	let filter_sum: u64 = filter.iter ().sum ();
	// Rust plz
	let filter_sum = filter_sum as f64;
	let filter_f: Vec <f64> = filter.iter ().map (|x| *x as f64 / filter_sum).collect ();

	let sz = input_plane.size;

	let mut pixels = vec![];
	for y in 0..sz.y {
		for x in 0..sz.x {
			let dest_index = sz.clamped_index (&PlaneCoord {
				x: x,
				y: y
			});

			pixels.push (0.0f64);

			for src_y in sz.clamp_y (y + 0 + offset)..sz.clamp_y (y + filter_f.len () as i32 - 1 + offset)
			{
				let src_index = sz.clamped_index (&PlaneCoord {
					x: x,
					y: src_y,
				});

				pixels [dest_index as usize] += filter_f [(src_y - y - offset) as usize] * input_plane.pixels [src_index as usize];
			}
		}
	}

	HdrPlane {
		size: sz,
		pixels: pixels,
	}
}

fn read_farbfeld_grey <T> (reader: &mut T) -> HdrPlane where T: ReadBytesExt {
	let mut magic = [0; 8];
	reader.read (&mut magic [..]).unwrap ();

	// TODO: Assert that magic == 'farbfeld'
	//assert_eq! (magic, &"farbfeld");

	let width = reader.read_u32::<BigEndian>().unwrap() as i32;
	let height = reader.read_u32::<BigEndian>().unwrap() as i32;

	writeln!(&mut io::stderr(), "{} x {}", width, height).expect("failed printing to stderr");

	let mut pixels = vec![0.0; (width * height) as usize];

	for i in 0 .. width * height {
		let gamma = read_pixel (reader).g as f64 / 65536.0;
		pixels [i as usize] = gamma * gamma;
	}

	HdrPlane {
		size: PlaneCoord {
			x: width,
			y: height,
		},
		pixels: pixels,
	}
}

fn write_farbfeld_plane <T> (writer: &mut T, plane: &HdrPlane) where T: WriteBytesExt
{
	write_farbfeld (writer, &plane.size, plane.pixels.iter ().map (|x| {
		let val = (x.sqrt ().min (1.0) * 65535.0) as u16;

		FfPixel {
			r: val,
			g: val,
			b: val,
			a: 65535,
		}
	}));
}

fn double_to_ff (val: f64) -> u16 {
	(val.sqrt ().min (1.0) * 65535.0) as u16
}

fn write_farbfeld <T, I> (writer: &mut T, size: &PlaneCoord, pixels: I ) where T: WriteBytesExt, I: Iterator <Item = FfPixel>
{
	writer.write ("farbfeld".as_bytes ()).expect ("printing farbfeld");

	writer.write_u32::<BigEndian> (size.x as u32).unwrap ();
	writer.write_u32::<BigEndian> (size.y as u32).unwrap ();

	for pixel in pixels.take ((size.x * size.y) as usize) {
		write_pixel (writer, &pixel);
	}
}

fn blur (input_plane: &HdrPlane, filter: &Vec <u64>) -> HdrPlane {
	blur_vert (&blur_hor (input_plane, filter), filter)
}

fn blur_n (input_plane: &HdrPlane, filter: &Vec <u64>, n: u32) -> HdrPlane {
	match n {
		0 => {
			// I know this is dumb
			panic! ("Can't blur an image 0 times")
		},
		1 => {
			blur (input_plane, filter)
		},
		_ => {
			blur (&blur_n (input_plane, filter, n - 1), filter)
		},
	}
}

fn main () {
	// Reader
	let mut reader = BufReader::new (io::stdin ());

	let filter = pascal (41);

	let input_plane = read_farbfeld_grey (&mut reader);
	let blurry_10 = blur_n (&input_plane, &filter, 10);
	let blurry_20 = blur_n (&blurry_10, &filter, 10);

	let sum = [&input_plane, &blurry_20].iter ().fold (
	HdrPlane::new (input_plane.size),
	|accum, b| {
		assert_eq!(accum.size, b.size);
		HdrPlane {
			size: accum.size,
			pixels: accum.pixels.iter ().zip (b.pixels.iter ()).map (|(a, b)| a + b).collect (),
		}
	});

	let sum_iter = (0..(input_plane.size.x * input_plane.size.y) as usize).map (|i| FfPixel {
		r: double_to_ff (input_plane.pixels [i]),
		g: double_to_ff (blurry_10.pixels [i]),
		b: double_to_ff (blurry_20.pixels [i]),
		a: 65535,
	});

	// Write
	{
		let mut writer = BufWriter::new (io::stdout ());

		write_farbfeld (&mut writer, &input_plane.size, sum_iter);
	}

	writeln!(&mut io::stderr(), "filter {:?}", filter).expect("failed printing to stderr");
}
<commit_msg>Playing with the colors<commit_after>// Farbfeld filter that applies a cool blurring effect over images
// Usage: png2ff < greyscale.png | blur | ff2png > false-colored.png

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::BufWriter;

extern crate byteorder;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};

#[derive (Clone, Copy)]
struct FfPixel {
	pub r: u16,
	pub g: u16,
	pub b: u16,
	pub a: u16,
}

#[derive (Clone, Copy, Debug, PartialEq)]
struct PlaneCoord {
	pub x: i32,
	pub y: i32,
}

impl PlaneCoord {
	pub fn contains_x (&self, x: i32) -> bool {
		x >= 0 && x < self.x
	}

	pub fn contains_y (&self, y: i32) -> bool {
		y >= 0 && y < self.y
	}

	pub fn contains (&self, x: i32, y: i32) -> bool {
		self.contains_x (x) &&
		self.contains_y (y)
	}

	pub fn clamp_x (&self, x: i32) -> i32 {
		return if x < 0 {
			0
		}
		else if x >= self.x {
			self.x - 1
		}
		else {
			x
		}
	}

	pub fn clamp_y (&self, y: i32) -> i32 {
		return if y < 0 {
			0
		}
		else if y >= self.y {
			self.y - 1
		}
		else {
			y
		}
	}

	pub fn clamp (&self, pc: &PlaneCoord) -> PlaneCoord {
		PlaneCoord {
			x: self.clamp_x (pc.x),
			y: self.clamp_y (pc.y),
		}
	}

	pub fn index (&self, pc: &PlaneCoord) -> i32 {
		let pc = self.clamp (pc);

		pc.y * self.x + pc.x
	}

	pub fn clamped_index (&self, pc: &PlaneCoord) -> i32 {
		self.index (&self.clamp (pc))
	}
}

struct HdrPlane {
	pub size: PlaneCoord,
	pub pixels: Vec <f64>,
}

impl HdrPlane {
	pub fn new (size: PlaneCoord) -> HdrPlane {
		HdrPlane {
			size: size,
			pixels: vec! [0.0; (size.x * size.y) as usize],
		}
	}
}

fn read_pixel <T> (reader: &mut T) -> FfPixel where T: ReadBytesExt {
	FfPixel {
		r: reader.read_u16::<BigEndian> ().unwrap (),
		g: reader.read_u16::<BigEndian> ().unwrap (),
		b: reader.read_u16::<BigEndian> ().unwrap (),
		a: reader.read_u16::<BigEndian> ().unwrap (),
	}
}

fn write_pixel <T> (writer: &mut T, pix: &FfPixel) where T: WriteBytesExt {
	writer.write_u16::<BigEndian> (pix.r).unwrap ();
	writer.write_u16::<BigEndian> (pix.g).unwrap ();
	writer.write_u16::<BigEndian> (pix.b).unwrap ();
	writer.write_u16::<BigEndian> (pix.a).unwrap ();
}

fn pascal (n: u32) -> Vec <u64> {
	match n {
		0 => {
			vec! []
		}
		1 => {
			vec! [1]
		},
		2 => {
			vec! [1, 1]
		},
		3 => {
			vec! [1, 2, 1]
		},
		4 => {
			vec! [1, 3, 3, 1]
		}
		5 => {
			vec! [1, 4, 6, 4, 1]
		},
		_ => {
			let step = 5;
			let prev_row = pascal (n - step + 1);
			let step_row = pascal (step);

			let mut output = vec! [];
			for _ in 0..n {
				output.push (0);
			}

			for a in 0..prev_row.len () {
				for b in 0..step_row.len () {
					output [a + b] += prev_row [a] * step_row [b];
				}
			}

			output
		}
	}
}

fn blur_hor (input_plane: &HdrPlane, filter: &Vec <u64>) -> HdrPlane {
	let offset = -(filter.len () as i32 - 1) / 2;
	let filter_sum: u64 = filter.iter ().sum ();
	// Rust plz
	let filter_sum = filter_sum as f64;
	let filter_f: Vec <f64> = filter.iter ().map (|x| *x as f64 / filter_sum).collect ();

	let sz = input_plane.size;

	let mut pixels = vec![0.0; (sz.x * sz.y) as usize];
	for y in 0..sz.y {
		for x in 0..sz.x {
			let dest_index = sz.clamped_index (&PlaneCoord {
				x: x,
				y: y
			});

			for src_x in sz.clamp_x (x + 0 + offset)..sz.clamp_x (x + filter_f.len () as i32 - 1 + offset)
			{
				let src_index = sz.clamped_index (&PlaneCoord {
					x: src_x,
					y: y
				});

				pixels [dest_index as usize] += filter_f [(src_x - x - offset) as usize] * input_plane.pixels [src_index as usize];
			}
		}
	}

	HdrPlane {
		size: sz,
		pixels: pixels,
	}
}

fn blur_vert (input_plane: &HdrPlane, filter: &Vec <u64>) -> HdrPlane {
	let offset = -(filter.len () as i32 - 1) / 2;
	let filter_sum: u64 = filter.iter ().sum ();
	// Rust plz
	let filter_sum = filter_sum as f64;
	let filter_f: Vec <f64> = filter.iter ().map (|x| *x as f64 / filter_sum).collect ();

	let sz = input_plane.size;

	let mut pixels = vec![];
	for y in 0..sz.y {
		for x in 0..sz.x {
			let dest_index = sz.clamped_index (&PlaneCoord {
				x: x,
				y: y
			});

			pixels.push (0.0f64);

			for src_y in sz.clamp_y (y + 0 + offset)..sz.clamp_y (y + filter_f.len () as i32 - 1 + offset)
			{
				let src_index = sz.clamped_index (&PlaneCoord {
					x: x,
					y: src_y,
				});

				pixels [dest_index as usize] += filter_f [(src_y - y - offset) as usize] * input_plane.pixels [src_index as usize];
			}
		}
	}

	HdrPlane {
		size: sz,
		pixels: pixels,
	}
}

fn read_farbfeld_grey <T> (reader: &mut T) -> HdrPlane where T: ReadBytesExt {
	let mut magic = [0; 8];
	reader.read (&mut magic [..]).unwrap ();

	// TODO: Assert that magic == 'farbfeld'
	//assert_eq! (magic, &"farbfeld");

	let width = reader.read_u32::<BigEndian>().unwrap() as i32;
	let height = reader.read_u32::<BigEndian>().unwrap() as i32;

	writeln!(&mut io::stderr(), "{} x {}", width, height).expect("failed printing to stderr");

	let mut pixels = vec![0.0; (width * height) as usize];

	for i in 0 .. width * height {
		let gamma = read_pixel (reader).g as f64 / 65536.0;
		pixels [i as usize] = gamma * gamma;
	}

	HdrPlane {
		size: PlaneCoord {
			x: width,
			y: height,
		},
		pixels: pixels,
	}
}

fn write_farbfeld_plane <T> (writer: &mut T, plane: &HdrPlane) where T: WriteBytesExt
{
	write_farbfeld (writer, &plane.size, plane.pixels.iter ().map (|x| {
		let val = (x.sqrt ().min (1.0) * 65535.0) as u16;

		FfPixel {
			r: val,
			g: val,
			b: val,
			a: 65535,
		}
	}));
}

fn double_to_ff (val: f64) -> u16 {
	(val.sqrt ().min (1.0) * 65535.0) as u16
}

fn write_farbfeld <T, I> (writer: &mut T, size: &PlaneCoord, pixels: I ) where T: WriteBytesExt, I: Iterator <Item = FfPixel>
{
	writer.write ("farbfeld".as_bytes ()).expect ("printing farbfeld");

	writer.write_u32::<BigEndian> (size.x as u32).unwrap ();
	writer.write_u32::<BigEndian> (size.y as u32).unwrap ();

	for pixel in pixels.take ((size.x * size.y) as usize) {
		write_pixel (writer, &pixel);
	}
}

fn blur (input_plane: &HdrPlane, filter: &Vec <u64>) -> HdrPlane {
	blur_vert (&blur_hor (input_plane, filter), filter)
}

fn blur_n (input_plane: &HdrPlane, filter: &Vec <u64>, n: u32) -> HdrPlane {
	match n {
		0 => {
			// I know this is dumb
			panic! ("Can't blur an image 0 times")
		},
		1 => {
			blur (input_plane, filter)
		},
		_ => {
			blur (&blur_n (input_plane, filter, n - 1), filter)
		},
	}
}

fn main () {
	// Reader
	let mut reader = BufReader::new (io::stdin ());

	let filter = pascal (41);

	let input_plane = read_farbfeld_grey (&mut reader);
	let blurry_1 = blur_n (&input_plane, &filter, 1);
	let blurry_10 = blur_n (&blurry_1, &filter, 9);
	let blurry_20 = blur_n (&blurry_10, &filter, 10);

	let sum_iter = (0..(input_plane.size.x * input_plane.size.y) as usize).map (|i| {
		let r = input_plane.pixels [i];
		let g = r;
		let b = r;

		let r = r + blurry_1.pixels [i] * 512.0 / 256.0;
		let g = g + blurry_1.pixels [i] * 256.0 / 256.0;

		let r = r + blurry_20.pixels [i] * 59.0 / 256.0;
		let b = b + blurry_20.pixels [i] * 60.0 / 256.0;

		FfPixel {
			r: double_to_ff (r),
			g: double_to_ff (g),
			b: double_to_ff (b),
			a: 65535,
		}
	});

	// Write
	{
		let mut writer = BufWriter::new (io::stdout ());

		write_farbfeld (&mut writer, &input_plane.size, sum_iter);
	}

	writeln!(&mut io::stderr(), "filter {:?}", filter).expect("failed printing to stderr");
}
<|endoftext|>


<commit_before>use super::code_writer::CodeWriter;
use super::rust_types_values::*;
use protobuf::descriptor::*;
use scope::RootScope;
use descriptorx::FieldDescriptorProtoExt;
use ident::RustIdentWithPath;

struct ExtGen<'a> {
    file: &'a FileDescriptorProto,
    root_scope: &'a RootScope<'a>,
    field: &'a FieldDescriptorProto,
}

impl<'a> ExtGen<'a> {
    fn extendee_rust_name(&self) -> RustIdentWithPath {
        type_name_to_rust_relative(self.field.get_extendee(), self.file, true, self.root_scope)
    }

    fn repeated(&self) -> bool {
        match self.field.get_label() {
            FieldDescriptorProto_Label::LABEL_REPEATED => true,
            FieldDescriptorProto_Label::LABEL_OPTIONAL => false,
            FieldDescriptorProto_Label::LABEL_REQUIRED => {
                panic!("required ext field: {}", self.field.get_name())
            }
        }
    }

    fn return_type_gen(&self) -> ProtobufTypeGen {
        if self.field.has_type_name() {
            let rust_name_relative = type_name_to_rust_relative(
                self.field.get_type_name(),
                self.file,
                true,
                self.root_scope,
            );
            match self.field.get_field_type() {
                FieldDescriptorProto_Type::TYPE_MESSAGE => {
                    ProtobufTypeGen::Message(rust_name_relative)
                }
                FieldDescriptorProto_Type::TYPE_ENUM => ProtobufTypeGen::EnumOrUnknown(rust_name_relative),
                t => panic!("unknown type: {:?}", t),
            }
        } else {
            ProtobufTypeGen::Primitive(self.field.get_field_type(), PrimitiveTypeVariant::Default)
        }
    }

    fn write(&self, w: &mut CodeWriter) {
        let suffix = if self.repeated() {
            "Repeated"
        } else {
            "Optional"
        };
        let field_type = format!("::protobuf::ext::ExtField{}", suffix);
        w.pub_const(
            &self.field.rust_name(),
            &format!(
                "{}<{}, {}>",
                field_type,
                self.extendee_rust_name(),
                self.return_type_gen().rust_type()
            ),
            &format!(
                "{} {{ field_number: {}, phantom: ::std::marker::PhantomData }}",
                field_type,
                self.field.get_number()
            ),
        );
    }
}

pub fn write_extensions(file: &FileDescriptorProto, root_scope: &RootScope, w: &mut CodeWriter) {
    if file.extension.is_empty() {
        return;
    }

    w.write_line("");
    w.pub_mod("exts", |w| {
        w.write_line("use protobuf::Message as Message_imported_for_functions;");

        for field in &file.extension {
            if field.get_field_type() == FieldDescriptorProto_Type::TYPE_GROUP {
                continue;
            }

            w.write_line("");
            ExtGen {
                file: file,
                root_scope: root_scope,
                field: field,
            }.write(w);
        }
    });
}
<commit_msg>Improve code searchability<commit_after>use super::code_writer::CodeWriter;
use super::rust_types_values::*;
use protobuf::descriptor::*;
use scope::RootScope;
use descriptorx::FieldDescriptorProtoExt;
use ident::RustIdentWithPath;

struct ExtGen<'a> {
    file: &'a FileDescriptorProto,
    root_scope: &'a RootScope<'a>,
    field: &'a FieldDescriptorProto,
}

impl<'a> ExtGen<'a> {
    fn extendee_rust_name(&self) -> RustIdentWithPath {
        type_name_to_rust_relative(self.field.get_extendee(), self.file, true, self.root_scope)
    }

    fn repeated(&self) -> bool {
        match self.field.get_label() {
            FieldDescriptorProto_Label::LABEL_REPEATED => true,
            FieldDescriptorProto_Label::LABEL_OPTIONAL => false,
            FieldDescriptorProto_Label::LABEL_REQUIRED => {
                panic!("required ext field: {}", self.field.get_name())
            }
        }
    }

    fn return_type_gen(&self) -> ProtobufTypeGen {
        if self.field.has_type_name() {
            let rust_name_relative = type_name_to_rust_relative(
                self.field.get_type_name(),
                self.file,
                true,
                self.root_scope,
            );
            match self.field.get_field_type() {
                FieldDescriptorProto_Type::TYPE_MESSAGE => {
                    ProtobufTypeGen::Message(rust_name_relative)
                }
                FieldDescriptorProto_Type::TYPE_ENUM => ProtobufTypeGen::EnumOrUnknown(rust_name_relative),
                t => panic!("unknown type: {:?}", t),
            }
        } else {
            ProtobufTypeGen::Primitive(self.field.get_field_type(), PrimitiveTypeVariant::Default)
        }
    }

    fn write(&self, w: &mut CodeWriter) {
        let suffix = if self.repeated() {
            "ExtFieldRepeated"
        } else {
            "ExtFieldOptional"
        };
        let field_type = format!("::protobuf::ext::{}", suffix);
        w.pub_const(
            &self.field.rust_name(),
            &format!(
                "{}<{}, {}>",
                field_type,
                self.extendee_rust_name(),
                self.return_type_gen().rust_type()
            ),
            &format!(
                "{} {{ field_number: {}, phantom: ::std::marker::PhantomData }}",
                field_type,
                self.field.get_number()
            ),
        );
    }
}

pub fn write_extensions(file: &FileDescriptorProto, root_scope: &RootScope, w: &mut CodeWriter) {
    if file.extension.is_empty() {
        return;
    }

    w.write_line("");
    w.pub_mod("exts", |w| {
        w.write_line("use protobuf::Message as Message_imported_for_functions;");

        for field in &file.extension {
            if field.get_field_type() == FieldDescriptorProto_Type::TYPE_GROUP {
                continue;
            }

            w.write_line("");
            ExtGen {
                file: file,
                root_scope: root_scope,
                field: field,
            }.write(w);
        }
    });
}
<|endoftext|>


<commit_before>use crate::index::{CloneOptions, LAST_SEEN_REFNAME};
use crate::Index;
use git_repository as git;
use std::path::Path;
use std::sync::atomic::AtomicBool;

/// The error returned by various initialization methods.
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error2 {
    #[error(transparent)]
    PrepareClone(#[from] git::clone::prepare::Error),
    #[error(transparent)]
    Fetch(#[from] git::clone::fetch::Error),
    #[error(transparent)]
    Open(#[from] git::open::Error),
}

/// Initialization
impl Index {
    /// Return a new `Index` instance from the given `path`, which should contain a bare clone of the `crates.io` index.
    /// If the directory does not contain the repository or does not exist, it will be cloned from
    /// the official location automatically (with complete history).
    ///
    /// An error will occour if the repository exists and the remote URL does not match the given repository URL.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use std::sync::atomic::AtomicBool;
    /// use crates_index_diff::{Index, index, git};
    ///
    /// # let path = tempdir::TempDir::new("index").unwrap();
    /// // Note that credentials are automatically picked up from the standard git configuration.
    /// let mut options = index::CloneOptions {
    ///   url: "https://github.com/rust-lang/staging.crates.io-index".into(),
    /// };
    ///
    ///
    /// let index = Index::from_path_or_cloned_with_options(path, git::progress::Discard, &AtomicBool::default(), options)?;
    /// # Ok::<(), crates_index_diff::index::init::Error2>(())
    /// ```
    pub fn from_path_or_cloned_with_options(
        path: impl AsRef<Path>,
        progress: impl git::Progress,
        should_interrupt: &AtomicBool,
        CloneOptions { url }: CloneOptions,
    ) -> Result<Index, Error2> {
        let path = path.as_ref();
        let mut repo = match git::open(path) {
            Ok(repo) => repo,
            Err(git::open::Error::NotARepository(_)) => {
                let (repo, _out) =
                    git::prepare_clone_bare(url, path)?.fetch_only(progress, should_interrupt)?;
                repo
            }
            Err(err) => return Err(err.into()),
        }
        .apply_environment();

        repo.object_cache_size_if_unset(4 * 1024 * 1024);
        let remote_name = repo
            .remote_names()
            .into_iter()
            .next()
            .map(ToOwned::to_owned);
        Ok(Index {
            repo,
            remote_name,
            branch_name: "master",
            seen_ref_name: LAST_SEEN_REFNAME,
        })
    }

    /// Return a new `Index` instance from the given `path`, which should contain a bare or non-bare
    /// clone of the `crates.io` index.
    /// If the directory does not contain the repository or does not exist, it will be cloned from
    /// the official location automatically (with complete history).
    pub fn from_path_or_cloned(path: impl AsRef<Path>) -> Result<Index, Error2> {
        Index::from_path_or_cloned_with_options(
            path,
            git::progress::Discard,
            &AtomicBool::default(),
            CloneOptions::default(),
        )
    }
}
<commit_msg>fix: rename `init::Error2` to `init::Error`.<commit_after>use crate::index::{CloneOptions, LAST_SEEN_REFNAME};
use crate::Index;
use git_repository as git;
use std::path::Path;
use std::sync::atomic::AtomicBool;

/// The error returned by various initialization methods.
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
    #[error(transparent)]
    PrepareClone(#[from] git::clone::prepare::Error),
    #[error(transparent)]
    Fetch(#[from] git::clone::fetch::Error),
    #[error(transparent)]
    Open(#[from] git::open::Error),
}

/// Initialization
impl Index {
    /// Return a new `Index` instance from the given `path`, which should contain a bare clone of the `crates.io` index.
    /// If the directory does not contain the repository or does not exist, it will be cloned from
    /// the official location automatically (with complete history).
    ///
    /// An error will occour if the repository exists and the remote URL does not match the given repository URL.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use std::sync::atomic::AtomicBool;
    /// use crates_index_diff::{Index, index, git};
    ///
    /// # let path = tempdir::TempDir::new("index").unwrap();
    /// // Note that credentials are automatically picked up from the standard git configuration.
    /// let mut options = index::CloneOptions {
    ///   url: "https://github.com/rust-lang/staging.crates.io-index".into(),
    /// };
    ///
    ///
    /// let index = Index::from_path_or_cloned_with_options(path, git::progress::Discard, &AtomicBool::default(), options)?;
    /// # Ok::<(), crates_index_diff::index::init::Error>(())
    /// ```
    pub fn from_path_or_cloned_with_options(
        path: impl AsRef<Path>,
        progress: impl git::Progress,
        should_interrupt: &AtomicBool,
        CloneOptions { url }: CloneOptions,
    ) -> Result<Index, Error> {
        let path = path.as_ref();
        let mut repo = match git::open(path) {
            Ok(repo) => repo,
            Err(git::open::Error::NotARepository(_)) => {
                let (repo, _out) =
                    git::prepare_clone_bare(url, path)?.fetch_only(progress, should_interrupt)?;
                repo
            }
            Err(err) => return Err(err.into()),
        }
        .apply_environment();

        repo.object_cache_size_if_unset(4 * 1024 * 1024);
        let remote_name = repo
            .remote_names()
            .into_iter()
            .next()
            .map(ToOwned::to_owned);
        Ok(Index {
            repo,
            remote_name,
            branch_name: "master",
            seen_ref_name: LAST_SEEN_REFNAME,
        })
    }

    /// Return a new `Index` instance from the given `path`, which should contain a bare or non-bare
    /// clone of the `crates.io` index.
    /// If the directory does not contain the repository or does not exist, it will be cloned from
    /// the official location automatically (with complete history).
    pub fn from_path_or_cloned(path: impl AsRef<Path>) -> Result<Index, Error> {
        Index::from_path_or_cloned_with_options(
            path,
            git::progress::Discard,
            &AtomicBool::default(),
            CloneOptions::default(),
        )
    }
}
<|endoftext|>


<commit_before>//! Implements search parallelization (not implemented yet).

use std::cell::UnsafeCell;
use std::sync::{Arc, Mutex, Condvar};
use std::sync::mpsc::{Sender, Receiver, RecvError};
use basetypes::*;
use moves::*;
use tt::*;
use search::{SearchReport, SearchParams};
use search::alpha_beta::Search;

/// Represents a command to a search thread.
pub enum Command {
    /// Starts a new search.
    Start(SearchParams),

    /// Terminates the currently running search.
    Terminate,

    /// Terminates the currently running search and exits the search
    /// thread.
    Exit,
}

/// Listens for commands, executes simple searches, sends reports
/// back.
///
/// This function will block and wait to receive commands on the
/// `commands` channel to start, stop, or exit searches. It is
/// intended to be called in a separate thread. While the search is
/// executed, regular `Report` messages will be send back to the
/// master thread via the `reports` channel. When the search is done,
/// the final `Report` message will have its `done` field set to
/// `true`.
///
/// # Example:
///
/// ```rust
/// // Spawn a slave thread:
/// let tt = Arc::new(tt);
/// let (commands_tx, commands_rx) = channel();
/// let (reports_tx, reports_rx) = channel();
/// thread::spawn(move || {
///     serve_simple(tt, commands_rx, reports_tx);
/// });
///
/// // Send a command to start a new search:
/// commands_tx.send(Command::Search {
///     search_id: 0,
///     position: Position::form_fen("8/8/8/8/8/8/7P/5k1K b - - 0 99"),
///     depth: 5,
///     lower_bound: VALUE_MIN,
///     upper_bound: VALUE_MAX,
/// }).unwrap();
/// ```
///
/// This function executes sequential (non-parallel) search to a fixed
/// depth.
pub fn serve_simple(tt: Arc<Tt>,
                    commands: Receiver<Command>,
                    reports: Sender<SearchReport>,
                    has_reports_condition: Arc<(Mutex<bool>, Condvar)>) {
    thread_local!(
        static MOVE_STACK: UnsafeCell<MoveStack> = UnsafeCell::new(MoveStack::new())
    );
    MOVE_STACK.with(|s| {
        let &(ref has_reports, ref condition) = &*has_reports_condition;
        let mut move_stack = unsafe { &mut *s.get() };
        let mut pending_command = None;
        loop {
            // If there is a pending command, we take it, otherwise we
            // block and wait to receive a command.
            let command = match pending_command.take() {
                Some(cmd) => cmd,
                None => commands.recv().or::<RecvError>(Ok(Command::Exit)).unwrap(),
            };

            match command {
                Command::Start(SearchParams { search_id,
                                              position,
                                              depth,
                                              lower_bound,
                                              upper_bound,
                                              .. }) => {
                    debug_assert!(lower_bound < upper_bound);
                    let mut report = |searched_nodes| {
                        reports.send(SearchReport {
                                   search_id: search_id,
                                   searched_nodes: searched_nodes,
                                   depth: 0,
                                   value: VALUE_UNKNOWN,
                                   sorted_moves: vec![],
                                   done: false,
                               })
                               .ok();
                        let mut has_reports = has_reports.lock().unwrap();
                        *has_reports = true;
                        condition.notify_one();

                        if let Ok(cmd) = commands.try_recv() {
                            pending_command = Some(cmd);
                            true
                        } else {
                            false
                        }
                    };
                    let mut search = Search::new(position, &tt, move_stack, &mut report);
                    let (depth, value) = if let Ok(v) = search.run(lower_bound,
                                                                   upper_bound,
                                                                   depth,
                                                                   Move::invalid()) {
                        (depth, v)
                    } else {
                        (0, VALUE_UNKNOWN)
                    };

                    reports.send(SearchReport {
                               search_id: search_id,
                               searched_nodes: search.node_count(),
                               depth: depth,
                               value: value,
                               sorted_moves: vec![],
                               done: true,
                           })
                           .ok();
                    let mut has_reports = has_reports.lock().unwrap();
                    *has_reports = true;
                    condition.notify_one();

                    search.reset();
                }

                Command::Terminate => continue,

                Command::Exit => break,
            }
        }
    })
}
<commit_msg>fix docs<commit_after>//! Implements search parallelization (not implemented yet).

use std::cell::UnsafeCell;
use std::sync::{Arc, Mutex, Condvar};
use std::sync::mpsc::{Sender, Receiver, RecvError};
use basetypes::*;
use moves::*;
use tt::*;
use search::{SearchReport, SearchParams};
use search::alpha_beta::Search;

/// Represents a command to a search thread.
pub enum Command {
    /// Starts a new search.
    Start(SearchParams),

    /// Terminates the currently running search.
    Terminate,

    /// Terminates the currently running search and exits the search
    /// thread.
    Exit,
}

/// Listens for commands, executes simple searches, sends reports
/// back.
///
/// This function will block and wait to receive commands on the
/// `commands` channel to start, stop, or exit searches. It is
/// intended to be called in a separate thread. While the search is
/// executed, regular `SearchReport` messages will be send back to the
/// master thread via the `reports` channel. When the search is done,
/// the final `SearchReport` message will have its `done` field set to
/// `true`.
///
/// # Example:
///
/// ```rust
/// // Spawn a slave thread:
/// let tt = Arc::new(tt);
/// let (commands_tx, commands_rx) = channel();
/// let (reports_tx, reports_rx) = channel();
/// thread::spawn(move || {
///     serve_simple(tt, commands_rx, reports_tx);
/// });
///
/// // Send a command to start a new search:
/// commands_tx.send(Command::Search {
///     search_id: 0,
///     position: Position::form_fen("8/8/8/8/8/8/7P/5k1K b - - 0 99"),
///     depth: 5,
///     lower_bound: VALUE_MIN,
///     upper_bound: VALUE_MAX,
/// }).unwrap();
/// ```
///
/// This function executes sequential (non-parallel) search to a fixed
/// depth.
pub fn serve_simple(tt: Arc<Tt>,
                    commands: Receiver<Command>,
                    reports: Sender<SearchReport>,
                    has_reports_condition: Arc<(Mutex<bool>, Condvar)>) {
    thread_local!(
        static MOVE_STACK: UnsafeCell<MoveStack> = UnsafeCell::new(MoveStack::new())
    );
    MOVE_STACK.with(|s| {
        let &(ref has_reports, ref condition) = &*has_reports_condition;
        let mut move_stack = unsafe { &mut *s.get() };
        let mut pending_command = None;
        loop {
            // If there is a pending command, we take it, otherwise we
            // block and wait to receive a command.
            let command = match pending_command.take() {
                Some(cmd) => cmd,
                None => commands.recv().or::<RecvError>(Ok(Command::Exit)).unwrap(),
            };

            match command {
                Command::Start(SearchParams { search_id,
                                              position,
                                              depth,
                                              lower_bound,
                                              upper_bound,
                                              .. }) => {
                    debug_assert!(lower_bound < upper_bound);
                    let mut report = |searched_nodes| {
                        reports.send(SearchReport {
                                   search_id: search_id,
                                   searched_nodes: searched_nodes,
                                   depth: 0,
                                   value: VALUE_UNKNOWN,
                                   sorted_moves: vec![],
                                   done: false,
                               })
                               .ok();
                        let mut has_reports = has_reports.lock().unwrap();
                        *has_reports = true;
                        condition.notify_one();

                        if let Ok(cmd) = commands.try_recv() {
                            pending_command = Some(cmd);
                            true
                        } else {
                            false
                        }
                    };
                    let mut search = Search::new(position, &tt, move_stack, &mut report);
                    let (depth, value) = if let Ok(v) = search.run(lower_bound,
                                                                   upper_bound,
                                                                   depth,
                                                                   Move::invalid()) {
                        (depth, v)
                    } else {
                        (0, VALUE_UNKNOWN)
                    };

                    reports.send(SearchReport {
                               search_id: search_id,
                               searched_nodes: search.node_count(),
                               depth: depth,
                               value: value,
                               sorted_moves: vec![],
                               done: true,
                           })
                           .ok();
                    let mut has_reports = has_reports.lock().unwrap();
                    *has_reports = true;
                    condition.notify_one();

                    search.reset();
                }

                Command::Terminate => continue,

                Command::Exit => break,
            }
        }
    })
}
<|endoftext|>