<commit_before>use crate::expression::subselect::Subselect;
use crate::expression::{AsExpression, Expression, ValidGrouping};
use crate::pg::Pg;
use crate::query_builder::*;
use crate::result::QueryResult;
use crate::sql_types::Array;

/// Creates a PostgreSQL `ANY` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically from `diesel::pg::expression::dsl::any`, or glob import
/// `diesel::dsl::any`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let sean = (1, "Sean".to_string());
/// let jim = (3, "Jim".to_string());
/// let data = users.filter(name.eq(any(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![sean, jim]), data.load(&connection));
/// # }
/// ```
pub fn any<ST, T>(vals: T) -> Any<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    Any::new(vals.as_expression())
}

/// Creates a PostgreSQL `ALL` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically as `diesel::pg::expression::dsl::all`, or glob import
/// `diesel::dsl::*`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let tess = (2, "Tess".to_string());
/// let data = users.filter(name.ne(all(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![tess]), data.load(&connection));
/// # }
/// ```
pub fn all<ST, T>(vals: T) -> All<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    All::new(vals.as_expression())
}

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct Any<Expr> {
    expr: Expr,
}

impl<Expr> Any<Expr> {
    fn new(expr: Expr) -> Self {
        Any { expr: expr }
    }
}

impl<Expr, ST> Expression for Any<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for Any<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ANY(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(Any<Expr>);

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct All<Expr> {
    expr: Expr,
}

impl<Expr> All<Expr> {
    fn new(expr: Expr) -> Self {
        All { expr: expr }
    }
}

impl<Expr, ST> Expression for All<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for All<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ALL(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(All<Expr>);

pub trait AsArrayExpression<ST> {
    type Expression: Expression<SqlType = Array<ST>>;

    fn as_expression(self) -> Self::Expression;
}

impl<ST, T> AsArrayExpression<ST> for T
where
    T: AsExpression<Array<ST>>,
{
    type Expression = <T as AsExpression<Array<ST>>>::Expression;

    fn as_expression(self) -> Self::Expression {
        AsExpression::as_expression(self)
    }
}

impl<ST, S, F, W, O, L, Of, G, FU> AsArrayExpression<ST>
    for SelectStatement<S, F, W, O, L, Of, G, FU>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}

impl<'a, ST, QS, DB> AsArrayExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}
<commit_msg>apply glob import documentation suggestions<commit_after>use crate::expression::subselect::Subselect;
use crate::expression::{AsExpression, Expression, ValidGrouping};
use crate::pg::Pg;
use crate::query_builder::*;
use crate::result::QueryResult;
use crate::sql_types::Array;

/// Creates a PostgreSQL `ANY` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically from `diesel::pg::expression::dsl::any`, or glob import
/// `diesel::dsl::any`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let sean = (1, "Sean".to_string());
/// let jim = (3, "Jim".to_string());
/// let data = users.filter(name.eq(any(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![sean, jim]), data.load(&connection));
/// # }
/// ```
pub fn any<ST, T>(vals: T) -> Any<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    Any::new(vals.as_expression())
}

/// Creates a PostgreSQL `ALL` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically as `diesel::pg::expression::dsl::all`, or glob import
/// `diesel::dsl::all`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let tess = (2, "Tess".to_string());
/// let data = users.filter(name.ne(all(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![tess]), data.load(&connection));
/// # }
/// ```
pub fn all<ST, T>(vals: T) -> All<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    All::new(vals.as_expression())
}

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct Any<Expr> {
    expr: Expr,
}

impl<Expr> Any<Expr> {
    fn new(expr: Expr) -> Self {
        Any { expr: expr }
    }
}

impl<Expr, ST> Expression for Any<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for Any<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ANY(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(Any<Expr>);

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct All<Expr> {
    expr: Expr,
}

impl<Expr> All<Expr> {
    fn new(expr: Expr) -> Self {
        All { expr: expr }
    }
}

impl<Expr, ST> Expression for All<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for All<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ALL(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(All<Expr>);

pub trait AsArrayExpression<ST> {
    type Expression: Expression<SqlType = Array<ST>>;

    fn as_expression(self) -> Self::Expression;
}

impl<ST, T> AsArrayExpression<ST> for T
where
    T: AsExpression<Array<ST>>,
{
    type Expression = <T as AsExpression<Array<ST>>>::Expression;

    fn as_expression(self) -> Self::Expression {
        AsExpression::as_expression(self)
    }
}

impl<ST, S, F, W, O, L, Of, G, FU> AsArrayExpression<ST>
    for SelectStatement<S, F, W, O, L, Of, G, FU>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}

impl<'a, ST, QS, DB> AsArrayExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}
<|endoftext|>


<commit_before><commit_msg>refactor: rustup<commit_after><|endoftext|>


<commit_before><commit_msg>Fix hex escape to not include letters after "F"<commit_after><|endoftext|>


<commit_before><commit_msg>pr: fix file not found in pr and mpr<commit_after><|endoftext|>


<commit_before><commit_msg>Weird comment fix<commit_after><|endoftext|>


<commit_before>// * This file is part of the uutils coreutils package.
// *
// * (c) 2015 Wiktor Kuropatwa <wiktor.kuropatwa@gmail.com>
// * (c) 2020 nicoo            <nicoo@debian.org>
// *
// * For the full copyright and license information, please view the LICENSE file
// * that was distributed with this source code.

use num_traits::{
    identities::{One, Zero},
    int::PrimInt,
    ops::wrapping::{WrappingMul, WrappingNeg, WrappingSub},
};
use std::fmt::{Debug, Display};
use std::mem::swap;

// This is incorrectly reported as dead code,
//  presumably when included in build.rs.
#[allow(dead_code)]
pub(crate) fn gcd(mut a: u64, mut b: u64) -> u64 {
    while b > 0 {
        a %= b;
        swap(&mut a, &mut b);
    }
    a
}

pub(crate) trait Arithmetic: Copy + Sized {
    // The type of integers mod m, in some opaque representation
    type ModInt: Copy + Sized + Eq;

    fn new(m: u64) -> Self;
    fn modulus(&self) -> u64;
    fn from_u64(&self, n: u64) -> Self::ModInt;
    fn to_u64(&self, n: Self::ModInt) -> u64;
    fn add(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt;
    fn mul(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt;

    fn pow(&self, mut a: Self::ModInt, mut b: u64) -> Self::ModInt {
        let (_a, _b) = (a, b);
        let mut result = self.one();
        while b > 0 {
            if b & 1 != 0 {
                result = self.mul(result, a);
            }
            a = self.mul(a, a);
            b >>= 1;
        }

        // Check that r (reduced back to the usual representation) equals
        //  a^b % n, unless the latter computation overflows
        // Temporarily commented-out, as there u64::checked_pow is not available
        //  on the minimum supported Rust version, nor is an appropriate method
        //  for compiling the check conditionally.
        //debug_assert!(self
        //    .to_u64(_a)
        //    .checked_pow(_b as u32)
        //    .map(|r| r % self.modulus() == self.to_u64(result))
        //    .unwrap_or(true));

        result
    }

    fn one(&self) -> Self::ModInt {
        self.from_u64(1)
    }
    fn minus_one(&self) -> Self::ModInt {
        self.from_u64(self.modulus() - 1)
    }
    fn zero(&self) -> Self::ModInt {
        self.from_u64(0)
    }
}

#[derive(Clone, Copy, Debug)]
pub(crate) struct Montgomery<T: DoubleInt> {
    a: T,
    n: T,
}

impl<T: DoubleInt> Montgomery<T> {
    /// computes x/R mod n efficiently
    fn reduce(&self, x: T::DoubleWidth) -> T {
        let t_bits = T::zero().count_zeros() as usize;

        debug_assert!(x < (self.n.as_double_width()) << t_bits);
        // TODO: optimiiiiiiise
        let Montgomery { a, n } = self;
        let m = T::from_double_width(x).wrapping_mul(a);
        let nm = (n.as_double_width()) * (m.as_double_width());
        let (xnm, overflow) = x.overflowing_add_(nm); // x + n*m
        debug_assert_eq!(
            xnm % (T::DoubleWidth::one() << T::zero().count_zeros() as usize),
            T::DoubleWidth::zero()
        );

        // (x + n*m) / R
        // in case of overflow, this is (2¹²⁸ + xnm)/2⁶⁴ - n = xnm/2⁶⁴ + (2⁶⁴ - n)
        let y = T::from_double_width(xnm >> t_bits)
            + if !overflow {
                T::zero()
            } else {
                n.wrapping_neg()
            };

        if y >= *n {
            y - *n
        } else {
            y
        }
    }
}

impl<T: DoubleInt> Arithmetic for Montgomery<T> {
    // Montgomery transform, R=2⁶⁴
    // Provides fast arithmetic mod n (n odd, u64)
    type ModInt = T;

    fn new(n: u64) -> Self {
        debug_assert!(T::zero().count_zeros() >= 64 || n < (1 << T::zero().count_zeros() as usize));
        let n = T::from_u64(n);
        let a = modular_inverse(n).wrapping_neg();
        debug_assert_eq!(n.wrapping_mul(&a), T::one().wrapping_neg());
        Montgomery { a, n }
    }

    fn modulus(&self) -> u64 {
        self.n.as_u64()
    }

    fn from_u64(&self, x: u64) -> Self::ModInt {
        // TODO: optimise!
        debug_assert!(x < self.n.as_u64());
        let r = T::from_double_width(
            ((T::DoubleWidth::from_u64(x)) << T::zero().count_zeros() as usize)
                % self.n.as_double_width(),
        );
        debug_assert_eq!(x, self.to_u64(r));
        r
    }

    fn to_u64(&self, n: Self::ModInt) -> u64 {
        self.reduce(n.as_double_width()).as_u64()
    }

    fn add(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt {
        let (r, overflow) = a.overflowing_add_(b);

        // In case of overflow, a+b = 2⁶⁴ + r = (2⁶⁴ - n) + r (working mod n)
        let r = if !overflow {
            r
        } else {
            r + self.n.wrapping_neg()
        };

        // Normalise to [0; n[
        let r = if r < self.n { r } else { r - self.n };

        // Check that r (reduced back to the usual representation) equals
        // a+b % n
        #[cfg(debug_assertions)]
        {
            let a_r = self.to_u64(a) as u128;
            let b_r = self.to_u64(b) as u128;
            let r_r = self.to_u64(r);
            let r_2 = ((a_r + b_r) % self.n.as_u128()) as u64;
            debug_assert_eq!(
                r_r, r_2,
                "[{}] = {} ≠ {} = {} + {} = [{}] + [{}] mod {}; a = {}",
                r, r_r, r_2, a_r, b_r, a, b, self.n, self.a
            );
        }
        r
    }

    fn mul(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt {
        let r = self.reduce(a.as_double_width() * b.as_double_width());

        // Check that r (reduced back to the usual representation) equals
        // a*b % n
        #[cfg(debug_assertions)]
        {
            let a_r = self.to_u64(a) as u128;
            let b_r = self.to_u64(b) as u128;
            let r_r = self.to_u64(r);
            let r_2: u64 = ((a_r * b_r) % self.n.as_u128()) as u64;
            debug_assert_eq!(
                r_r, r_2,
                "[{}] = {} ≠ {} = {} * {} = [{}] * [{}] mod {}; a = {}",
                r, r_r, r_2, a_r, b_r, a, b, self.n, self.a
            );
        }
        r
    }
}

// NOTE: Trait can be removed once num-traits adds a similar one;
//       see https://github.com/rust-num/num-traits/issues/168
pub(crate) trait OverflowingAdd: Sized {
    fn overflowing_add_(self, n: Self) -> (Self, bool);
}
macro_rules! overflowing {
    ($x:ty) => {
        impl OverflowingAdd for $x {
            fn overflowing_add_(self, n: Self) -> (Self, bool) {
                self.overflowing_add(n)
            }
        }
    };
}
overflowing!(u32);
overflowing!(u64);
overflowing!(u128);

pub(crate) trait Int:
    Display + Debug + PrimInt + OverflowingAdd + WrappingNeg + WrappingSub + WrappingMul
{
    fn as_u64(&self) -> u64;
    fn from_u64(n: u64) -> Self;
    #[cfg(debug_assertions)]
    fn as_u128(&self) -> u128;
    #[cfg(debug_assertions)]
    fn from_u128(n: u64) -> Self;
}

pub(crate) trait DoubleInt: Int {
    type DoubleWidth: Int;

    fn as_double_width(self) -> Self::DoubleWidth;
    fn from_double_width(n: Self::DoubleWidth) -> Self;
}

macro_rules! int {
    ( $x:ty ) => {
        impl Int for $x {
            fn as_u64(&self) -> u64 {
                *self as u64
            }
            fn from_u64(n: u64) -> Self {
                n as _
            }
            #[cfg(debug_assertions)]
            fn as_u128(&self) -> u128 {
                *self as u128
            }
            #[cfg(debug_assertions)]
            fn from_u128(n: u64) -> Self {
                n as _
            }
        }
    };
}
macro_rules! double_int {
    ( $x:ty, $y:ty ) => {
        int!($x);
        impl DoubleInt for $x {
            type DoubleWidth = $y;

            fn as_double_width(self) -> $y {
                self as _
            }
            fn from_double_width(n: $y) -> $x {
                n as _
            }
        }
    };
}

double_int!(u32, u64);
double_int!(u64, u128);
int!(u128);

// extended Euclid algorithm
// precondition: a is odd
pub(crate) fn modular_inverse<T: Int>(a: T) -> T {
    let zero = T::zero();
    let one = T::one();
    debug_assert!(a % (one + one) == one, "{:?} is not odd", a);

    let mut t = zero;
    let mut newt = one;
    let mut r = zero;
    let mut newr = a;

    while newr != zero {
        let quot = if r == zero {
            // special case when we're just starting out
            // This works because we know that
            // a does not divide 2^64, so floor(2^64 / a) == floor((2^64-1) / a);
            T::max_value()
        } else {
            r
        } / newr;

        let newtp = t.wrapping_sub(&quot.wrapping_mul(&newt));
        t = newt;
        newt = newtp;

        let newrp = r.wrapping_sub(&quot.wrapping_mul(&newr));
        r = newr;
        newr = newrp;
    }

    debug_assert_eq!(r, one);
    t
}

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

    macro_rules! parametrized_check {
        ( $f:ident ) => {
            paste::item! {
                #[test]
                fn [< $f _ u32 >]() {
                    $f::<u32>()
                }
                #[test]
                fn [< $f _ u64 >]() {
                    $f::<u64>()
                }
            }
        };
    }

    fn test_inverter<T: Int>() {
        // All odd integers from 1 to 20 000
        let one = T::from(1).unwrap();
        let two = T::from(2).unwrap();
        let mut test_values = (0..10_000)
            .map(|i| T::from(i).unwrap())
            .map(|i| two * i + one);

        assert!(test_values.all(|x| x.wrapping_mul(&modular_inverse(x)) == one));
    }
    parametrized_check!(test_inverter);

    fn test_add<A: DoubleInt>() {
        for n in 0..100 {
            let n = 2 * n + 1;
            let m = Montgomery::<A>::new(n);
            for x in 0..n {
                let m_x = m.from_u64(x);
                for y in 0..=x {
                    let m_y = m.from_u64(y);
                    println!("{n:?}, {x:?}, {y:?}", n = n, x = x, y = y);
                    assert_eq!((x + y) % n, m.to_u64(m.add(m_x, m_y)));
                }
            }
        }
    }
    parametrized_check!(test_add);

    fn test_mult<A: DoubleInt>() {
        for n in 0..100 {
            let n = 2 * n + 1;
            let m = Montgomery::<A>::new(n);
            for x in 0..n {
                let m_x = m.from_u64(x);
                for y in 0..=x {
                    let m_y = m.from_u64(y);
                    assert_eq!((x * y) % n, m.to_u64(m.mul(m_x, m_y)));
                }
            }
        }
    }
    parametrized_check!(test_mult);

    fn test_roundtrip<A: DoubleInt>() {
        for n in 0..100 {
            let n = 2 * n + 1;
            let m = Montgomery::<A>::new(n);
            for x in 0..n {
                let x_ = m.from_u64(x);
                assert_eq!(x, m.to_u64(x_));
            }
        }
    }
    parametrized_check!(test_roundtrip);
}
<commit_msg>factor::numeric::Int: Remove `from_u128` method<commit_after>// * This file is part of the uutils coreutils package.
// *
// * (c) 2015 Wiktor Kuropatwa <wiktor.kuropatwa@gmail.com>
// * (c) 2020 nicoo            <nicoo@debian.org>
// *
// * For the full copyright and license information, please view the LICENSE file
// * that was distributed with this source code.

use num_traits::{
    identities::{One, Zero},
    int::PrimInt,
    ops::wrapping::{WrappingMul, WrappingNeg, WrappingSub},
};
use std::fmt::{Debug, Display};
use std::mem::swap;

// This is incorrectly reported as dead code,
//  presumably when included in build.rs.
#[allow(dead_code)]
pub(crate) fn gcd(mut a: u64, mut b: u64) -> u64 {
    while b > 0 {
        a %= b;
        swap(&mut a, &mut b);
    }
    a
}

pub(crate) trait Arithmetic: Copy + Sized {
    // The type of integers mod m, in some opaque representation
    type ModInt: Copy + Sized + Eq;

    fn new(m: u64) -> Self;
    fn modulus(&self) -> u64;
    fn from_u64(&self, n: u64) -> Self::ModInt;
    fn to_u64(&self, n: Self::ModInt) -> u64;
    fn add(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt;
    fn mul(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt;

    fn pow(&self, mut a: Self::ModInt, mut b: u64) -> Self::ModInt {
        let (_a, _b) = (a, b);
        let mut result = self.one();
        while b > 0 {
            if b & 1 != 0 {
                result = self.mul(result, a);
            }
            a = self.mul(a, a);
            b >>= 1;
        }

        // Check that r (reduced back to the usual representation) equals
        //  a^b % n, unless the latter computation overflows
        // Temporarily commented-out, as there u64::checked_pow is not available
        //  on the minimum supported Rust version, nor is an appropriate method
        //  for compiling the check conditionally.
        //debug_assert!(self
        //    .to_u64(_a)
        //    .checked_pow(_b as u32)
        //    .map(|r| r % self.modulus() == self.to_u64(result))
        //    .unwrap_or(true));

        result
    }

    fn one(&self) -> Self::ModInt {
        self.from_u64(1)
    }
    fn minus_one(&self) -> Self::ModInt {
        self.from_u64(self.modulus() - 1)
    }
    fn zero(&self) -> Self::ModInt {
        self.from_u64(0)
    }
}

#[derive(Clone, Copy, Debug)]
pub(crate) struct Montgomery<T: DoubleInt> {
    a: T,
    n: T,
}

impl<T: DoubleInt> Montgomery<T> {
    /// computes x/R mod n efficiently
    fn reduce(&self, x: T::DoubleWidth) -> T {
        let t_bits = T::zero().count_zeros() as usize;

        debug_assert!(x < (self.n.as_double_width()) << t_bits);
        // TODO: optimiiiiiiise
        let Montgomery { a, n } = self;
        let m = T::from_double_width(x).wrapping_mul(a);
        let nm = (n.as_double_width()) * (m.as_double_width());
        let (xnm, overflow) = x.overflowing_add_(nm); // x + n*m
        debug_assert_eq!(
            xnm % (T::DoubleWidth::one() << T::zero().count_zeros() as usize),
            T::DoubleWidth::zero()
        );

        // (x + n*m) / R
        // in case of overflow, this is (2¹²⁸ + xnm)/2⁶⁴ - n = xnm/2⁶⁴ + (2⁶⁴ - n)
        let y = T::from_double_width(xnm >> t_bits)
            + if !overflow {
                T::zero()
            } else {
                n.wrapping_neg()
            };

        if y >= *n {
            y - *n
        } else {
            y
        }
    }
}

impl<T: DoubleInt> Arithmetic for Montgomery<T> {
    // Montgomery transform, R=2⁶⁴
    // Provides fast arithmetic mod n (n odd, u64)
    type ModInt = T;

    fn new(n: u64) -> Self {
        debug_assert!(T::zero().count_zeros() >= 64 || n < (1 << T::zero().count_zeros() as usize));
        let n = T::from_u64(n);
        let a = modular_inverse(n).wrapping_neg();
        debug_assert_eq!(n.wrapping_mul(&a), T::one().wrapping_neg());
        Montgomery { a, n }
    }

    fn modulus(&self) -> u64 {
        self.n.as_u64()
    }

    fn from_u64(&self, x: u64) -> Self::ModInt {
        // TODO: optimise!
        debug_assert!(x < self.n.as_u64());
        let r = T::from_double_width(
            ((T::DoubleWidth::from_u64(x)) << T::zero().count_zeros() as usize)
                % self.n.as_double_width(),
        );
        debug_assert_eq!(x, self.to_u64(r));
        r
    }

    fn to_u64(&self, n: Self::ModInt) -> u64 {
        self.reduce(n.as_double_width()).as_u64()
    }

    fn add(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt {
        let (r, overflow) = a.overflowing_add_(b);

        // In case of overflow, a+b = 2⁶⁴ + r = (2⁶⁴ - n) + r (working mod n)
        let r = if !overflow {
            r
        } else {
            r + self.n.wrapping_neg()
        };

        // Normalise to [0; n[
        let r = if r < self.n { r } else { r - self.n };

        // Check that r (reduced back to the usual representation) equals
        // a+b % n
        #[cfg(debug_assertions)]
        {
            let a_r = self.to_u64(a) as u128;
            let b_r = self.to_u64(b) as u128;
            let r_r = self.to_u64(r);
            let r_2 = ((a_r + b_r) % self.n.as_u128()) as u64;
            debug_assert_eq!(
                r_r, r_2,
                "[{}] = {} ≠ {} = {} + {} = [{}] + [{}] mod {}; a = {}",
                r, r_r, r_2, a_r, b_r, a, b, self.n, self.a
            );
        }
        r
    }

    fn mul(&self, a: Self::ModInt, b: Self::ModInt) -> Self::ModInt {
        let r = self.reduce(a.as_double_width() * b.as_double_width());

        // Check that r (reduced back to the usual representation) equals
        // a*b % n
        #[cfg(debug_assertions)]
        {
            let a_r = self.to_u64(a) as u128;
            let b_r = self.to_u64(b) as u128;
            let r_r = self.to_u64(r);
            let r_2: u64 = ((a_r * b_r) % self.n.as_u128()) as u64;
            debug_assert_eq!(
                r_r, r_2,
                "[{}] = {} ≠ {} = {} * {} = [{}] * [{}] mod {}; a = {}",
                r, r_r, r_2, a_r, b_r, a, b, self.n, self.a
            );
        }
        r
    }
}

// NOTE: Trait can be removed once num-traits adds a similar one;
//       see https://github.com/rust-num/num-traits/issues/168
pub(crate) trait OverflowingAdd: Sized {
    fn overflowing_add_(self, n: Self) -> (Self, bool);
}
macro_rules! overflowing {
    ($x:ty) => {
        impl OverflowingAdd for $x {
            fn overflowing_add_(self, n: Self) -> (Self, bool) {
                self.overflowing_add(n)
            }
        }
    };
}
overflowing!(u32);
overflowing!(u64);
overflowing!(u128);

pub(crate) trait Int:
    Display + Debug + PrimInt + OverflowingAdd + WrappingNeg + WrappingSub + WrappingMul
{
    fn as_u64(&self) -> u64;
    fn from_u64(n: u64) -> Self;
    #[cfg(debug_assertions)]
    fn as_u128(&self) -> u128;
}

pub(crate) trait DoubleInt: Int {
    type DoubleWidth: Int;

    fn as_double_width(self) -> Self::DoubleWidth;
    fn from_double_width(n: Self::DoubleWidth) -> Self;
}

macro_rules! int {
    ( $x:ty ) => {
        impl Int for $x {
            fn as_u64(&self) -> u64 {
                *self as u64
            }
            fn from_u64(n: u64) -> Self {
                n as _
            }
            #[cfg(debug_assertions)]
            fn as_u128(&self) -> u128 {
                *self as u128
            }
        }
    };
}
macro_rules! double_int {
    ( $x:ty, $y:ty ) => {
        int!($x);
        impl DoubleInt for $x {
            type DoubleWidth = $y;

            fn as_double_width(self) -> $y {
                self as _
            }
            fn from_double_width(n: $y) -> $x {
                n as _
            }
        }
    };
}

double_int!(u32, u64);
double_int!(u64, u128);
int!(u128);

// extended Euclid algorithm
// precondition: a is odd
pub(crate) fn modular_inverse<T: Int>(a: T) -> T {
    let zero = T::zero();
    let one = T::one();
    debug_assert!(a % (one + one) == one, "{:?} is not odd", a);

    let mut t = zero;
    let mut newt = one;
    let mut r = zero;
    let mut newr = a;

    while newr != zero {
        let quot = if r == zero {
            // special case when we're just starting out
            // This works because we know that
            // a does not divide 2^64, so floor(2^64 / a) == floor((2^64-1) / a);
            T::max_value()
        } else {
            r
        } / newr;

        let newtp = t.wrapping_sub(&quot.wrapping_mul(&newt));
        t = newt;
        newt = newtp;

        let newrp = r.wrapping_sub(&quot.wrapping_mul(&newr));
        r = newr;
        newr = newrp;
    }

    debug_assert_eq!(r, one);
    t
}

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

    macro_rules! parametrized_check {
        ( $f:ident ) => {
            paste::item! {
                #[test]
                fn [< $f _ u32 >]() {
                    $f::<u32>()
                }
                #[test]
                fn [< $f _ u64 >]() {
                    $f::<u64>()
                }
            }
        };
    }

    fn test_inverter<T: Int>() {
        // All odd integers from 1 to 20 000
        let one = T::from(1).unwrap();
        let two = T::from(2).unwrap();
        let mut test_values = (0..10_000)
            .map(|i| T::from(i).unwrap())
            .map(|i| two * i + one);

        assert!(test_values.all(|x| x.wrapping_mul(&modular_inverse(x)) == one));
    }
    parametrized_check!(test_inverter);

    fn test_add<A: DoubleInt>() {
        for n in 0..100 {
            let n = 2 * n + 1;
            let m = Montgomery::<A>::new(n);
            for x in 0..n {
                let m_x = m.from_u64(x);
                for y in 0..=x {
                    let m_y = m.from_u64(y);
                    println!("{n:?}, {x:?}, {y:?}", n = n, x = x, y = y);
                    assert_eq!((x + y) % n, m.to_u64(m.add(m_x, m_y)));
                }
            }
        }
    }
    parametrized_check!(test_add);

    fn test_mult<A: DoubleInt>() {
        for n in 0..100 {
            let n = 2 * n + 1;
            let m = Montgomery::<A>::new(n);
            for x in 0..n {
                let m_x = m.from_u64(x);
                for y in 0..=x {
                    let m_y = m.from_u64(y);
                    assert_eq!((x * y) % n, m.to_u64(m.mul(m_x, m_y)));
                }
            }
        }
    }
    parametrized_check!(test_mult);

    fn test_roundtrip<A: DoubleInt>() {
        for n in 0..100 {
            let n = 2 * n + 1;
            let m = Montgomery::<A>::new(n);
            for x in 0..n {
                let x_ = m.from_u64(x);
                assert_eq!(x, m.to_u64(x_));
            }
        }
    }
    parametrized_check!(test_roundtrip);
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate lopdf;

use chrono::{DateTime, Utc};
use predicates::prelude::*;
use predicates::reflection::{Case, Child, PredicateReflection, Product};
use std::cmp;
use std::fmt;

/// Checks that the variable of type [u8] can be parsed as a PDF file.
#[derive(Debug)]
pub struct PdfPredicate {}

impl PdfPredicate {
    pub fn with_page_count(self: Self, num_pages: usize) -> DetailPredicate<Self> {
        DetailPredicate::<Self> {
            p: self,
            d: Detail::PageCount(num_pages),
        }
    }

    pub fn with_page_size(self: Self, width: i64, height: i64) -> DetailPredicate<Self> {
        DetailPredicate::<Self> {
            p: self,
            d: Detail::PageSize(Dimensions {
                w: width,
                h: height,
                unit: 1.0,
            }),
        }
    }

    pub fn with_creation_date(self: Self, when: DateTime<Utc>) -> DetailPredicate<Self> {
        DetailPredicate::<Self> {
            p: self,
            d: Detail::CreationDate(when),
        }
    }
}

impl Predicate<[u8]> for PdfPredicate {
    fn eval(&self, data: &[u8]) -> bool {
        lopdf::Document::load_mem(data).is_ok()
    }

    fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
        match lopdf::Document::load_mem(data) {
            Ok(_) => None,
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for PdfPredicate {}

impl fmt::Display for PdfPredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "is a PDF")
    }
}

/// Extends a PdfPredicate by a check for page count, page size or creation date.
#[derive(Debug)]
pub struct DetailPredicate<PdfPredicate> {
    p: PdfPredicate,
    d: Detail,
}

#[derive(Debug)]
enum Detail {
    PageCount(usize),
    PageSize(Dimensions),
    CreationDate(DateTime<Utc>),
}

#[derive(Debug)]
struct Dimensions {
    w: i64,
    h: i64,    //
    unit: f64, // UserUnit, in points (1/72 of an inch)
}

impl Dimensions {
    pub fn from_media_box(obj: &lopdf::Object, unit: Option<f64>) -> lopdf::Result<Dimensions> {
        let a = obj.as_array()?;
        Ok(Dimensions {
            w: a[2].as_i64()?,
            h: a[3].as_i64()?,
            unit: unit.unwrap_or(1.0),
        })
    }

    pub fn width_in_mm(self: &Self) -> f64 {
        self.w as f64 * self.unit * 72.0 / 254.0
    }

    pub fn height_in_mm(self: &Self) -> f64 {
        self.h as f64 * self.unit * 72.0 / 254.0
    }
}

impl fmt::Display for Dimensions {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} mm x {} mm", self.width_in_mm(), self.height_in_mm())
    }
}

impl cmp::PartialEq for Dimensions {
    fn eq(&self, other: &Self) -> bool {
        approx_eq!(f64, self.width_in_mm(), other.width_in_mm())
            && approx_eq!(f64, self.height_in_mm(), other.height_in_mm())
    }
}

impl cmp::Eq for Dimensions {}

trait Details {
    fn get_page_count(&self) -> usize;
    fn get_page_size(&self) -> Option<Dimensions>;
    fn get_creation_date(&self) -> Option<DateTime<Utc>>;
    fn get_from_trailer<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object>;
    fn get_from_first_page<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object>;
}

impl DetailPredicate<PdfPredicate> {
    fn eval_doc(&self, doc: &lopdf::Document) -> bool {
        match &self.d {
            Detail::PageCount(n) => doc.get_page_count() == *n,
            Detail::PageSize(d) => doc.get_page_size().map_or(false, |dim| dim == *d),
            Detail::CreationDate(d) => doc.get_creation_date().map_or(false, |date| date == *d),
        }
    }

    fn find_case_for_doc<'a>(&'a self, expected: bool, doc: &lopdf::Document) -> Option<Case<'a>> {
        if self.eval_doc(doc) == expected {
            let product = self.product_for_doc(doc);
            Some(Case::new(Some(self), false).add_product(product))
        } else {
            None
        }
    }

    fn product_for_doc(&self, doc: &lopdf::Document) -> Product {
        match &self.d {
            Detail::PageCount(_) => Product::new(
                "actual page count",
                format!("{} page(s)", doc.get_page_count()),
            ),
            Detail::PageSize(_) => Product::new(
                "actual page size",
                match doc.get_page_size() {
                    Some(dim) => format!("{}", dim),
                    None => "None".to_string(),
                },
            ),
            Detail::CreationDate(_) => Product::new(
                "actual creation date",
                format!("{:?}", doc.get_creation_date()),
            ),
        }
    }
}

impl Details for lopdf::Document {
    fn get_page_count(self: &Self) -> usize {
        self.get_pages().len()
    }

    fn get_page_size(self: &Self) -> Option<Dimensions> {
        let to_f64 = |obj: &lopdf::Object| obj.as_f64();
        match self.get_from_first_page(b"MediaBox") {
            Ok(obj) => {
                let unit = self.get_from_first_page(b"UserUnit").and_then(to_f64).ok();
                Dimensions::from_media_box(obj, unit).ok()
            }
            Err(_) => None,
        }
    }

    fn get_creation_date(self: &Self) -> Option<DateTime<Utc>> {
        match self.get_from_trailer(b"CreationDate") {
            Ok(obj) => obj.as_datetime().map(|date| date.with_timezone(&Utc)),
            Err(_) => None,
        }
    }

    fn get_from_trailer<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object> {
        let id = self.trailer.get(b"Info")?.as_reference()?;
        self.get_object(id)?.as_dict()?.get(key)
    }

    fn get_from_first_page<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object> {
        match self.page_iter().next() {
            Some(id) => self.get_object(id)?.as_dict()?.get(key),
            None => Err(lopdf::Error::ObjectNotFound),
        }
    }
}

impl Predicate<[u8]> for DetailPredicate<PdfPredicate> {
    fn eval(&self, data: &[u8]) -> bool {
        match lopdf::Document::load_mem(data) {
            Ok(doc) => self.eval_doc(&doc),
            _ => false,
        }
    }

    fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
        match lopdf::Document::load_mem(data) {
            Ok(doc) => self.find_case_for_doc(expected, &doc),
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for DetailPredicate<PdfPredicate> {
    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
        let params = vec![Child::new("predicate", &self.p)];
        Box::new(params.into_iter())
    }
}

impl fmt::Display for DetailPredicate<PdfPredicate> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match &self.d {
            Detail::PageCount(n) => write!(f, "is a PDF with {} page(s)", n),
            Detail::PageSize(d) => write!(f, "is a PDF sized {}", d),
            Detail::CreationDate(d) => write!(f, "is a PDF created {:?}", d),
        }
    }
}
<commit_msg>Comment on what a PDF dimensions mean<commit_after>extern crate chrono;
extern crate lopdf;

use chrono::{DateTime, Utc};
use predicates::prelude::*;
use predicates::reflection::{Case, Child, PredicateReflection, Product};
use std::cmp;
use std::fmt;

/// Checks that the variable of type [u8] can be parsed as a PDF file.
#[derive(Debug)]
pub struct PdfPredicate {}

impl PdfPredicate {
    pub fn with_page_count(self: Self, num_pages: usize) -> DetailPredicate<Self> {
        DetailPredicate::<Self> {
            p: self,
            d: Detail::PageCount(num_pages),
        }
    }

    pub fn with_page_size(self: Self, width: i64, height: i64) -> DetailPredicate<Self> {
        DetailPredicate::<Self> {
            p: self,
            d: Detail::PageSize(Dimensions {
                w: width,
                h: height,
                unit: 1.0,
            }),
        }
    }

    pub fn with_creation_date(self: Self, when: DateTime<Utc>) -> DetailPredicate<Self> {
        DetailPredicate::<Self> {
            p: self,
            d: Detail::CreationDate(when),
        }
    }
}

impl Predicate<[u8]> for PdfPredicate {
    fn eval(&self, data: &[u8]) -> bool {
        lopdf::Document::load_mem(data).is_ok()
    }

    fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
        match lopdf::Document::load_mem(data) {
            Ok(_) => None,
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for PdfPredicate {}

impl fmt::Display for PdfPredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "is a PDF")
    }
}

/// Extends a PdfPredicate by a check for page count, page size or creation date.
#[derive(Debug)]
pub struct DetailPredicate<PdfPredicate> {
    p: PdfPredicate,
    d: Detail,
}

#[derive(Debug)]
enum Detail {
    PageCount(usize),
    PageSize(Dimensions),
    CreationDate(DateTime<Utc>),
}

/// A PDF page's dimensions from its `MediaBox`.
///
/// Note that `w` and `h` given in `UserUnit`, which is by default 1.0 = 1/72 inch.
#[derive(Debug)]
struct Dimensions {
    w: i64,
    h: i64,
    unit: f64, // UserUnit, in points (1/72 of an inch)
}

impl Dimensions {
    pub fn from_media_box(obj: &lopdf::Object, unit: Option<f64>) -> lopdf::Result<Dimensions> {
        let a = obj.as_array()?;
        Ok(Dimensions {
            w: a[2].as_i64()?,
            h: a[3].as_i64()?,
            unit: unit.unwrap_or(1.0),
        })
    }

    pub fn width_in_mm(self: &Self) -> f64 {
        self.w as f64 * self.unit * 72.0 / 254.0
    }

    pub fn height_in_mm(self: &Self) -> f64 {
        self.h as f64 * self.unit * 72.0 / 254.0
    }
}

impl fmt::Display for Dimensions {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} mm x {} mm", self.width_in_mm(), self.height_in_mm())
    }
}

impl cmp::PartialEq for Dimensions {
    fn eq(&self, other: &Self) -> bool {
        approx_eq!(f64, self.width_in_mm(), other.width_in_mm())
            && approx_eq!(f64, self.height_in_mm(), other.height_in_mm())
    }
}

impl cmp::Eq for Dimensions {}

trait Details {
    fn get_page_count(&self) -> usize;
    fn get_page_size(&self) -> Option<Dimensions>;
    fn get_creation_date(&self) -> Option<DateTime<Utc>>;
    fn get_from_trailer<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object>;
    fn get_from_first_page<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object>;
}

impl DetailPredicate<PdfPredicate> {
    fn eval_doc(&self, doc: &lopdf::Document) -> bool {
        match &self.d {
            Detail::PageCount(n) => doc.get_page_count() == *n,
            Detail::PageSize(d) => doc.get_page_size().map_or(false, |dim| dim == *d),
            Detail::CreationDate(d) => doc.get_creation_date().map_or(false, |date| date == *d),
        }
    }

    fn find_case_for_doc<'a>(&'a self, expected: bool, doc: &lopdf::Document) -> Option<Case<'a>> {
        if self.eval_doc(doc) == expected {
            let product = self.product_for_doc(doc);
            Some(Case::new(Some(self), false).add_product(product))
        } else {
            None
        }
    }

    fn product_for_doc(&self, doc: &lopdf::Document) -> Product {
        match &self.d {
            Detail::PageCount(_) => Product::new(
                "actual page count",
                format!("{} page(s)", doc.get_page_count()),
            ),
            Detail::PageSize(_) => Product::new(
                "actual page size",
                match doc.get_page_size() {
                    Some(dim) => format!("{}", dim),
                    None => "None".to_string(),
                },
            ),
            Detail::CreationDate(_) => Product::new(
                "actual creation date",
                format!("{:?}", doc.get_creation_date()),
            ),
        }
    }
}

impl Details for lopdf::Document {
    fn get_page_count(self: &Self) -> usize {
        self.get_pages().len()
    }

    fn get_page_size(self: &Self) -> Option<Dimensions> {
        let to_f64 = |obj: &lopdf::Object| obj.as_f64();
        match self.get_from_first_page(b"MediaBox") {
            Ok(obj) => {
                let unit = self.get_from_first_page(b"UserUnit").and_then(to_f64).ok();
                Dimensions::from_media_box(obj, unit).ok()
            }
            Err(_) => None,
        }
    }

    fn get_creation_date(self: &Self) -> Option<DateTime<Utc>> {
        match self.get_from_trailer(b"CreationDate") {
            Ok(obj) => obj.as_datetime().map(|date| date.with_timezone(&Utc)),
            Err(_) => None,
        }
    }

    fn get_from_trailer<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object> {
        let id = self.trailer.get(b"Info")?.as_reference()?;
        self.get_object(id)?.as_dict()?.get(key)
    }

    fn get_from_first_page<'a>(self: &'a Self, key: &[u8]) -> lopdf::Result<&'a lopdf::Object> {
        match self.page_iter().next() {
            Some(id) => self.get_object(id)?.as_dict()?.get(key),
            None => Err(lopdf::Error::ObjectNotFound),
        }
    }
}

impl Predicate<[u8]> for DetailPredicate<PdfPredicate> {
    fn eval(&self, data: &[u8]) -> bool {
        match lopdf::Document::load_mem(data) {
            Ok(doc) => self.eval_doc(&doc),
            _ => false,
        }
    }

    fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
        match lopdf::Document::load_mem(data) {
            Ok(doc) => self.find_case_for_doc(expected, &doc),
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for DetailPredicate<PdfPredicate> {
    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
        let params = vec![Child::new("predicate", &self.p)];
        Box::new(params.into_iter())
    }
}

impl fmt::Display for DetailPredicate<PdfPredicate> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match &self.d {
            Detail::PageCount(n) => write!(f, "is a PDF with {} page(s)", n),
            Detail::PageSize(d) => write!(f, "is a PDF sized {}", d),
            Detail::CreationDate(d) => write!(f, "is a PDF created {:?}", d),
        }
    }
}
<|endoftext|>


<commit_before>use std::result::Result;

use super::script::*;

///
/// Represents a parse error
///
pub struct ParseError {

}

///
/// Tool that parses our scripting language
///
pub struct ParseScriptTool {
}

///
/// Returns true if a token is considered syntax (gets returned from lookahead)
///
fn is_syntax(token: &ScriptToken) -> bool {
    match token.token {
        ScriptLexerToken::Whitespace    |
        ScriptLexerToken::Comment       => false,

        _                               => true
    }
}

///
/// Looks ahead to the next syntactically relevant lexer match (and returns the tokens after it)
///
fn lookahead<'a>(input: &'a [ScriptToken]) -> Option<(&'a ScriptToken, &'a [ScriptToken])> {
    let mut index   = 0;
    let len         = input.len();

    loop {
        if index >= len {
            return None;
        } else if is_syntax(&input[index]) {
            return Some((&input[index], &input[index+1..len]));
        }

        index += 1;
    }
}

///
/// Parses a statement
///
pub fn parse_statement<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!();
}

///
/// Parses a command
///
/// Syntax '<expression>', '<expression> <expression>'
///
pub fn parse_command<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!();
}

impl ParseScriptTool {
    ///
    /// Creates a new script parsing tool
    ///
    pub fn new() -> ParseScriptTool {
        ParseScriptTool { }
    }
}<commit_msg>Use parse_statement to dispatch to the parsers for different statement types<commit_after>use std::result::Result;

use super::script::*;

///
/// Represents a parse error
///
pub struct ParseError {

}

///
/// Tool that parses our scripting language
///
pub struct ParseScriptTool {
}

impl ParseError {
    pub fn new() -> ParseError {
        ParseError { }
    }
}

///
/// Returns true if a token is considered syntax (gets returned from lookahead)
///
fn is_syntax(token: &ScriptToken) -> bool {
    match token.token {
        ScriptLexerToken::Whitespace    |
        ScriptLexerToken::Comment       => false,

        _                               => true
    }
}

///
/// Looks ahead to the next syntactically relevant lexer match (and returns the tokens after it)
///
fn lookahead<'a>(input: &'a [ScriptToken]) -> Option<(&'a ScriptToken, &'a [ScriptToken])> {
    let mut index   = 0;
    let len         = input.len();

    loop {
        if index >= len {
            return None;
        } else if is_syntax(&input[index]) {
            return Some((&input[index], &input[index+1..len]));
        }

        index += 1;
    }
}

///
/// Parses a statement
///
pub fn parse_statement<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    if let Some((lookahead, remainder)) = lookahead(input) {
        match lookahead.token {
            // Newlines are ignored
            ScriptLexerToken::Newline       => parse_statement(remainder),

            ScriptLexerToken::Let           => parse_let(remainder),
            ScriptLexerToken::Var           => parse_var(remainder),
            ScriptLexerToken::Def           => parse_def(remainder),
            ScriptLexerToken::If            => parse_if(remainder),
            ScriptLexerToken::Using         => parse_using(remainder),
            ScriptLexerToken::While         => parse_while(remainder),
            ScriptLexerToken::Loop          => parse_loop(remainder),
            ScriptLexerToken::For           => parse_for(remainder),

            ScriptLexerToken::Identifier    => parse_command(input),

            // Unrecognised token
            _ => Err(ParseError::new())
        }
    } else {
        // EOF
        Err(ParseError::new())
    }
}

///
/// Parses a command
///
/// Syntax '<expression>', '<expression> <expression>'
///
pub fn parse_command<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!();
}

pub fn parse_let<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_var<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_def<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_if<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_using<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_while<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_loop<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_for<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

impl ParseScriptTool {
    ///
    /// Creates a new script parsing tool
    ///
    pub fn new() -> ParseScriptTool {
        ParseScriptTool { }
    }
}<|endoftext|>


<commit_before>#![allow(clippy::cast_ptr_alignment)] // clippy is too strict here

use super::arc_wake::{ArcWake, clone_arc_raw, wake_arc_raw, wake_by_ref_arc_raw};
use alloc::sync::Arc;
use core::marker::PhantomData;
use core::ops::Deref;
use core::task::{Waker, RawWaker, RawWakerVTable};

// TODO: The link to Waker below points to futures::task::Waker and not to std. Is that a
// bug in rustdoc?
//
/// A [`Waker`](::std::task::Waker) that is only valid for a given lifetime.
///
/// Note: this type implements [`Deref<Target = Waker>`](::std::ops::Deref),
/// so it can be used to get a `&Waker`.
#[derive(Debug)]
pub struct WakerRef<'a> {
    waker: Waker,
    _marker: PhantomData<&'a ()>,
}

impl WakerRef<'_> {
    /// Create a new [`WakerRef`] from a [`Waker`].
    ///
    /// Note: this function is safe, but it is generally only used
    /// from `unsafe` contexts that need to create a `Waker`
    /// that is guaranteed not to outlive a particular lifetime.
    pub fn new(waker: Waker) -> Self {
        WakerRef {
            waker,
            _marker: PhantomData,
        }
    }
}

impl Deref for WakerRef<'_> {
    type Target = Waker;

    fn deref(&self) -> &Waker {
        &self.waker
    }
}

#[inline]
unsafe fn noop(_data: *const ()) {}

/// Creates a reference to a [`Waker`](::std::task::Waker)
/// from a local [`ArcWake`].
///
/// The resulting [`Waker`](::std::task::Waker) will call
/// [`ArcWake.wake()`](ArcWake::wake) if awoken.
#[inline]
pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
where
    W: ArcWake
{
    // This uses the same mechanism as Arc::into_raw, without needing a reference.
    // This is potentially not stable
    let ptr = &*wake as &W as *const W as *const ();

    // Similar to `waker_vtable`, but with a no-op `drop` function.
    // Clones of the resulting `RawWaker` will still be dropped normally.
    let vtable = &RawWakerVTable::new(
        clone_arc_raw::<W>,
        wake_arc_raw::<W>,
        wake_by_ref_arc_raw::<W>,
        noop,
    );

    let waker = unsafe {
        Waker::from_raw(RawWaker::new(ptr, vtable))
    };
    WakerRef::new(waker)
}
<commit_msg>Change WakerRef's wake function to panic<commit_after>#![allow(clippy::cast_ptr_alignment)] // clippy is too strict here

use super::arc_wake::{ArcWake, clone_arc_raw, wake_by_ref_arc_raw};
use alloc::sync::Arc;
use core::marker::PhantomData;
use core::ops::Deref;
use core::task::{Waker, RawWaker, RawWakerVTable};

// TODO: The link to Waker below points to futures::task::Waker and not to std. Is that a
// bug in rustdoc?
//
/// A [`Waker`](::std::task::Waker) that is only valid for a given lifetime.
///
/// Note: this type implements [`Deref<Target = Waker>`](::std::ops::Deref),
/// so it can be used to get a `&Waker`.
#[derive(Debug)]
pub struct WakerRef<'a> {
    waker: Waker,
    _marker: PhantomData<&'a ()>,
}

impl WakerRef<'_> {
    /// Create a new [`WakerRef`] from a [`Waker`].
    ///
    /// Note: this function is safe, but it is generally only used
    /// from `unsafe` contexts that need to create a `Waker`
    /// that is guaranteed not to outlive a particular lifetime.
    pub fn new(waker: Waker) -> Self {
        WakerRef {
            waker,
            _marker: PhantomData,
        }
    }
}

impl Deref for WakerRef<'_> {
    type Target = Waker;

    fn deref(&self) -> &Waker {
        &self.waker
    }
}

#[inline]
unsafe fn noop(_data: *const ()) {}

unsafe fn wake_unreachable(_data: *const ()) {
    // With only a reference, calling `wake_arc_raw()` would be unsound,
    // since the `WakerRef` didn't increment the refcount of the `ArcWake`,
    // and `wake_arc_raw` would *decrement* it.
    //
    // This should never be reachable, since `WakerRef` only provides a `Deref`
    // to the inner `Waker`.
    //
    // Still, safer to panic here than to call `wake_arc_raw`.
    unreachable!("WakerRef::wake");
}

/// Creates a reference to a [`Waker`](::std::task::Waker)
/// from a local [`ArcWake`].
///
/// The resulting [`Waker`](::std::task::Waker) will call
/// [`ArcWake.wake()`](ArcWake::wake) if awoken.
#[inline]
pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
where
    W: ArcWake
{
    // This uses the same mechanism as Arc::into_raw, without needing a reference.
    // This is potentially not stable
    let ptr = &*wake as &W as *const W as *const ();

    // Similar to `waker_vtable`, but with a no-op `drop` function.
    // Clones of the resulting `RawWaker` will still be dropped normally.
    let vtable = &RawWakerVTable::new(
        clone_arc_raw::<W>,
        wake_unreachable,
        wake_by_ref_arc_raw::<W>,
        noop,
    );

    let waker = unsafe {
        Waker::from_raw(RawWaker::new(ptr, vtable))
    };
    WakerRef::new(waker)
}
<|endoftext|>


<commit_before><commit_msg>ADD: regression test for runaway runlength, as reported by Corey Farwell<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor Roundtrip Tester<commit_after><|endoftext|>


<commit_before><commit_msg>Fix lack of nightly attr on test<commit_after><|endoftext|>


<commit_before>use core::cmp::{Eq, Ord};

pub trait Map<K: Copy Eq Ord, V: Copy> {
  pure fn get(k: K) -> @Option<V>;
  pure fn put(k: K, v: V) -> self;
  pure fn delete(k: K) -> self;
}

// private
enum RBColor {
  Red,
  Black
}

pub enum RBMap<K: Copy Eq Ord, V: Copy> {
  //   color    left         k  value      right
  Tree(RBColor, @RBMap<K,V>, K, @Option<V>, @RBMap<K,V>),
  Leaf
}

pure fn RBMap<K: Copy Eq Ord, V: Copy>(key: K, value: V) -> @RBMap<K, V> {
  @Tree(Red, @Leaf, key, @Some(value), @Leaf)
}

/**
 * A purely functional Red-Black tree.
 *
 * A port of Matt Might's Scala port of Okasaki's RB Trees: http://matt.might.net/articles/implementation-of-immutable-purely-functional-okasaki-red-black-tree-maps-in-scala/RBMap.scala
 * which was itself a port of http://www.ccs.neu.edu/course/cs3500wc/jfp99redblack.pdf
 */
impl<K: Copy Eq Ord, V: Copy> @RBMap<K, V> : Map<K, V> {
  pure fn get(k: K) -> @Option<V> {
    match self {
      @Leaf => @None,
      @Tree(_, left, key, maybe_value, right) => {
        if (k.lt(&key)) {
          left.get(k)
        } else if (k.gt(&key)) {
          right.get(k)
        } else {
          maybe_value
        }
      }
    }
  }

  pure fn put(k : K, v : V) -> @RBMap<K, V> {
    self.modifiedWith(k, |m,n| { @Some(v) })
  }

  pure fn delete(k: K) -> @RBMap<K, V> {
    self.modifiedWith(k, |m,n| { @None })
  }

  priv pure fn blacken(n : @RBMap<K, V>) -> @RBMap<K, V> {
    match n {
      @Leaf => n,
      @Tree(_,l,k,v,r) => @Tree(Black,l,k,v,r)
    }
  }

  priv pure fn modifiedWith (k : K, f : fn(K, @Option<V>) -> @Option<V>) -> @RBMap<K, V> {
    self.blacken(self.modWith(k, f))
  }

  priv pure fn balance (c : RBColor, l : @RBMap<K,V>, k : K, v : @Option<V>, r : @RBMap<K,V>) -> @RBMap<K,V> {
    match (c,l,k,v,r) {
      (Black,@Tree(Red,@Tree(Red,a,xK,xV,b),yK,yV,c),zK,zV,d) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (Black,@Tree(Red,a,xK,xV,@Tree(Red,b,yK,yV,c)),zK,zV,d) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (Black,a,xK,xV,@Tree(Red,@Tree(Red,b,yK,yV,c),zK,zV,d)) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (Black,a,xK,xV,@Tree(Red,b,yK,yV,@Tree(Red,c,zK,zV,d))) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (c,a,xK,xV,b) =>
        @Tree(c,a,xK,xV,b)
    }
  }

  priv pure fn modWith (k : K, f : fn(K, @Option<V>) -> @Option<V>) -> @RBMap<K, V> {
    match self {
      @Leaf => @Tree(Red, self, k, f(k, @None), self),
      @Tree(color, left, key, maybe_value, right) => {
        if (k.lt(&key)) {
          self.balance(color, left.modWith(k, f), key, maybe_value, right)
        } else if (k == key) {
          @Tree(color, left, k, f(key, maybe_value), right)
        } else {
          self.balance(color, left, key, maybe_value, right.modWith(k, f))
        }
      }
    }
  }
}

#[test]
fn test_rb_tree_create() {
  let v1 = RBMap("stevej", 150);
  let v2 = v1.put("thatstacy", 167);

  assert(v2.get("stevej") == @Some(150));
  assert(v2.get("thatstacy") == @Some(167));

  let v3 = v2.delete("stevej");
  assert(v3.get("stevej") == @None);
  assert(v3.get("thatstacy") == @Some(167));
}<commit_msg>small cleanup<commit_after>use core::cmp::{Eq, Ord};

pub trait Map<K: Copy Eq Ord, V: Copy> {
  pure fn get(k: K) -> @Option<V>;
  pure fn put(k: K, v: V) -> self;
  pure fn delete(k: K) -> self;
}

enum RBColor {
  Red,
  Black
}

pub enum RBMap<K: Copy Eq Ord, V: Copy> {
  //   color    left         k  value       right
  Tree(RBColor, @RBMap<K,V>, K, @Option<V>, @RBMap<K,V>),
  Leaf
}

pure fn RBMap<K: Copy Eq Ord, V: Copy>(key: K, value: V) -> @RBMap<K, V> {
  @Tree(Red, @Leaf, key, @Some(value), @Leaf)
}

/**
 * A purely functional Red-Black tree.
 *
 * A port of Matt Might's Scala port of Okasaki's RB Trees: http://matt.might.net/articles/implementation-of-immutable-purely-functional-okasaki-red-black-tree-maps-in-scala/RBMap.scala
 * which was itself a port of http://www.ccs.neu.edu/course/cs3500wc/jfp99redblack.pdf
 */
impl<K: Copy Eq Ord, V: Copy> @RBMap<K, V> : Map<K, V> {
  pure fn get(k: K) -> @Option<V> {
    match self {
      @Leaf => @None,
      @Tree(_, left, key, maybe_value, right) => {
        if (k.lt(&key)) {
          left.get(k)
        } else if (k.gt(&key)) {
          right.get(k)
        } else {
          maybe_value
        }
      }
    }
  }

  pure fn put(k : K, v : V) -> @RBMap<K, V> {
    self.modifiedWith(k, |m,n| { @Some(v) })
  }

  pure fn delete(k: K) -> @RBMap<K, V> {
    self.modifiedWith(k, |m,n| { @None })
  }

  priv pure fn blacken(n : @RBMap<K, V>) -> @RBMap<K, V> {
    match n {
      @Leaf => n,
      @Tree(_,l,k,v,r) => @Tree(Black,l,k,v,r)
    }
  }

  priv pure fn modifiedWith (k : K, f : fn(K, @Option<V>) -> @Option<V>) -> @RBMap<K, V> {
    self.blacken(self.modWith(k, f))
  }

  priv pure fn balance (c : RBColor, l : @RBMap<K,V>, k : K, v : @Option<V>, r : @RBMap<K,V>) -> @RBMap<K,V> {
    match (c,l,k,v,r) {
      (Black,@Tree(Red,@Tree(Red,a,xK,xV,b),yK,yV,c),zK,zV,d) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (Black,@Tree(Red,a,xK,xV,@Tree(Red,b,yK,yV,c)),zK,zV,d) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (Black,a,xK,xV,@Tree(Red,@Tree(Red,b,yK,yV,c),zK,zV,d)) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (Black,a,xK,xV,@Tree(Red,b,yK,yV,@Tree(Red,c,zK,zV,d))) =>
        @Tree(Red,@Tree(Black,a,xK,xV,b),yK,yV,@Tree(Black,c,zK,zV,d)),
      (c,a,xK,xV,b) =>
        @Tree(c,a,xK,xV,b)
    }
  }

  priv pure fn modWith (k : K, f : fn(K, @Option<V>) -> @Option<V>) -> @RBMap<K, V> {
    match self {
      @Leaf => @Tree(Red, self, k, f(k, @None), self),
      @Tree(color, left, key, maybe_value, right) => {
        if (k.lt(&key)) {
          self.balance(color, left.modWith(k, f), key, maybe_value, right)
        } else if (k == key) {
          @Tree(color, left, k, f(key, maybe_value), right)
        } else {
          self.balance(color, left, key, maybe_value, right.modWith(k, f))
        }
      }
    }
  }
}

#[test]
fn test_rb_tree_create() {
  let v1 = RBMap("stevej", 150);
  let v2 = v1.put("thatstacy", 167);

  assert(v2.get("stevej") == @Some(150));
  assert(v2.get("thatstacy") == @Some(167));

  let v3 = v2.delete("stevej");
  assert(v3.get("stevej") == @None);
  assert(v3.get("thatstacy") == @Some(167));
}<|endoftext|>


<commit_before>use crate::aliased_command;
use cargo::util::errors::CargoResult;
use cargo::{drop_println, Config};
use cargo_util::paths::resolve_executable;
use flate2::read::GzDecoder;
use std::ffi::OsString;
use std::io::Read;
use std::io::Write;
use std::path::Path;

const COMPRESSED_MAN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/man.tgz"));

/// Checks if the `help` command is being issued.
///
/// This runs before clap processing, because it needs to intercept the `help`
/// command if a man page is available.
///
/// Returns `true` if a man page was displayed. In this case, Cargo should
/// exit.
pub fn handle_embedded_help(config: &Config) -> bool {
    match try_help(config) {
        Ok(true) => true,
        Ok(false) => false,
        Err(e) => {
            log::warn!("man failed: {:?}", e);
            false
        }
    }
}

fn try_help(config: &Config) -> CargoResult<bool> {
    let mut args = std::env::args_os()
        .skip(1)
        .skip_while(|arg| arg.to_str().map_or(false, |s| s.starts_with('-')));
    if !args
        .next()
        .map_or(false, |arg| arg.to_str() == Some("help"))
    {
        return Ok(false);
    }
    let subcommand = match args.next() {
        Some(arg) => arg,
        None => return Ok(false),
    };
    let subcommand = match subcommand.to_str() {
        Some(s) => s,
        None => return Ok(false),
    };

    // Check if this is an alias. If so, just display the alias information.
    if let Some(argv) = check_alias(config, subcommand) {
        let alias = argv.join(" ");
        drop_println!(config, "'{}' is aliased to '{}'", subcommand, alias);
        return Ok(true);
    }

    // If not an alias, this should be a built-in subcommand.
    let subcommand = match check_builtin(subcommand) {
        Some(s) => s,
        None => return Ok(false),
    };
    if resolve_executable(Path::new("man")).is_ok() {
        let man = match extract_man(&subcommand, "1") {
            Some(man) => man,
            None => return Ok(false),
        };
        write_and_spawn(&subcommand, &man, "man")?;
    } else {
        let txt = match extract_man(&subcommand, "txt") {
            Some(txt) => txt,
            None => return Ok(false),
        };
        if resolve_executable(Path::new("less")).is_ok() {
            write_and_spawn(&subcommand, &txt, "less")?;
        } else if resolve_executable(Path::new("more")).is_ok() {
            write_and_spawn(&subcommand, &txt, "more")?;
        } else {
            drop(std::io::stdout().write_all(&txt));
        }
    }
    Ok(true)
}

/// Checks if the given subcommand is an alias.
///
/// Returns None if it is not an alias.
fn check_alias(config: &Config, subcommand: &str) -> Option<Vec<String>> {
    match aliased_command(config, subcommand) {
        Ok(Some(alias)) => Some(alias),
        _ => None,
    }
}

/// Checks if the given subcommand is a built-in command (not via an alias).
///
/// Returns None if it is not a built-in command.
fn check_builtin(subcommand: &str) -> Option<String> {
    match super::builtin_exec(subcommand) {
        Some(_) => Some(subcommand.to_string()),
        None => None,
    }
}

/// Extracts the given man page from the compressed archive.
///
/// Returns None if the command wasn't found.
fn extract_man(subcommand: &str, extension: &str) -> Option<Vec<u8>> {
    let extract_name = OsString::from(format!("cargo-{}.{}", subcommand, extension));
    let gz = GzDecoder::new(COMPRESSED_MAN);
    let mut ar = tar::Archive::new(gz);
    // Unwraps should be safe here, since this is a static archive generated
    // by our build script. It should never be an invalid format!
    for entry in ar.entries().unwrap() {
        let mut entry = entry.unwrap();
        let path = entry.path().unwrap();
        if path.file_name().unwrap() != extract_name {
            continue;
        }
        let mut result = Vec::new();
        entry.read_to_end(&mut result).unwrap();
        return Some(result);
    }
    None
}

/// Write the contents of a man page to disk and spawn the given command to
/// display it.
fn write_and_spawn(name: &str, contents: &[u8], command: &str) -> CargoResult<()> {
    let prefix = format!("cargo-{}.", name);
    let mut tmp = tempfile::Builder::new().prefix(&prefix).tempfile()?;
    let f = tmp.as_file_mut();
    f.write_all(contents)?;
    f.flush()?;
    let path = tmp.path();
    // Use a path relative to the temp directory so that it can work on
    // cygwin/msys systems which don't handle windows-style paths.
    let mut relative_name = std::ffi::OsString::from("./");
    relative_name.push(path.file_name().unwrap());
    let mut cmd = std::process::Command::new(command)
        .arg(relative_name)
        .current_dir(path.parent().unwrap())
        .spawn()?;
    drop(cmd.wait());
    Ok(())
}
<commit_msg>Update src/bin/cargo/commands/help.rs<commit_after>use crate::aliased_command;
use cargo::util::errors::CargoResult;
use cargo::{drop_println, Config};
use cargo_util::paths::resolve_executable;
use flate2::read::GzDecoder;
use std::ffi::OsString;
use std::io::Read;
use std::io::Write;
use std::path::Path;

const COMPRESSED_MAN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/man.tgz"));

/// Checks if the `help` command is being issued.
///
/// This runs before clap processing, because it needs to intercept the `help`
/// command if a man page is available.
///
/// Returns `true` if a man page was displayed. In this case, Cargo should
/// exit.
pub fn handle_embedded_help(config: &Config) -> bool {
    match try_help(config) {
        Ok(true) => true,
        Ok(false) => false,
        Err(e) => {
            log::warn!("man failed: {:?}", e);
            false
        }
    }
}

fn try_help(config: &Config) -> CargoResult<bool> {
    let mut args = std::env::args_os()
        .skip(1)
        .skip_while(|arg| arg.to_str().map_or(false, |s| s.starts_with('-')));
    if !args
        .next()
        .map_or(false, |arg| arg.to_str() == Some("help"))
    {
        return Ok(false);
    }
    let subcommand = match args.next() {
        Some(arg) => arg,
        None => return Ok(false),
    };
    let subcommand = match subcommand.to_str() {
        Some(s) => s,
        None => return Ok(false),
    };

    // Check if this is an alias. If so, just display the alias information.
    if let Some(argv) = check_alias(config, subcommand) {
        let alias = argv.join(" ");
        drop_println!(config, "'{}' is aliased to '{}'", subcommand, alias);
        return Ok(true);
    }

    // If not an alias, this should be a built-in subcommand.
    let subcommand = match check_builtin(subcommand) {
        Some(s) => s,
        None => return Ok(false),
    };
    if resolve_executable(Path::new("man")).is_ok() {
        let man = match extract_man(&subcommand, "1") {
            Some(man) => man,
            None => return Ok(false),
        };
        write_and_spawn(&subcommand, &man, "man")?;
    } else {
        let txt = match extract_man(&subcommand, "txt") {
            Some(txt) => txt,
            None => return Ok(false),
        };
        if resolve_executable(Path::new("less")).is_ok() {
            write_and_spawn(&subcommand, &txt, "less")?;
        } else if resolve_executable(Path::new("more")).is_ok() {
            write_and_spawn(&subcommand, &txt, "more")?;
        } else {
            drop(std::io::stdout().write_all(&txt));
        }
    }
    Ok(true)
}

/// Checks if the given subcommand is an alias.
///
/// Returns None if it is not an alias.
fn check_alias(config: &Config, subcommand: &str) -> Option<Vec<String>> {
    match aliased_command(config, subcommand) {
        Ok(Some(alias)) => Some(alias),
        _ => None,
    }
}

/// Checks if the given subcommand is a built-in command (not via an alias).
///
/// Returns None if it is not a built-in command.
fn check_builtin(subcommand: &str) -> Option<&str> {
    super::builtin_exec(subcommand).map(|_| subcommand)
}

/// Extracts the given man page from the compressed archive.
///
/// Returns None if the command wasn't found.
fn extract_man(subcommand: &str, extension: &str) -> Option<Vec<u8>> {
    let extract_name = OsString::from(format!("cargo-{}.{}", subcommand, extension));
    let gz = GzDecoder::new(COMPRESSED_MAN);
    let mut ar = tar::Archive::new(gz);
    // Unwraps should be safe here, since this is a static archive generated
    // by our build script. It should never be an invalid format!
    for entry in ar.entries().unwrap() {
        let mut entry = entry.unwrap();
        let path = entry.path().unwrap();
        if path.file_name().unwrap() != extract_name {
            continue;
        }
        let mut result = Vec::new();
        entry.read_to_end(&mut result).unwrap();
        return Some(result);
    }
    None
}

/// Write the contents of a man page to disk and spawn the given command to
/// display it.
fn write_and_spawn(name: &str, contents: &[u8], command: &str) -> CargoResult<()> {
    let prefix = format!("cargo-{}.", name);
    let mut tmp = tempfile::Builder::new().prefix(&prefix).tempfile()?;
    let f = tmp.as_file_mut();
    f.write_all(contents)?;
    f.flush()?;
    let path = tmp.path();
    // Use a path relative to the temp directory so that it can work on
    // cygwin/msys systems which don't handle windows-style paths.
    let mut relative_name = std::ffi::OsString::from("./");
    relative_name.push(path.file_name().unwrap());
    let mut cmd = std::process::Command::new(command)
        .arg(relative_name)
        .current_dir(path.parent().unwrap())
        .spawn()?;
    drop(cmd.wait());
    Ok(())
}
<|endoftext|>


<commit_before>use std::string::*;
use std::fmt;

#[derive(Debug,Copy,Clone,PartialEq)]
pub struct Soniton {
    pub bits: u8,
    pub be: bool,
    pub packed: bool,
    pub planar: bool,
    pub float: bool,
    pub signed: bool,
}

// TODO: make it a trait for usize?
fn align(v: usize, a: usize) -> usize {
    (v + a - 1) & !(a - 1)
}

fn round_to_byte(v: usize) -> usize {
    (v + 7) >> 3
}

impl Soniton {
    pub fn new(bits: u8, be: bool, packed: bool, planar: bool, float: bool, signed: bool) -> Self {
        Soniton {
            bits: bits,
            be: be,
            packed: packed,
            planar: planar,
            float: float,
            signed: signed,
        }
    }

    pub fn get_audio_size(&self, length: usize, alignment: usize) -> usize {
        let s = if self.packed {
            round_to_byte(length * (self.bits as usize))
        } else {
            length * round_to_byte(self.bits as usize)
        };

        align(s, alignment)
    }
}

impl fmt::Display for Soniton {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let fmt = if self.float {
            "float"
        } else if self.signed {
            "int"
        } else {
            "uint"
        };
        let end = if self.be {
            "BE"
        } else {
            "LE"
        };
        write!(f,
               "({} bps, {} planar: {} packed: {} {})",
               self.bits,
               end,
               self.packed,
               self.planar,
               fmt)
    }
}

#[derive(Debug,Clone,Copy,PartialEq)]
pub enum ChannelType {
    C,
    L,
    R,
    Cs,
    Ls,
    Rs,
    Lss,
    Rss,
    LFE,
    Lc,
    Rc,
    Lh,
    Rh,
    Ch,
    LFE2,
    Lw,
    Rw,
    Ov,
    Lhs,
    Rhs,
    Chs,
    Ll,
    Rl,
    Cl,
    Lt,
    Rt,
    Lo,
    Ro,
}

impl ChannelType {
    pub fn is_center(&self) -> bool {
        match *self {
            ChannelType::C => true,
            ChannelType::Ch => true,
            ChannelType::Cl => true,
            ChannelType::Ov => true,
            ChannelType::LFE => true,
            ChannelType::LFE2 => true,
            ChannelType::Cs => true,
            ChannelType::Chs => true,
            _ => false,
        }
    }
    pub fn is_left(&self) -> bool {
        match *self {
            ChannelType::L => true,
            ChannelType::Ls => true,
            ChannelType::Lss => true,
            ChannelType::Lc => true,
            ChannelType::Lh => true,
            ChannelType::Lw => true,
            ChannelType::Lhs => true,
            ChannelType::Ll => true,
            ChannelType::Lt => true,
            ChannelType::Lo => true,
            _ => false,
        }
    }
    pub fn is_right(&self) -> bool {
        match *self {
            ChannelType::R => true,
            ChannelType::Rs => true,
            ChannelType::Rss => true,
            ChannelType::Rc => true,
            ChannelType::Rh => true,
            ChannelType::Rw => true,
            ChannelType::Rhs => true,
            ChannelType::Rl => true,
            ChannelType::Rt => true,
            ChannelType::Ro => true,
            _ => false,
        }
    }
}

impl fmt::Display for ChannelType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let name = match *self {
            ChannelType::C => "C".to_string(),
            ChannelType::L => "L".to_string(),
            ChannelType::R => "R".to_string(),
            ChannelType::Cs => "Cs".to_string(),
            ChannelType::Ls => "Ls".to_string(),
            ChannelType::Rs => "Rs".to_string(),
            ChannelType::Lss => "Lss".to_string(),
            ChannelType::Rss => "Rss".to_string(),
            ChannelType::LFE => "LFE".to_string(),
            ChannelType::Lc => "Lc".to_string(),
            ChannelType::Rc => "Rc".to_string(),
            ChannelType::Lh => "Lh".to_string(),
            ChannelType::Rh => "Rh".to_string(),
            ChannelType::Ch => "Ch".to_string(),
            ChannelType::LFE2 => "LFE2".to_string(),
            ChannelType::Lw => "Lw".to_string(),
            ChannelType::Rw => "Rw".to_string(),
            ChannelType::Ov => "Ov".to_string(),
            ChannelType::Lhs => "Lhs".to_string(),
            ChannelType::Rhs => "Rhs".to_string(),
            ChannelType::Chs => "Chs".to_string(),
            ChannelType::Ll => "Ll".to_string(),
            ChannelType::Rl => "Rl".to_string(),
            ChannelType::Cl => "Cl".to_string(),
            ChannelType::Lt => "Lt".to_string(),
            ChannelType::Rt => "Rt".to_string(),
            ChannelType::Lo => "Lo".to_string(),
            ChannelType::Ro => "Ro".to_string(),
        };
        write!(f, "{}", name)
    }
}

#[derive(Clone,Debug,PartialEq)]
pub struct ChannelMap {
    ids: Vec<ChannelType>,
}

impl ChannelMap {
    pub fn new() -> Self {
        ChannelMap { ids: Vec::new() }
    }
    pub fn add_channel(&mut self, ch: ChannelType) {
        self.ids.push(ch);
    }
    pub fn add_channels(&mut self, chs: &[ChannelType]) {
        for i in 0..chs.len() {
            self.ids.push(chs[i]);
        }
    }
    pub fn len(&self) -> usize {
        self.ids.len()
    }
    pub fn get_channel(&self, idx: usize) -> ChannelType {
        self.ids[idx]
    }
    pub fn find_channel_id(&self, t: ChannelType) -> Option<u8> {
        for i in 0..self.ids.len() {
            if self.ids[i] as i32 == t as i32 {
                return Some(i as u8);
            }
        }
        None
    }
}

pub mod formats {
    use super::*;

    pub const U8: Soniton = Soniton {
        bits: 8,
        be: false,
        packed: false,
        planar: false,
        float: false,
        signed: false,
    };
    pub const S16: Soniton = Soniton {
        bits: 16,
        be: false,
        packed: false,
        planar: false,
        float: false,
        signed: true,
    };
    pub const F32: Soniton = Soniton {
        bits: 32,
        be: false,
        packed: false,
        planar: false,
        float: true,
        signed: true,
    };
}

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

    #[test]
    fn fmt() {
        println!("{}", formats::S16);
        println!("{}", formats::U8);
        println!("{}", formats::F32);
    }
}
<commit_msg>wip: audiosample: Add an helper to build simple channelmaps<commit_after>use std::string::*;
use std::fmt;

#[derive(Debug,Copy,Clone,PartialEq)]
pub struct Soniton {
    pub bits: u8,
    pub be: bool,
    pub packed: bool,
    pub planar: bool,
    pub float: bool,
    pub signed: bool,
}

// TODO: make it a trait for usize?
fn align(v: usize, a: usize) -> usize {
    (v + a - 1) & !(a - 1)
}

fn round_to_byte(v: usize) -> usize {
    (v + 7) >> 3
}

impl Soniton {
    pub fn new(bits: u8, be: bool, packed: bool, planar: bool, float: bool, signed: bool) -> Self {
        Soniton {
            bits: bits,
            be: be,
            packed: packed,
            planar: planar,
            float: float,
            signed: signed,
        }
    }

    pub fn get_audio_size(&self, length: usize, alignment: usize) -> usize {
        let s = if self.packed {
            round_to_byte(length * (self.bits as usize))
        } else {
            length * round_to_byte(self.bits as usize)
        };

        align(s, alignment)
    }
}

impl fmt::Display for Soniton {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let fmt = if self.float {
            "float"
        } else if self.signed {
            "int"
        } else {
            "uint"
        };
        let end = if self.be {
            "BE"
        } else {
            "LE"
        };
        write!(f,
               "({} bps, {} planar: {} packed: {} {})",
               self.bits,
               end,
               self.packed,
               self.planar,
               fmt)
    }
}

#[derive(Debug,Clone,Copy,PartialEq)]
pub enum ChannelType {
    C,
    L,
    R,
    Cs,
    Ls,
    Rs,
    Lss,
    Rss,
    LFE,
    Lc,
    Rc,
    Lh,
    Rh,
    Ch,
    LFE2,
    Lw,
    Rw,
    Ov,
    Lhs,
    Rhs,
    Chs,
    Ll,
    Rl,
    Cl,
    Lt,
    Rt,
    Lo,
    Ro,
}

impl ChannelType {
    pub fn is_center(&self) -> bool {
        match *self {
            ChannelType::C => true,
            ChannelType::Ch => true,
            ChannelType::Cl => true,
            ChannelType::Ov => true,
            ChannelType::LFE => true,
            ChannelType::LFE2 => true,
            ChannelType::Cs => true,
            ChannelType::Chs => true,
            _ => false,
        }
    }
    pub fn is_left(&self) -> bool {
        match *self {
            ChannelType::L => true,
            ChannelType::Ls => true,
            ChannelType::Lss => true,
            ChannelType::Lc => true,
            ChannelType::Lh => true,
            ChannelType::Lw => true,
            ChannelType::Lhs => true,
            ChannelType::Ll => true,
            ChannelType::Lt => true,
            ChannelType::Lo => true,
            _ => false,
        }
    }
    pub fn is_right(&self) -> bool {
        match *self {
            ChannelType::R => true,
            ChannelType::Rs => true,
            ChannelType::Rss => true,
            ChannelType::Rc => true,
            ChannelType::Rh => true,
            ChannelType::Rw => true,
            ChannelType::Rhs => true,
            ChannelType::Rl => true,
            ChannelType::Rt => true,
            ChannelType::Ro => true,
            _ => false,
        }
    }
}

impl fmt::Display for ChannelType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let name = match *self {
            ChannelType::C => "C".to_string(),
            ChannelType::L => "L".to_string(),
            ChannelType::R => "R".to_string(),
            ChannelType::Cs => "Cs".to_string(),
            ChannelType::Ls => "Ls".to_string(),
            ChannelType::Rs => "Rs".to_string(),
            ChannelType::Lss => "Lss".to_string(),
            ChannelType::Rss => "Rss".to_string(),
            ChannelType::LFE => "LFE".to_string(),
            ChannelType::Lc => "Lc".to_string(),
            ChannelType::Rc => "Rc".to_string(),
            ChannelType::Lh => "Lh".to_string(),
            ChannelType::Rh => "Rh".to_string(),
            ChannelType::Ch => "Ch".to_string(),
            ChannelType::LFE2 => "LFE2".to_string(),
            ChannelType::Lw => "Lw".to_string(),
            ChannelType::Rw => "Rw".to_string(),
            ChannelType::Ov => "Ov".to_string(),
            ChannelType::Lhs => "Lhs".to_string(),
            ChannelType::Rhs => "Rhs".to_string(),
            ChannelType::Chs => "Chs".to_string(),
            ChannelType::Ll => "Ll".to_string(),
            ChannelType::Rl => "Rl".to_string(),
            ChannelType::Cl => "Cl".to_string(),
            ChannelType::Lt => "Lt".to_string(),
            ChannelType::Rt => "Rt".to_string(),
            ChannelType::Lo => "Lo".to_string(),
            ChannelType::Ro => "Ro".to_string(),
        };
        write!(f, "{}", name)
    }
}

#[derive(Clone,Debug,PartialEq)]
pub struct ChannelMap {
    ids: Vec<ChannelType>,
}

impl ChannelMap {
    pub fn new() -> Self {
        ChannelMap { ids: Vec::new() }
    }
    pub fn add_channel(&mut self, ch: ChannelType) {
        self.ids.push(ch);
    }
    pub fn add_channels(&mut self, chs: &[ChannelType]) {
        for i in 0..chs.len() {
            self.ids.push(chs[i]);
        }
    }
    pub fn len(&self) -> usize {
        self.ids.len()
    }
    pub fn get_channel(&self, idx: usize) -> ChannelType {
        self.ids[idx]
    }
    pub fn find_channel_id(&self, t: ChannelType) -> Option<u8> {
        for i in 0..self.ids.len() {
            if self.ids[i] as i32 == t as i32 {
                return Some(i as u8);
            }
        }
        None
    }
    pub fn default_map(count: usize) -> Self {
        use self::ChannelType::*;
        let ids = match count {
            1 => vec![C],
            2 => vec![R, L],
            _ => unimplemented!()
        };

        ChannelMap { ids }
    }
}

pub mod formats {
    use super::*;

    pub const U8: Soniton = Soniton {
        bits: 8,
        be: false,
        packed: false,
        planar: false,
        float: false,
        signed: false,
    };
    pub const S16: Soniton = Soniton {
        bits: 16,
        be: false,
        packed: false,
        planar: false,
        float: false,
        signed: true,
    };
    pub const F32: Soniton = Soniton {
        bits: 32,
        be: false,
        packed: false,
        planar: false,
        float: true,
        signed: true,
    };
}

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

    #[test]
    fn fmt() {
        println!("{}", formats::S16);
        println!("{}", formats::U8);
        println!("{}", formats::F32);
    }
}
<|endoftext|>


<commit_before>use std::cmp::min;
use std::fmt;
use std::fs::File;
use std::io::prelude::*;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;

fn get_input() -> std::io::Result<String> {
    let mut file = File::open("07.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;

    Ok(contents)
}

type Graph<T> = HashMap<T, HashSet<T>>;

struct Timetable<'a, T: 'a>
where T: Hash + Eq {
    durations: &'a HashMap<T, usize>,
    by_time: HashMap<usize, HashMap<usize, T>>,
    stop_times: HashMap<T, usize>
}

impl<'a, T: 'a> Timetable<'a, T>
where T: Hash + Eq + Copy {
    fn new(durations: &HashMap<T, usize>) -> Timetable<T> {
        Timetable {
            durations,
            by_time: HashMap::new(),
            stop_times: HashMap::new()
        }
    }

    fn allocate(&mut self, job: T, worker: usize, time: usize) {
        let duration = self.durations.get(&job).cloned().unwrap_or(1);

        if self.stop_times.contains_key(&job) {
            return;
        }

        for t in time..time + duration {
            if !self.by_time.contains_key(&t) {
                self.by_time.insert(t, HashMap::new());
            }

            let worker_data = self.by_time.get_mut(&t).unwrap();
            worker_data.insert(worker, job);
        }

        self.stop_times.insert(job, time + duration);
    }
}

impl<'a> fmt::Debug for Timetable<'a, char> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "Timetable {{")?;

        for t in 0..self.by_time.keys().cloned().max().unwrap_or(0) + 1 {
            write!(f, "  ({:4}) ", t)?;

            if let Some(worker_data) = self.by_time.get(&t) {
                for id in 0..worker_data.keys().cloned().max().unwrap_or(0) + 1 {
                    write!(f, "{:?} ", worker_data.get(&id).cloned().unwrap_or(' '))?;
                }
            }

            writeln!(f, "")?;
        }

        write!(f, "}}")?;
        Ok(())
    }
}

fn parse_input(input: &str) -> Graph<char> {
    fn first_char(x: &str) -> Option<char> {
        x.chars().next()
    }

    input.lines()
    .map(|line| line.split(' '))
    .filter_map(|mut tokens| {
        tokens.nth(1).and_then(first_char)
        .and_then(|x| tokens.nth(5).and_then(first_char).map(|y| (x, y)))
    })
    .fold(Graph::new(), |mut graph, (x, y)| {
        if !graph.contains_key(&x) {
            graph.insert(x, HashSet::new());
        }

        let mut children = graph.remove(&x).unwrap();
        children.insert(y);

        for &child in children.iter() {
            if !graph.contains_key(&child) {
                graph.insert(child, HashSet::new());
            }
        }

        graph.insert(x, children);
        graph
    })
}

fn get_root_nodes<T>(graph: &Graph<T>) -> Vec<T>
where T: Eq + Hash + Copy {
    graph.keys()
    .cloned()
    .filter(|&k| {
        graph.values()
        .flat_map(|children| children.iter())
        .all(|&child| child != k)
    })
    .collect()
}

fn get_order<T>(mut graph: Graph<T>) -> Vec<T>
where T: Eq + Hash + Copy + Ord {
    let mut result = vec![];
    let mut root_nodes;

    loop {
        root_nodes = get_root_nodes(&graph);
        root_nodes.sort();

        if root_nodes.len() == 0 {
            break;
        }

        let node = root_nodes.remove(0);

        graph.remove(&node);
        result.push(node);
    }

    result
}

fn create_timetable<T>(mut graph: Graph<T>, durations: &HashMap<T, usize>, workers: usize) -> Timetable<T>
where T: Eq + Hash + Copy + Ord {
    let mut result = Timetable::new(durations);
    let mut root_nodes;
    let mut busy = vec![];
    let mut t = 0;

    loop {
        // Wait for free workers

        loop {
            if !result.by_time.contains_key(&t) {
                result.by_time.insert(t, HashMap::new());
            }

            let busy_workers_count = result.by_time.get(&t).unwrap().keys().count();

            if busy_workers_count >= workers {
                t += 1;
            } else {
                break;
            }
        }

        // Remove jobs that have stopped

        let stopped: Vec<T> = busy.iter().cloned()
            .filter(|&job| result.stop_times.get(&job).cloned().unwrap() <= t)
            .collect();

        for node in stopped.iter() {
            graph.remove(node);
        }

        busy.retain(|job| !stopped.contains(job));

        // Get available jobs

        root_nodes = get_root_nodes(&graph);
        root_nodes.retain(|job| !busy.contains(job));
        root_nodes.sort();

        if root_nodes.len() == 0 {
            if busy.len() == 0 {
                break;
            } else {
                t += 1;
                continue;
            }
        }

        // Allocate jobs

        let free_workers: Vec<usize> = {
            let worker_data = result.by_time.get(&t).unwrap();

            (0..workers)
            .filter(|id| !worker_data.contains_key(id))
            .collect()
        };

        let new_job_count = min(free_workers.len(), root_nodes.len());
        let new_jobs: Vec<T> = root_nodes.iter().cloned().take(new_job_count).collect();

        for (job, worker) in new_jobs.iter().cloned().zip(free_workers.iter().cloned()) {
            result.allocate(job, worker, t);
            busy.push(job);
        }
    }

    result
}

fn main() {
    let input = get_input().unwrap();
    let graph = parse_input(&input);
    let order = get_order(graph.clone());

    println!("Part 1: {}", order.into_iter().fold(String::new(), |mut acc, x| {
        acc.push(x);
        acc
    }));

    let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let durations = alphabet.chars()
        .enumerate()
        .fold(HashMap::new(), |mut acc, (i, c)| {
            acc.insert(c, i + 61);
            acc
        });
    let timetable = create_timetable(graph, &durations, 5);

    println!("Part 2: {}", timetable.by_time.keys().cloned().max().unwrap_or(0));
}
<commit_msg>Simplify code<commit_after>use std::fmt;
use std::fs::File;
use std::io::prelude::*;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;

fn get_input() -> std::io::Result<String> {
    let mut file = File::open("07.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;

    Ok(contents)
}

type Graph<T> = HashMap<T, HashSet<T>>;

struct Timetable<'a, T: 'a>
where T: Hash + Eq {
    durations: &'a HashMap<T, usize>,
    by_time: HashMap<usize, HashMap<usize, T>>,
    stop_times: HashMap<T, usize>
}

impl<'a, T: 'a> Timetable<'a, T>
where T: Hash + Eq + Copy {
    fn new(durations: &HashMap<T, usize>) -> Timetable<T> {
        Timetable {
            durations,
            by_time: HashMap::new(),
            stop_times: HashMap::new()
        }
    }

    fn allocate(&mut self, job: T, worker: usize, time: usize) {
        let duration = self.durations.get(&job).cloned().unwrap_or(1);

        if self.stop_times.contains_key(&job) {
            return;
        }

        for t in time..time + duration {
            if !self.by_time.contains_key(&t) {
                self.by_time.insert(t, HashMap::new());
            }

            let worker_data = self.by_time.get_mut(&t).unwrap();
            worker_data.insert(worker, job);
        }

        self.stop_times.insert(job, time + duration);
    }
}

impl<'a> fmt::Debug for Timetable<'a, char> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "Timetable {{")?;

        for t in 0..self.by_time.keys().cloned().max().unwrap_or(0) + 1 {
            write!(f, "  ({:4}) ", t)?;

            if let Some(worker_data) = self.by_time.get(&t) {
                for id in 0..worker_data.keys().cloned().max().unwrap_or(0) + 1 {
                    write!(f, "{:?} ", worker_data.get(&id).cloned().unwrap_or(' '))?;
                }
            }

            writeln!(f, "")?;
        }

        write!(f, "}}")?;
        Ok(())
    }
}

fn parse_input(input: &str) -> Graph<char> {
    fn first_char(x: &str) -> Option<char> {
        x.chars().next()
    }

    input.lines()
    .map(|line| line.split(' '))
    .filter_map(|mut tokens| {
        tokens.nth(1).and_then(first_char)
        .and_then(|x| tokens.nth(5).and_then(first_char).map(|y| (x, y)))
    })
    .fold(Graph::new(), |mut graph, (x, y)| {
        if !graph.contains_key(&x) {
            graph.insert(x, HashSet::new());
        }

        let mut children = graph.remove(&x).unwrap();
        children.insert(y);

        for &child in children.iter() {
            if !graph.contains_key(&child) {
                graph.insert(child, HashSet::new());
            }
        }

        graph.insert(x, children);
        graph
    })
}

fn get_root_nodes<T>(graph: &Graph<T>) -> Vec<T>
where T: Eq + Hash + Copy {
    graph.keys()
    .cloned()
    .filter(|&k| {
        graph.values()
        .flat_map(|children| children.iter())
        .all(|&child| child != k)
    })
    .collect()
}

fn get_order<T>(mut graph: Graph<T>) -> Vec<T>
where T: Eq + Hash + Copy + Ord {
    let mut result = vec![];
    let mut root_nodes;

    loop {
        root_nodes = get_root_nodes(&graph);
        root_nodes.sort();

        if root_nodes.len() == 0 {
            break;
        }

        let node = root_nodes.remove(0);

        graph.remove(&node);
        result.push(node);
    }

    result
}

fn create_timetable<T>(mut graph: Graph<T>, durations: &HashMap<T, usize>, workers: usize) -> Timetable<T>
where T: Eq + Hash + Copy + Ord {
    let mut result = Timetable::new(durations);
    let mut root_nodes;
    let mut busy = vec![];
    let mut t = 0;

    loop {
        if !result.by_time.contains_key(&t) {
            result.by_time.insert(t, HashMap::new());
        }

        // Remove jobs that have stopped

        let stopped: Vec<T> = busy.iter().cloned()
            .filter(|&job| result.stop_times.get(&job).cloned().unwrap() <= t)
            .collect();

        for node in stopped.iter() {
            graph.remove(node);
        }

        busy.retain(|job| !stopped.contains(job));

        // Get available jobs

        root_nodes = get_root_nodes(&graph);
        root_nodes.retain(|job| !busy.contains(job));
        root_nodes.sort();

        if root_nodes.len() == 0 {
            if busy.len() == 0 {
                break;
            } else {
                t += 1;
                continue;
            }
        }

        // Allocate jobs

        let free_workers: Vec<usize> = {
            let worker_data = result.by_time.get(&t).unwrap();

            (0..workers)
            .filter(|id| !worker_data.contains_key(id))
            .collect()
        };

        for (job, worker) in root_nodes.iter().cloned().zip(free_workers.iter().cloned()) {
            result.allocate(job, worker, t);
            busy.push(job);
        }
    }

    result
}

fn main() {
    let input = get_input().unwrap();
    let graph = parse_input(&input);
    let order = get_order(graph.clone());

    println!("Part 1: {}", order.into_iter().fold(String::new(), |mut acc, x| {
        acc.push(x);
        acc
    }));

    let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let durations = alphabet.chars()
        .enumerate()
        .fold(HashMap::new(), |mut acc, (i, c)| {
            acc.insert(c, i + 61);
            acc
        });
    let timetable = create_timetable(graph, &durations, 5);

    println!("Part 2: {}", timetable.by_time.keys().cloned().max().unwrap_or(0));
}
<|endoftext|>