<commit_before>use error::Error;
use ng::graph::{Dependency, Edge, Graph, Hierarchy, Module, Visibility, GLOB};

pub fn print(graph: &Graph, include_orphans: bool) -> Result<(), Error> {
    let indent_str: &str = "    ";
    let root_node: Module = find_root_module(&graph)?;

    println!("digraph {{\n{}label=\"{}\";", indent_str, root_node.name());

    println!("{}// Modules", indent_str);
    for module in graph.nodes().filter(|m| {
        // All modules if include_orhans is true,
        // else only non-orphaned modules.
        include_orphans || !m.is_orphan()
    }) {
        print!("{}", indent_str);
        print_node(module);
    }
    print!("\n");

    println!("{}// Hierarchy", indent_str);
    for (from, to, edge) in graph.all_edges() {
        format_hierarchy(from, to, edge).map(|s| println!("{}{}", indent_str, s));
    }
    print!("\n");

    println!("{}// Dependencies", indent_str);
    for (from, to, edge) in graph.all_edges() {
        format_dependency(from, to, edge).map(|s| println!("{}{}", indent_str, s));
    }
    print!("\n");

    println!("}}");
    Ok(())
}

fn find_root_module(graph: &Graph) -> Result<Module, Error> {
    let mut nodes = graph.nodes().filter(Module::is_root);
    match (nodes.next(), nodes.count()) {
        (None, _) => Err(Error::Graph("No root module found.".to_owned())),
        (Some(module), 0) => Ok(module),
        (Some(_), _) => Err(Error::Graph("There are multiple root modules.".to_owned())),
    }
}

fn format_dependency(from: Module, to: Module, edge: &Edge) -> Option<String> {
    if edge.dependency.is_empty() {
        None
    } else {
        match &edge.dependency {
            Dependency {
                refers_to_all,
                refers_to_mod,
                referred_members,
            } => {
                let color: &str = "darkviolet";
                // TODO: Set the overall font size manually as well, instead
                //       of relying on the default value.
                let font_size: u8 = 10;

                let mut label_parts: Vec<String> = Vec::new();
                if *refers_to_mod {
                    label_parts.push("self".to_owned());
                }
                if *refers_to_all {
                    label_parts.push(GLOB.to_owned());
                }
                let mut sorted_members = referred_members.iter().cloned().collect::<Vec<_>>();
                for member in sorted_members.drain(..) {
                    label_parts.push(member);
                }

                Some(format!(
                    "\"{}\" -> \"{}\" [weight=90, color={}, label=<{}>]",
                    from.path(),
                    to.path(),
                    color,
                    font_size,
                    color,
                    label_parts.join(", ")
                ))
            }
        }
    }
}

fn format_hierarchy(from: Module, to: Module, edge: &Edge) -> Option<String> {
    (match edge.hierarchy {
        Hierarchy::Child => Some("[weight=100, color=azure4]"),
        Hierarchy::Orphan => Some("[weight=50, color=azure2]"),
        Hierarchy::None => None,
    })
    .map(|edge_style| format!("\"{}\" -> \"{}\" {}", from.path(), to.path(), edge_style))
}

fn print_node(module: Module) {
    let node_color: &str = match module.visibility() {
        Some(Visibility::Public) => "green",
        Some(Visibility::Private) => "gold",
        None => "red", // Module is orphaned
    };
    println!(
        "\"{}\" [label=\"{}\", color={}]",
        module.path(),
        module.name(),
        node_color
    );
}
<commit_msg>Change some graph settings to make it more readable<commit_after>use error::Error;
use ng::graph::{Dependency, Edge, Graph, Hierarchy, Module, Visibility, GLOB};

pub fn print(graph: &Graph, include_orphans: bool) -> Result<(), Error> {
    let indent_str: &str = "    ";
    let root_node: Module = find_root_module(&graph)?;

    println!(
        "digraph {{\n{}label=\"{}\";\npad=0.4;",
        indent_str,
        root_node.name()
    );

    println!("{}// Modules", indent_str);
    for module in graph.nodes().filter(|m| {
        // All modules if include_orhans is true,
        // else only non-orphaned modules.
        include_orphans || !m.is_orphan()
    }) {
        print!("{}", indent_str);
        print_node(module);
    }
    print!("\n");

    println!("{}// Hierarchy", indent_str);
    for (from, to, edge) in graph.all_edges() {
        format_hierarchy(from, to, edge).map(|s| println!("{}{}", indent_str, s));
    }
    print!("\n");

    println!("{}// Dependencies", indent_str);
    for (from, to, edge) in graph.all_edges() {
        format_dependency(from, to, edge).map(|s| println!("{}{}", indent_str, s));
    }
    print!("\n");

    println!("}}");
    Ok(())
}

fn find_root_module(graph: &Graph) -> Result<Module, Error> {
    let mut nodes = graph.nodes().filter(Module::is_root);
    match (nodes.next(), nodes.count()) {
        (None, _) => Err(Error::Graph("No root module found.".to_owned())),
        (Some(module), 0) => Ok(module),
        (Some(_), _) => Err(Error::Graph("There are multiple root modules.".to_owned())),
    }
}

fn format_dependency(from: Module, to: Module, edge: &Edge) -> Option<String> {
    if edge.dependency.is_empty() {
        None
    } else {
        match &edge.dependency {
            Dependency {
                refers_to_all,
                refers_to_mod,
                referred_members,
            } => {
                let color: &str = "azure3";
                // TODO: Set the overall font size manually as well, instead
                //       of relying on the default value.
                let font_size: u8 = 10;

                let mut label_parts: Vec<String> = Vec::new();
                if *refers_to_mod {
                    label_parts.push("self".to_owned());
                }
                if *refers_to_all {
                    label_parts.push(GLOB.to_owned());
                }
                let mut sorted_members = referred_members.iter().cloned().collect::<Vec<_>>();
                for member in sorted_members.drain(..) {
                    label_parts.push(member);
                }

                Some(format!(
                    "\"{}\" -> \"{}\" [weight=90, color={}, penwidth=2, label=<use {}>]",
                    from.path(),
                    to.path(),
                    color,
                    font_size,
                    color,
                    label_parts.join(", ")
                ))
            }
        }
    }
}

fn format_hierarchy(from: Module, to: Module, edge: &Edge) -> Option<String> {
    (match edge.hierarchy {
        Hierarchy::Child => Some("[weight=100, color=azure4, penwidth=3]"),
        Hierarchy::Orphan => Some("[weight=50, color=firebrick4, penwidth=1]"),
        Hierarchy::None => None,
    })
    .map(|edge_style| format!("\"{}\" -> \"{}\" {}", from.path(), to.path(), edge_style))
}

fn print_node(module: Module) {
    let (color, fillcolor): (&str, &str) = match module.visibility() {
        Some(Visibility::Public) => ("green4", "greenyellow"),
        Some(Visibility::Private) => ("darkgoldenrod", "khaki1"),
        None => ("firebrick4", "rosybrown1"), // Module is orphaned
    };
    println!(
        "\"{}\" [label=\"{}\", color={}, fontcolor={} style=filled, fillcolor={}]",
        module.path(),
        module.name(),
        color,
        color,
        fillcolor
    );
}
<|endoftext|>


<commit_before>//! Support for creating futures that represent intervals.
//!
//! This module contains the `Interval` type which is a stream that will
//! resolve at a fixed intervals in future

use std::io;
use std::time::{Duration, Instant};

use futures::{Poll, Async};
use futures::stream::{Stream};

use reactor::{Remote, Handle};
use reactor::timeout_token::TimeoutToken;

/// A stream representing notifications at fixed interval
///
/// Intervals are created through the `Interval::new` or
/// `Interval::new_at` methods indicating when a first notification
/// should be triggered and when it will be repeated.
///
/// Note that timeouts are not intended for high resolution timers, but rather
/// they will likely fire some granularity after the exact instant that they're
/// otherwise indicated to fire at.
pub struct Interval {
    token: TimeoutToken,
    next: Instant,
    interval: Duration,
    handle: Remote,
}

impl Interval {
    /// Creates a new interval which will fire at `dur` time into the future,
    /// and will repeat every `dur` interval after
    ///
    /// This function will return a future that will resolve to the actual
    /// interval object. The interval object itself is then a stream which will
    /// be set to fire at the specified intervals
    pub fn new(dur: Duration, handle: &Handle) -> io::Result<Interval> {
        Interval::new_at(Instant::now() + dur, dur, handle)
    }

    /// Creates a new interval which will fire at the time specified by `at`,
    /// and then will repeat every `dur` interval after
    ///
    /// This function will return a future that will resolve to the actual
    /// timeout object. The timeout object itself is then a future which will be
    /// set to fire at the specified point in the future.
    pub fn new_at(at: Instant, dur: Duration, handle: &Handle)
        -> io::Result<Interval>
    {
        Ok(Interval {
            token: try!(TimeoutToken::new(at, &handle)),
            next: at,
            interval: dur,
            handle: handle.remote().clone(),
        })
    }
}

impl Stream for Interval {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<()>, io::Error> {
        // TODO: is this fast enough?
        let now = Instant::now();
        if self.next <= now {
            self.next = next_interval(self.next, now, self.interval);
            self.token.reset_timeout(self.next, &self.handle);
            Ok(Async::Ready(Some(())))
        } else {
            self.token.update_timeout(&self.handle);
            Ok(Async::NotReady)
        }
    }
}

impl Drop for Interval {
    fn drop(&mut self) {
        self.token.cancel_timeout(&self.handle);
    }
}

/// Converts Duration object to raw nanoseconds if possible
///
/// This is useful to divide intervals.
///
/// While technically for large duration it's impossible to represent any
/// duration as nanoseconds, the largest duration we can represent is about
/// 427_000 years. Large enough for any interval we would use or calculate in
/// tokio.
fn duration_to_nanos(dur: Duration) -> Option<u64> {
    dur.as_secs()
        .checked_mul(1_000_000_000)
        .and_then(|v| v.checked_add(dur.subsec_nanos() as u64))
}

fn next_interval(prev: Instant, now: Instant, interval: Duration) -> Instant {
    let new = prev + interval;
    if new > now {
        return new;
    } else {
        let spent_ns = duration_to_nanos(now.duration_since(prev))
            .expect("interval should be expired");
        let interval_ns = duration_to_nanos(interval)
            .expect("interval is less that 427 thousand years");
        let mult = spent_ns/interval_ns + 1;
        assert!(mult < (1 << 32),
            "can't skip more than 4 billion intervals of {:?} \
             (trying to skip {})", interval, mult);
        return prev + interval * (mult as u32);
    }
}

#[cfg(test)]
mod test {
    use std::time::{Instant, Duration};
    use super::next_interval;

    struct Timeline(Instant);

    impl Timeline {
        fn new() -> Timeline {
            Timeline(Instant::now())
        }
        fn at(&self, millis: u64) -> Instant {
            self.0 + Duration::from_millis(millis)
        }
        fn at_ns(&self, sec: u64, nanos: u32) -> Instant {
            self.0 + Duration::new(sec, nanos)
        }
    }

    fn dur(millis: u64) -> Duration {
        Duration::from_millis(millis)
    }

    #[test]
    fn norm_next() {
        let tm = Timeline::new();
        assert_eq!(next_interval(tm.at(1), tm.at(2), dur(10)), tm.at(11));
        assert_eq!(next_interval(tm.at(7777), tm.at(7788), dur(100)),
                                 tm.at(7877));
        assert_eq!(next_interval(tm.at(1), tm.at(1000), dur(2100)),
                                 tm.at(2101));
    }

    #[test]
    fn fast_forward() {
        let tm = Timeline::new();
        assert_eq!(next_interval(tm.at(1), tm.at(1000), dur(10)),
                                 tm.at(1001));
        assert_eq!(next_interval(tm.at(7777), tm.at(8888), dur(100)),
                                 tm.at(8977));
        assert_eq!(next_interval(tm.at(1), tm.at(10000), dur(2100)),
                                 tm.at(10501));
    }

    /// TODO: this test actually should be successful, but since we can't
    ///       multiply Duration on anything larger than u32 easily we decided
    ///       to allow it to fail for now
    #[test]
    #[should_panic(expected = "can't skip more than 4 billion intervals")]
    fn large_skip() {
        let tm = Timeline::new();
        assert_eq!(next_interval(
            tm.at_ns(0, 1), tm.at_ns(25, 0), Duration::new(0, 2)),
            tm.at_ns(25, 1));
    }

}
<commit_msg>Relax exact interval tests<commit_after>//! Support for creating futures that represent intervals.
//!
//! This module contains the `Interval` type which is a stream that will
//! resolve at a fixed intervals in future

use std::io;
use std::time::{Duration, Instant};

use futures::{Poll, Async};
use futures::stream::{Stream};

use reactor::{Remote, Handle};
use reactor::timeout_token::TimeoutToken;

/// A stream representing notifications at fixed interval
///
/// Intervals are created through the `Interval::new` or
/// `Interval::new_at` methods indicating when a first notification
/// should be triggered and when it will be repeated.
///
/// Note that timeouts are not intended for high resolution timers, but rather
/// they will likely fire some granularity after the exact instant that they're
/// otherwise indicated to fire at.
pub struct Interval {
    token: TimeoutToken,
    next: Instant,
    interval: Duration,
    handle: Remote,
}

impl Interval {
    /// Creates a new interval which will fire at `dur` time into the future,
    /// and will repeat every `dur` interval after
    ///
    /// This function will return a future that will resolve to the actual
    /// interval object. The interval object itself is then a stream which will
    /// be set to fire at the specified intervals
    pub fn new(dur: Duration, handle: &Handle) -> io::Result<Interval> {
        Interval::new_at(Instant::now() + dur, dur, handle)
    }

    /// Creates a new interval which will fire at the time specified by `at`,
    /// and then will repeat every `dur` interval after
    ///
    /// This function will return a future that will resolve to the actual
    /// timeout object. The timeout object itself is then a future which will be
    /// set to fire at the specified point in the future.
    pub fn new_at(at: Instant, dur: Duration, handle: &Handle)
        -> io::Result<Interval>
    {
        Ok(Interval {
            token: try!(TimeoutToken::new(at, &handle)),
            next: at,
            interval: dur,
            handle: handle.remote().clone(),
        })
    }
}

impl Stream for Interval {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<()>, io::Error> {
        // TODO: is this fast enough?
        let now = Instant::now();
        if self.next <= now {
            self.next = next_interval(self.next, now, self.interval);
            self.token.reset_timeout(self.next, &self.handle);
            Ok(Async::Ready(Some(())))
        } else {
            self.token.update_timeout(&self.handle);
            Ok(Async::NotReady)
        }
    }
}

impl Drop for Interval {
    fn drop(&mut self) {
        self.token.cancel_timeout(&self.handle);
    }
}

/// Converts Duration object to raw nanoseconds if possible
///
/// This is useful to divide intervals.
///
/// While technically for large duration it's impossible to represent any
/// duration as nanoseconds, the largest duration we can represent is about
/// 427_000 years. Large enough for any interval we would use or calculate in
/// tokio.
fn duration_to_nanos(dur: Duration) -> Option<u64> {
    dur.as_secs()
        .checked_mul(1_000_000_000)
        .and_then(|v| v.checked_add(dur.subsec_nanos() as u64))
}

fn next_interval(prev: Instant, now: Instant, interval: Duration) -> Instant {
    let new = prev + interval;
    if new > now {
        return new;
    } else {
        let spent_ns = duration_to_nanos(now.duration_since(prev))
            .expect("interval should be expired");
        let interval_ns = duration_to_nanos(interval)
            .expect("interval is less that 427 thousand years");
        let mult = spent_ns/interval_ns + 1;
        assert!(mult < (1 << 32),
            "can't skip more than 4 billion intervals of {:?} \
             (trying to skip {})", interval, mult);
        return prev + interval * (mult as u32);
    }
}

#[cfg(test)]
mod test {
    use std::time::{Instant, Duration};
    use super::next_interval;

    struct Timeline(Instant);

    impl Timeline {
        fn new() -> Timeline {
            Timeline(Instant::now())
        }
        fn at(&self, millis: u64) -> Instant {
            self.0 + Duration::from_millis(millis)
        }
        fn at_ns(&self, sec: u64, nanos: u32) -> Instant {
            self.0 + Duration::new(sec, nanos)
        }
    }

    fn dur(millis: u64) -> Duration {
        Duration::from_millis(millis)
    }

    // The math around Instant/Duration isn't 100% precise due to rounding
    // errors, see #249 for more info
    fn almost_eq(a: Instant, b: Instant) -> bool {
        if a == b {
            true
        } else if a > b {
            a - b < Duration::from_millis(1)
        } else {
            b - a < Duration::from_millis(1)
        }
    }

    #[test]
    fn norm_next() {
        let tm = Timeline::new();
        assert!(almost_eq(next_interval(tm.at(1), tm.at(2), dur(10)),
                                        tm.at(11)));
        assert!(almost_eq(next_interval(tm.at(7777), tm.at(7788), dur(100)),
                                        tm.at(7877)));
        assert!(almost_eq(next_interval(tm.at(1), tm.at(1000), dur(2100)),
                                        tm.at(2101)));
    }

    #[test]
    fn fast_forward() {
        let tm = Timeline::new();
        assert!(almost_eq(next_interval(tm.at(1), tm.at(1000), dur(10)),
                                        tm.at(1001)));
        assert!(almost_eq(next_interval(tm.at(7777), tm.at(8888), dur(100)),
                                        tm.at(8977)));
        assert!(almost_eq(next_interval(tm.at(1), tm.at(10000), dur(2100)),
                                        tm.at(10501)));
    }

    /// TODO: this test actually should be successful, but since we can't
    ///       multiply Duration on anything larger than u32 easily we decided
    ///       to allow it to fail for now
    #[test]
    #[should_panic(expected = "can't skip more than 4 billion intervals")]
    fn large_skip() {
        let tm = Timeline::new();
        assert_eq!(next_interval(
            tm.at_ns(0, 1), tm.at_ns(25, 0), Duration::new(0, 2)),
            tm.at_ns(25, 1));
    }

}
<|endoftext|>


<commit_before><commit_msg>Metadata Collection: Collecting direct emission applicabilities (324/455)<commit_after><|endoftext|>


<commit_before>fn main() {
    assert_eq!(6.0_f32*6.0_f32, 36.0_f32);
    assert_eq!(6.0_f64*6.0_f64, 36.0_f64);
    assert_eq!(-{5.0_f32}, -5.0_f32);
    assert!((5.0_f32/0.0).is_infinite());
    assert!((-5.0_f32).sqrt().is_nan());
    let x: u64 = unsafe { std::mem::transmute(42.0_f64) };
    let y: f64 = unsafe { std::mem::transmute(x) };
    assert_eq!(y, 42.0_f64);

    assert_eq!(5.0f32 as u32, 5);
    assert_eq!(5.0f32 as i32, 5);
    assert_eq!(-5.0f32 as i32, -5);

    assert_eq!((1.0 as f32).max(-1.0), 1.0);
    assert_eq!((1.0 as f32).min(-1.0), -1.0);
    assert_eq!(std::f32::NAN.min(9.0), 9.0);
    assert_eq!(std::f32::NAN.max(-9.0), -9.0);
    assert_eq!((9.0 as f32).min(std::f32::NAN), 9.0);
    assert_eq!((-9.0 as f32).max(std::f32::NAN), -9.0);

    assert_eq!((1.0 as f64).max(-1.0), 1.0);
    assert_eq!((1.0 as f64).min(-1.0), -1.0);
    assert_eq!(std::f64::NAN.min(9.0), 9.0);
    assert_eq!(std::f64::NAN.max(-9.0), -9.0);
    assert_eq!((9.0 as f64).min(std::f64::NAN), 9.0);
    assert_eq!((-9.0 as f64).max(std::f64::NAN), -9.0);

    assert_eq!(3.5_f32.copysign(0.42), 3.5_f32);
    assert_eq!(3.5_f32.copysign(-0.42), -3.5_f32);
    assert_eq!((-3.5_f32).copysign(0.42), 3.5_f32);
    assert_eq!((-3.5_f32).copysign(-0.42), -3.5_f32);
    assert!(std::f32::NAN.copysign(1.0).is_nan());

    assert_eq!(3.5_f64.copysign(0.42), 3.5_f64);
    assert_eq!(3.5_f64.copysign(-0.42), -3.5_f64);
    assert_eq!((-3.5_f64).copysign(0.42), 3.5_f64);
    assert_eq!((-3.5_f64).copysign(-0.42), -3.5_f64);
    assert!(std::f64::NAN.copysign(1.0).is_nan());
}
<commit_msg>Auto merge of #1265 - RalfJung:float-cast, r=RalfJung<commit_after>#![feature(track_caller)]
use std::fmt::Debug;

// Helper function to avoid promotion so that this tests "run-time" casts, not CTFE.
// Doesn't make a big difference when running this in Miri, but when running this in
// rustc (with -Zmir-opt-level=0) for comparison it means we use LLVM casts.
#[track_caller]
#[inline(never)]
fn assert_eq<T: PartialEq + Debug>(x: T, y: T) {
    assert_eq!(x, y);
}

fn main() {
    // basic arithmetic
    assert_eq(6.0_f32*6.0_f32, 36.0_f32);
    assert_eq(6.0_f64*6.0_f64, 36.0_f64);
    assert_eq(-{5.0_f32}, -5.0_f32);
    assert_eq(-{5.0_f64}, -5.0_f64);
    // infinities, NaN
    assert!((5.0_f32/0.0).is_infinite());
    assert!((5.0_f64/0.0).is_infinite());
    assert!((-5.0_f32).sqrt().is_nan());
    assert!((-5.0_f64).sqrt().is_nan());
    // byte-level transmute
    let x: u64 = unsafe { std::mem::transmute(42.0_f64) };
    let y: f64 = unsafe { std::mem::transmute(x) };
    assert_eq(y, 42.0_f64);
    let x: u32 = unsafe { std::mem::transmute(42.0_f32) };
    let y: f32 = unsafe { std::mem::transmute(x) };
    assert_eq(y, 42.0_f32);

    // f32-to-int casts
    assert_eq(5.0f32 as u32, 5);
    assert_eq(-5.0f32 as u32, 0);
    assert_eq(5.0f32 as i32, 5);
    assert_eq(-5.0f32 as i32, -5);
    assert_eq(std::f32::MAX as i32, i32::MAX);
    assert_eq(std::f32::INFINITY as i32, i32::MAX);
    assert_eq(std::f32::MAX as u32, u32::MAX);
    assert_eq(std::f32::INFINITY as u32, u32::MAX);
    assert_eq(std::f32::MIN as i32, i32::MIN);
    assert_eq(std::f32::NEG_INFINITY as i32, i32::MIN);
    assert_eq(std::f32::MIN as u32, 0);
    assert_eq(std::f32::NEG_INFINITY as u32, 0);
    assert_eq(std::f32::NAN as i32, 0);
    assert_eq(std::f32::NAN as u32, 0);
    assert_eq(u128::MAX as f32, std::f32::INFINITY);
    assert_eq((u32::MAX-127) as f32 as u32, u32::MAX); // rounding loss
    assert_eq((u32::MAX-128) as f32 as u32, u32::MAX-255); // rounding loss

    // f64-to-int casts
    assert_eq(5.0f64 as u64, 5);
    assert_eq(-5.0f64 as u64, 0);
    assert_eq(5.0f64 as i64, 5);
    assert_eq(-5.0f64 as i64, -5);
    assert_eq(std::f64::MAX as i64, i64::MAX);
    assert_eq(std::f64::INFINITY as i64, i64::MAX);
    assert_eq(std::f64::MAX as u64, u64::MAX);
    assert_eq(std::f64::INFINITY as u64, u64::MAX);
    assert_eq(std::f64::MIN as i64, i64::MIN);
    assert_eq(std::f64::NEG_INFINITY as i64, i64::MIN);
    assert_eq(std::f64::MIN as u64, 0);
    assert_eq(std::f64::NEG_INFINITY as u64, 0);
    assert_eq(std::f64::NAN as i64, 0);
    assert_eq(std::f64::NAN as u64, 0);
    assert_eq(u128::MAX as f64 as u128, u128::MAX);
    assert_eq((u64::MAX-1023) as f64 as u64, u64::MAX); // rounding loss
    assert_eq((u64::MAX-1024) as f64 as u64, u64::MAX-2047); // rounding loss

    // f32 <-> f64 casts
    assert_eq(5.0f64 as f32, 5.0f32);
    assert_eq(5.0f32 as f64, 5.0f64);
    assert_eq(std::f64::MAX as f32, std::f32::INFINITY);
    assert_eq(std::f64::MIN as f32, std::f32::NEG_INFINITY);
    assert_eq(std::f32::INFINITY as f64, std::f64::INFINITY);
    assert_eq(std::f32::NEG_INFINITY as f64, std::f64::NEG_INFINITY);

    // f32 min/max
    assert_eq((1.0 as f32).max(-1.0), 1.0);
    assert_eq((1.0 as f32).min(-1.0), -1.0);
    assert_eq(std::f32::NAN.min(9.0), 9.0);
    assert_eq(std::f32::NAN.max(-9.0), -9.0);
    assert_eq((9.0 as f32).min(std::f32::NAN), 9.0);
    assert_eq((-9.0 as f32).max(std::f32::NAN), -9.0);

    // f64 min/max
    assert_eq((1.0 as f64).max(-1.0), 1.0);
    assert_eq((1.0 as f64).min(-1.0), -1.0);
    assert_eq(std::f64::NAN.min(9.0), 9.0);
    assert_eq(std::f64::NAN.max(-9.0), -9.0);
    assert_eq((9.0 as f64).min(std::f64::NAN), 9.0);
    assert_eq((-9.0 as f64).max(std::f64::NAN), -9.0);

    // f32 copysign
    assert_eq(3.5_f32.copysign(0.42), 3.5_f32);
    assert_eq(3.5_f32.copysign(-0.42), -3.5_f32);
    assert_eq((-3.5_f32).copysign(0.42), 3.5_f32);
    assert_eq((-3.5_f32).copysign(-0.42), -3.5_f32);
    assert!(std::f32::NAN.copysign(1.0).is_nan());

    // f64 copysign
    assert_eq(3.5_f64.copysign(0.42), 3.5_f64);
    assert_eq(3.5_f64.copysign(-0.42), -3.5_f64);
    assert_eq((-3.5_f64).copysign(0.42), 3.5_f64);
    assert_eq((-3.5_f64).copysign(-0.42), -3.5_f64);
    assert!(std::f64::NAN.copysign(1.0).is_nan());
}
<|endoftext|>


<commit_before>pub mod buffer;
pub mod quad;

use error::RuntimeError;
use frame::GPUFrame;
use sys::utils::fn_ptr::NULL_PTR;

use super::ffi;

#[inline]
pub fn create_gpu_frame(
   width: u32, height: u32
) -> Result<Box<GPUFrame>, RuntimeError> {

   if ffi::has_gen_buffers() {
      create_buffer_frame(width, height)
   } else {
      create_quad_frame(width, height)
   }
}

#[inline]
fn create_buffer_frame(
   width: u32, height: u32
) -> Result<Box<GPUFrame>, RuntimeError> {

   match buffer::BufferFrame::new(width, height) {
      Ok(gpu_frame) => Ok(Box::new(gpu_frame)),
      Err(e) => Err(e)
   }
}

#[inline]
fn create_quad_frame(
   width: u32, height: u32
) -> Result<Box<GPUFrame>, RuntimeError> {

   match quad::QuadFrame::new(width, height) {
      Ok(gpu_frame) => Ok(Box::new(gpu_frame)),
      Err(e) => Err(e)
   }
}
<commit_msg>Unused import warning fixed<commit_after>pub mod buffer;
pub mod quad;

use error::RuntimeError;
use frame::GPUFrame;

use super::ffi;

#[inline]
pub fn create_gpu_frame(
   width: u32, height: u32
) -> Result<Box<GPUFrame>, RuntimeError> {

   if ffi::has_gen_buffers() {
      create_buffer_frame(width, height)
   } else {
      create_quad_frame(width, height)
   }
}

#[inline]
fn create_buffer_frame(
   width: u32, height: u32
) -> Result<Box<GPUFrame>, RuntimeError> {

   match buffer::BufferFrame::new(width, height) {
      Ok(gpu_frame) => Ok(Box::new(gpu_frame)),
      Err(e) => Err(e)
   }
}

#[inline]
fn create_quad_frame(
   width: u32, height: u32
) -> Result<Box<GPUFrame>, RuntimeError> {

   match quad::QuadFrame::new(width, height) {
      Ok(gpu_frame) => Ok(Box::new(gpu_frame)),
      Err(e) => Err(e)
   }
}
<|endoftext|>


<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Alexander Fomin <xander.fomin@ya.ru>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

/* Last synced with: sync (GNU coreutils) 8.13 */

extern crate libc;

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use std::path::Path;
use uucore::display::Quotable;

static EXIT_ERR: i32 = 1;

static ABOUT: &str = "Synchronize cached writes to persistent storage";
pub mod options {
    pub static FILE_SYSTEM: &str = "file-system";
    pub static DATA: &str = "data";
}

static ARG_FILES: &str = "files";

#[cfg(unix)]
mod platform {
    use super::libc;
    #[cfg(target_os = "linux")]
    use std::fs::File;
    #[cfg(target_os = "linux")]
    use std::os::unix::io::AsRawFd;

    pub unsafe fn do_sync() -> isize {
        libc::sync();
        0
    }

    #[cfg(target_os = "linux")]
    pub unsafe fn do_syncfs(files: Vec<String>) -> isize {
        for path in files {
            let f = File::open(&path).unwrap();
            let fd = f.as_raw_fd();
            libc::syscall(libc::SYS_syncfs, fd);
        }
        0
    }

    #[cfg(target_os = "linux")]
    pub unsafe fn do_fdatasync(files: Vec<String>) -> isize {
        for path in files {
            let f = File::open(&path).unwrap();
            let fd = f.as_raw_fd();
            libc::syscall(libc::SYS_fdatasync, fd);
        }
        0
    }
}

#[cfg(windows)]
mod platform {
    extern crate winapi;
    use self::winapi::shared::minwindef;
    use self::winapi::shared::winerror;
    use self::winapi::um::handleapi;
    use self::winapi::um::winbase;
    use self::winapi::um::winnt;
    use std::fs::OpenOptions;
    use std::mem;
    use std::os::windows::prelude::*;
    use std::path::Path;
    use uucore::wide::{FromWide, ToWide};

    unsafe fn flush_volume(name: &str) {
        let name_wide = name.to_wide_null();
        if winapi::um::fileapi::GetDriveTypeW(name_wide.as_ptr()) == winbase::DRIVE_FIXED {
            let sliced_name = &name[..name.len() - 1]; // eliminate trailing backslash
            match OpenOptions::new().write(true).open(sliced_name) {
                Ok(file) => {
                    if winapi::um::fileapi::FlushFileBuffers(file.as_raw_handle()) == 0 {
                        crash!(
                            winapi::um::errhandlingapi::GetLastError() as i32,
                            "failed to flush file buffer"
                        );
                    }
                }
                Err(e) => crash!(
                    e.raw_os_error().unwrap_or(1),
                    "failed to create volume handle"
                ),
            }
        }
    }

    unsafe fn find_first_volume() -> (String, winnt::HANDLE) {
        #[allow(deprecated)]
        let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized();
        let handle = winapi::um::fileapi::FindFirstVolumeW(
            name.as_mut_ptr(),
            name.len() as minwindef::DWORD,
        );
        if handle == handleapi::INVALID_HANDLE_VALUE {
            crash!(
                winapi::um::errhandlingapi::GetLastError() as i32,
                "failed to find first volume"
            );
        }
        (String::from_wide_null(&name), handle)
    }

    unsafe fn find_all_volumes() -> Vec<String> {
        let (first_volume, next_volume_handle) = find_first_volume();
        let mut volumes = vec![first_volume];
        loop {
            #[allow(deprecated)]
            let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized();
            if winapi::um::fileapi::FindNextVolumeW(
                next_volume_handle,
                name.as_mut_ptr(),
                name.len() as minwindef::DWORD,
            ) == 0
            {
                match winapi::um::errhandlingapi::GetLastError() {
                    winerror::ERROR_NO_MORE_FILES => {
                        winapi::um::fileapi::FindVolumeClose(next_volume_handle);
                        return volumes;
                    }
                    err => crash!(err as i32, "failed to find next volume"),
                }
            } else {
                volumes.push(String::from_wide_null(&name));
            }
        }
    }

    pub unsafe fn do_sync() -> isize {
        let volumes = find_all_volumes();
        for vol in &volumes {
            flush_volume(vol);
        }
        0
    }

    pub unsafe fn do_syncfs(files: Vec<String>) -> isize {
        for path in files {
            flush_volume(
                Path::new(&path)
                    .components()
                    .next()
                    .unwrap()
                    .as_os_str()
                    .to_str()
                    .unwrap(),
            );
        }
        0
    }
}

fn usage() -> String {
    format!("{0} [OPTION]... FILE...", uucore::execution_phrase())
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = usage();

    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let files: Vec<String> = matches
        .values_of(ARG_FILES)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();

    for f in &files {
        if !Path::new(&f).exists() {
            crash!(
                EXIT_ERR,
                "cannot stat {}: No such file or directory",
                f.quote()
            );
        }
    }

    #[allow(clippy::if_same_then_else)]
    if matches.is_present(options::FILE_SYSTEM) {
        #[cfg(any(target_os = "linux", target_os = "windows"))]
        syncfs(files);
    } else if matches.is_present(options::DATA) {
        #[cfg(target_os = "linux")]
        fdatasync(files);
    } else {
        sync();
    }
    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .arg(
            Arg::with_name(options::FILE_SYSTEM)
                .short("f")
                .long(options::FILE_SYSTEM)
                .conflicts_with(options::DATA)
                .help("sync the file systems that contain the files (Linux and Windows only)"),
        )
        .arg(
            Arg::with_name(options::DATA)
                .short("d")
                .long(options::DATA)
                .conflicts_with(options::FILE_SYSTEM)
                .help("sync only file data, no unneeded metadata (Linux only)"),
        )
        .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
}

fn sync() -> isize {
    unsafe { platform::do_sync() }
}

#[cfg(any(target_os = "linux", target_os = "windows"))]
fn syncfs(files: Vec<String>) -> isize {
    unsafe { platform::do_syncfs(files) }
}

#[cfg(target_os = "linux")]
fn fdatasync(files: Vec<String>) -> isize {
    unsafe { platform::do_fdatasync(files) }
}
<commit_msg>sync: return UResult from uumain() function<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Alexander Fomin <xander.fomin@ya.ru>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

/* Last synced with: sync (GNU coreutils) 8.13 */

extern crate libc;

use clap::{crate_version, App, Arg};
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError};

static ABOUT: &str = "Synchronize cached writes to persistent storage";
pub mod options {
    pub static FILE_SYSTEM: &str = "file-system";
    pub static DATA: &str = "data";
}

static ARG_FILES: &str = "files";

#[cfg(unix)]
mod platform {
    use super::libc;
    #[cfg(target_os = "linux")]
    use std::fs::File;
    #[cfg(target_os = "linux")]
    use std::os::unix::io::AsRawFd;

    pub unsafe fn do_sync() -> isize {
        libc::sync();
        0
    }

    #[cfg(target_os = "linux")]
    pub unsafe fn do_syncfs(files: Vec<String>) -> isize {
        for path in files {
            let f = File::open(&path).unwrap();
            let fd = f.as_raw_fd();
            libc::syscall(libc::SYS_syncfs, fd);
        }
        0
    }

    #[cfg(target_os = "linux")]
    pub unsafe fn do_fdatasync(files: Vec<String>) -> isize {
        for path in files {
            let f = File::open(&path).unwrap();
            let fd = f.as_raw_fd();
            libc::syscall(libc::SYS_fdatasync, fd);
        }
        0
    }
}

#[cfg(windows)]
mod platform {
    extern crate winapi;
    use self::winapi::shared::minwindef;
    use self::winapi::shared::winerror;
    use self::winapi::um::handleapi;
    use self::winapi::um::winbase;
    use self::winapi::um::winnt;
    use std::fs::OpenOptions;
    use std::mem;
    use std::os::windows::prelude::*;
    use std::path::Path;
    use uucore::wide::{FromWide, ToWide};

    unsafe fn flush_volume(name: &str) {
        let name_wide = name.to_wide_null();
        if winapi::um::fileapi::GetDriveTypeW(name_wide.as_ptr()) == winbase::DRIVE_FIXED {
            let sliced_name = &name[..name.len() - 1]; // eliminate trailing backslash
            match OpenOptions::new().write(true).open(sliced_name) {
                Ok(file) => {
                    if winapi::um::fileapi::FlushFileBuffers(file.as_raw_handle()) == 0 {
                        crash!(
                            winapi::um::errhandlingapi::GetLastError() as i32,
                            "failed to flush file buffer"
                        );
                    }
                }
                Err(e) => crash!(
                    e.raw_os_error().unwrap_or(1),
                    "failed to create volume handle"
                ),
            }
        }
    }

    unsafe fn find_first_volume() -> (String, winnt::HANDLE) {
        #[allow(deprecated)]
        let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized();
        let handle = winapi::um::fileapi::FindFirstVolumeW(
            name.as_mut_ptr(),
            name.len() as minwindef::DWORD,
        );
        if handle == handleapi::INVALID_HANDLE_VALUE {
            crash!(
                winapi::um::errhandlingapi::GetLastError() as i32,
                "failed to find first volume"
            );
        }
        (String::from_wide_null(&name), handle)
    }

    unsafe fn find_all_volumes() -> Vec<String> {
        let (first_volume, next_volume_handle) = find_first_volume();
        let mut volumes = vec![first_volume];
        loop {
            #[allow(deprecated)]
            let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized();
            if winapi::um::fileapi::FindNextVolumeW(
                next_volume_handle,
                name.as_mut_ptr(),
                name.len() as minwindef::DWORD,
            ) == 0
            {
                match winapi::um::errhandlingapi::GetLastError() {
                    winerror::ERROR_NO_MORE_FILES => {
                        winapi::um::fileapi::FindVolumeClose(next_volume_handle);
                        return volumes;
                    }
                    err => crash!(err as i32, "failed to find next volume"),
                }
            } else {
                volumes.push(String::from_wide_null(&name));
            }
        }
    }

    pub unsafe fn do_sync() -> isize {
        let volumes = find_all_volumes();
        for vol in &volumes {
            flush_volume(vol);
        }
        0
    }

    pub unsafe fn do_syncfs(files: Vec<String>) -> isize {
        for path in files {
            flush_volume(
                Path::new(&path)
                    .components()
                    .next()
                    .unwrap()
                    .as_os_str()
                    .to_str()
                    .unwrap(),
            );
        }
        0
    }
}

fn usage() -> String {
    format!("{0} [OPTION]... FILE...", uucore::execution_phrase())
}

#[uucore_procs::gen_uumain]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let usage = usage();

    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let files: Vec<String> = matches
        .values_of(ARG_FILES)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();

    for f in &files {
        if !Path::new(&f).exists() {
            return Err(USimpleError::new(
                1,
                format!("cannot stat {}: No such file or directory", f.quote()),
            ));
        }
    }

    #[allow(clippy::if_same_then_else)]
    if matches.is_present(options::FILE_SYSTEM) {
        #[cfg(any(target_os = "linux", target_os = "windows"))]
        syncfs(files);
    } else if matches.is_present(options::DATA) {
        #[cfg(target_os = "linux")]
        fdatasync(files);
    } else {
        sync();
    }
    Ok(())
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .arg(
            Arg::with_name(options::FILE_SYSTEM)
                .short("f")
                .long(options::FILE_SYSTEM)
                .conflicts_with(options::DATA)
                .help("sync the file systems that contain the files (Linux and Windows only)"),
        )
        .arg(
            Arg::with_name(options::DATA)
                .short("d")
                .long(options::DATA)
                .conflicts_with(options::FILE_SYSTEM)
                .help("sync only file data, no unneeded metadata (Linux only)"),
        )
        .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
}

fn sync() -> isize {
    unsafe { platform::do_sync() }
}

#[cfg(any(target_os = "linux", target_os = "windows"))]
fn syncfs(files: Vec<String>) -> isize {
    unsafe { platform::do_syncfs(files) }
}

#[cfg(target_os = "linux")]
fn fdatasync(files: Vec<String>) -> isize {
    unsafe { platform::do_fdatasync(files) }
}
<|endoftext|>


<commit_before>use super::Value;

impl PartialEq for Value {
    fn eq(&self, other: &Value) -> bool {
        match (self, other) {
            (&Value::Null, &Value::Null) => true,
            (&Value::Bool(a), &Value::Bool(b)) => a == b,
            (&Value::Number(ref a), &Value::Number(ref b)) => a == b,
            (&Value::String(ref a), &Value::String(ref b)) => a == b,
            (&Value::Sequence(ref a), &Value::Sequence(ref b)) => a == b,
            (&Value::Mapping(ref a), &Value::Mapping(ref b)) => a == b,
            _ => false,
        }
    }
}

impl PartialEq<str> for Value {
    /// Compare `str` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == *"lorem");
    /// ```
    fn eq(&self, other: &str) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl<'a> PartialEq<&'a str> for Value {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem");
    /// ```
    fn eq(&self, other: &&str) -> bool {
        self.as_str().map_or(false, |s| s == *other)
    }
}

impl PartialEq<Value> for str {
    /// Compare YAML value with `str`
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(*"lorem" == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

impl<'a> PartialEq<Value> for &'a str {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!("lorem" == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == *self)
    }
}

impl PartialEq<String> for Value {
    /// Compare YAML value with String
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem".to_string());
    /// ```
    fn eq(&self, other: &String) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl PartialEq<Value> for String {
    /// Compare `String` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!("lorem".to_string() == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

macro_rules! partialeq_numeric {
    ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
        $($(
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl PartialEq<Value> for $ty {
                fn eq(&self, other: &Value) -> bool {
                    other.$conversion().map_or(false, |i| i == (*self as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }
        )*)*
    }
}

partialeq_numeric! {
    [i8 i16 i32 i64 isize], as_i64, i64
    [u8 u16 u32 usize], as_i64, i64
    [f32 f64], as_f64, f64
}
<commit_msg>Value == bool<commit_after>use super::Value;

impl PartialEq for Value {
    fn eq(&self, other: &Value) -> bool {
        match (self, other) {
            (&Value::Null, &Value::Null) => true,
            (&Value::Bool(a), &Value::Bool(b)) => a == b,
            (&Value::Number(ref a), &Value::Number(ref b)) => a == b,
            (&Value::String(ref a), &Value::String(ref b)) => a == b,
            (&Value::Sequence(ref a), &Value::Sequence(ref b)) => a == b,
            (&Value::Mapping(ref a), &Value::Mapping(ref b)) => a == b,
            _ => false,
        }
    }
}

impl PartialEq<str> for Value {
    /// Compare `str` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == *"lorem");
    /// ```
    fn eq(&self, other: &str) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl<'a> PartialEq<&'a str> for Value {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem");
    /// ```
    fn eq(&self, other: &&str) -> bool {
        self.as_str().map_or(false, |s| s == *other)
    }
}

impl PartialEq<Value> for str {
    /// Compare YAML value with `str`
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(*"lorem" == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

impl<'a> PartialEq<Value> for &'a str {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!("lorem" == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == *self)
    }
}

impl PartialEq<String> for Value {
    /// Compare YAML value with String
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem".to_string());
    /// ```
    fn eq(&self, other: &String) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl PartialEq<Value> for String {
    /// Compare `String` with YAML value
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!("lorem".to_string() == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

impl PartialEq<bool> for Value {
    /// Compare YAML value with bool
    ///
    /// # Examples
    ///
    /// ```edition2018
    /// # use serde_yaml::Value;
    /// assert!(Value::Bool(true) == true);
    /// ```
    fn eq(&self, other: &bool) -> bool {
        self.as_bool().map_or(false, |b| b == *other)
    }
}

macro_rules! partialeq_numeric {
    ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
        $($(
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl PartialEq<Value> for $ty {
                fn eq(&self, other: &Value) -> bool {
                    other.$conversion().map_or(false, |i| i == (*self as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }
        )*)*
    }
}

partialeq_numeric! {
    [i8 i16 i32 i64 isize], as_i64, i64
    [u8 u16 u32 usize], as_i64, i64
    [f32 f64], as_f64, f64
}
<|endoftext|>


<commit_before>use std::convert::TryFrom;
use llvm_sys::core::{LLVMAddIncoming, LLVMCountIncoming, LLVMGetIncomingBlock, LLVMGetIncomingValue};
use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMValueRef};

use std::ffi::CStr;

use crate::basic_block::BasicBlock;
use crate::values::traits::AsValueRef;
use crate::values::{BasicValue, BasicValueEnum, InstructionOpcode, InstructionValue, Value};

// REVIEW: Metadata for phi values?
/// A Phi Instruction returns a value based on which basic block branched into
/// the Phi's containing basic block.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct PhiValue<'ctx> {
    phi_value: Value<'ctx>,
}

impl<'ctx> PhiValue<'ctx> {
    pub(crate) unsafe fn new(value: LLVMValueRef) -> Self {
        assert!(!value.is_null());

        PhiValue {
            phi_value: Value::new(value),
        }
    }

    pub fn add_incoming(self, incoming: &[(&dyn BasicValue<'ctx>, BasicBlock<'ctx>)]) {
        let (mut values, mut basic_blocks): (Vec<LLVMValueRef>, Vec<LLVMBasicBlockRef>) = {
            incoming.iter()
                    .map(|&(v, bb)| (v.as_value_ref(), bb.basic_block))
                    .unzip()
        };

        unsafe {
            LLVMAddIncoming(self.as_value_ref(), values.as_mut_ptr(), basic_blocks.as_mut_ptr(), incoming.len() as u32);
        }
    }

    pub fn count_incoming(self) -> u32 {
        unsafe {
            LLVMCountIncoming(self.as_value_ref())
        }
    }

    pub fn get_incoming(self, index: u32) -> Option<(BasicValueEnum<'ctx>, BasicBlock<'ctx>)> {
        if index >= self.count_incoming() {
            return None;
        }

        let basic_block = unsafe {
            BasicBlock::new(LLVMGetIncomingBlock(self.as_value_ref(), index)).expect("Invalid BasicBlock")
        };
        let value = unsafe {
            BasicValueEnum::new(LLVMGetIncomingValue(self.as_value_ref(), index))
        };

        Some((value, basic_block))
    }

    /// Gets the name of a `ArrayValue`. If the value is a constant, this will
    /// return an empty string.
    pub fn get_name(&self) -> &CStr {
        self.phi_value.get_name()
    }

    // I believe PhiValue is never a constant, so this should always work
    pub fn set_name(self, name: &str) {
        self.phi_value.set_name(name);
    }

    pub fn is_null(self) -> bool {
        self.phi_value.is_null()
    }

    pub fn is_undef(self) -> bool {
        self.phi_value.is_undef()
    }

    // SubType: -> InstructionValue<Phi>
    pub fn as_instruction(self) -> InstructionValue<'ctx> {
        self.phi_value.as_instruction().expect("PhiValue should always be a Phi InstructionValue")
    }

    pub fn replace_all_uses_with(self, other: &PhiValue<'ctx>) {
        self.phi_value.replace_all_uses_with(other.as_value_ref())
    }

    pub fn as_basic_value(self) -> BasicValueEnum<'ctx> {
        unsafe {
            BasicValueEnum::new(self.as_value_ref())
        }
    }
}

impl AsValueRef for PhiValue<'_> {
    fn as_value_ref(&self) -> LLVMValueRef {
        self.phi_value.value
    }
}

impl TryFrom<InstructionValue> for PhiValue {
    type Error = ();

    fn try_from(value: InstructionValue) -> Result<Self, Self::Error> {
        if value.get_opcode() == InstructionOpcode::Phi {
            unsafe {
                Ok(PhiValue::new(value.as_value_ref()))
            }
        } else {
            Err(())
        }
    }
}
<commit_msg>Add explicit anonymous lifetimes to `TryFrom` impl<commit_after>use std::convert::TryFrom;
use llvm_sys::core::{LLVMAddIncoming, LLVMCountIncoming, LLVMGetIncomingBlock, LLVMGetIncomingValue};
use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMValueRef};

use std::ffi::CStr;

use crate::basic_block::BasicBlock;
use crate::values::traits::AsValueRef;
use crate::values::{BasicValue, BasicValueEnum, InstructionOpcode, InstructionValue, Value};

// REVIEW: Metadata for phi values?
/// A Phi Instruction returns a value based on which basic block branched into
/// the Phi's containing basic block.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct PhiValue<'ctx> {
    phi_value: Value<'ctx>,
}

impl<'ctx> PhiValue<'ctx> {
    pub(crate) unsafe fn new(value: LLVMValueRef) -> Self {
        assert!(!value.is_null());

        PhiValue {
            phi_value: Value::new(value),
        }
    }

    pub fn add_incoming(self, incoming: &[(&dyn BasicValue<'ctx>, BasicBlock<'ctx>)]) {
        let (mut values, mut basic_blocks): (Vec<LLVMValueRef>, Vec<LLVMBasicBlockRef>) = {
            incoming.iter()
                    .map(|&(v, bb)| (v.as_value_ref(), bb.basic_block))
                    .unzip()
        };

        unsafe {
            LLVMAddIncoming(self.as_value_ref(), values.as_mut_ptr(), basic_blocks.as_mut_ptr(), incoming.len() as u32);
        }
    }

    pub fn count_incoming(self) -> u32 {
        unsafe {
            LLVMCountIncoming(self.as_value_ref())
        }
    }

    pub fn get_incoming(self, index: u32) -> Option<(BasicValueEnum<'ctx>, BasicBlock<'ctx>)> {
        if index >= self.count_incoming() {
            return None;
        }

        let basic_block = unsafe {
            BasicBlock::new(LLVMGetIncomingBlock(self.as_value_ref(), index)).expect("Invalid BasicBlock")
        };
        let value = unsafe {
            BasicValueEnum::new(LLVMGetIncomingValue(self.as_value_ref(), index))
        };

        Some((value, basic_block))
    }

    /// Gets the name of a `ArrayValue`. If the value is a constant, this will
    /// return an empty string.
    pub fn get_name(&self) -> &CStr {
        self.phi_value.get_name()
    }

    // I believe PhiValue is never a constant, so this should always work
    pub fn set_name(self, name: &str) {
        self.phi_value.set_name(name);
    }

    pub fn is_null(self) -> bool {
        self.phi_value.is_null()
    }

    pub fn is_undef(self) -> bool {
        self.phi_value.is_undef()
    }

    // SubType: -> InstructionValue<Phi>
    pub fn as_instruction(self) -> InstructionValue<'ctx> {
        self.phi_value.as_instruction().expect("PhiValue should always be a Phi InstructionValue")
    }

    pub fn replace_all_uses_with(self, other: &PhiValue<'ctx>) {
        self.phi_value.replace_all_uses_with(other.as_value_ref())
    }

    pub fn as_basic_value(self) -> BasicValueEnum<'ctx> {
        unsafe {
            BasicValueEnum::new(self.as_value_ref())
        }
    }
}

impl AsValueRef for PhiValue<'_> {
    fn as_value_ref(&self) -> LLVMValueRef {
        self.phi_value.value
    }
}

impl TryFrom<InstructionValue<'_>> for PhiValue<'_> {
    type Error = ();

    fn try_from(value: InstructionValue) -> Result<Self, Self::Error> {
        if value.get_opcode() == InstructionOpcode::Phi {
            unsafe {
                Ok(PhiValue::new(value.as_value_ref()))
            }
        } else {
            Err(())
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate cookie as cookie_rs;

use net::cookie::Cookie;
use net::cookie_storage::CookieStorage;
use net_traits::CookieSource;

#[test]
fn test_domain_match() {
    assert!(Cookie::domain_match("foo.com", "foo.com"));
    assert!(Cookie::domain_match("bar.foo.com", "foo.com"));
    assert!(Cookie::domain_match("baz.bar.foo.com", "foo.com"));

    assert!(!Cookie::domain_match("bar.foo.com", "bar.com"));
    assert!(!Cookie::domain_match("bar.com", "baz.bar.com"));
    assert!(!Cookie::domain_match("foo.com", "bar.com"));

    assert!(!Cookie::domain_match("bar.com", "bbar.com"));
    assert!(Cookie::domain_match("235.132.2.3", "235.132.2.3"));
    assert!(!Cookie::domain_match("235.132.2.3", "1.1.1.1"));
    assert!(!Cookie::domain_match("235.132.2.3", ".2.3"));
}

#[test]
fn test_default_path() {
    assert!(&*Cookie::default_path("/foo/bar/baz/") == "/foo/bar/baz");
    assert!(&*Cookie::default_path("/foo/bar/baz") == "/foo/bar");
    assert!(&*Cookie::default_path("/foo/") == "/foo");
    assert!(&*Cookie::default_path("/foo") == "/");
    assert!(&*Cookie::default_path("/") == "/");
    assert!(&*Cookie::default_path("") == "/");
    assert!(&*Cookie::default_path("foo") == "/");
}

#[test]
fn fn_cookie_constructor() {
    use net_traits::CookieSource;

    let url = &url!("http://example.com/foo");

    let gov_url = &url!("http://gov.ac/foo");
    // cookie name/value test
    assert!(cookie_rs::Cookie::parse(" baz ").is_err());
    assert!(cookie_rs::Cookie::parse(" = bar  ").is_err());
    assert!(cookie_rs::Cookie::parse(" baz = ").is_ok());

    // cookie domains test
    let cookie = cookie_rs::Cookie::parse(" baz = bar; Domain =  ").unwrap();
    assert!(Cookie::new_wrapped(cookie.clone(), url, CookieSource::HTTP).is_some());
    let cookie = Cookie::new_wrapped(cookie, url, CookieSource::HTTP).unwrap();
    assert!(&**cookie.cookie.domain.as_ref().unwrap() == "example.com");

    // cookie public domains test
    let cookie = cookie_rs::Cookie::parse(" baz = bar; Domain =  gov.ac").unwrap();
    assert!(Cookie::new_wrapped(cookie.clone(), url, CookieSource::HTTP).is_none());
    assert!(Cookie::new_wrapped(cookie, gov_url, CookieSource::HTTP).is_some());

    // cookie domain matching test
    let cookie = cookie_rs::Cookie::parse(" baz = bar ; Secure; Domain = bazample.com").unwrap();
    assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none());

    let cookie = cookie_rs::Cookie::parse(" baz = bar ; Secure; Path = /foo/bar/").unwrap();
    assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_some());

    let cookie = cookie_rs::Cookie::parse(" baz = bar ; HttpOnly").unwrap();
    assert!(Cookie::new_wrapped(cookie, url, CookieSource::NonHTTP).is_none());

    let cookie = cookie_rs::Cookie::parse(" baz = bar ; Secure; Path = /foo/bar/").unwrap();
    let cookie = Cookie::new_wrapped(cookie, url, CookieSource::HTTP).unwrap();
    assert!(cookie.cookie.value == "bar");
    assert!(cookie.cookie.name == "baz");
    assert!(cookie.cookie.secure);
    assert!(&cookie.cookie.path.as_ref().unwrap()[..] == "/foo/bar/");
    assert!(&cookie.cookie.domain.as_ref().unwrap()[..] == "example.com");
    assert!(cookie.host_only);

    let u = &url!("http://example.com/foobar");
    let cookie = cookie_rs::Cookie::parse("foobar=value;path=/").unwrap();
    assert!(Cookie::new_wrapped(cookie, u, CookieSource::HTTP).is_some());
}

#[test]
fn test_sort_order() {
    use std::cmp::Ordering;

    let url = &url!("http://example.com/foo");
    let a_wrapped = cookie_rs::Cookie::parse("baz=bar; Path=/foo/bar/").unwrap();
    let a = Cookie::new_wrapped(a_wrapped.clone(), url, CookieSource::HTTP).unwrap();
    let a_prime = Cookie::new_wrapped(a_wrapped, url, CookieSource::HTTP).unwrap();
    let b = cookie_rs::Cookie::parse("baz=bar;Path=/foo/bar/baz/").unwrap();
    let b = Cookie::new_wrapped(b, url, CookieSource::HTTP).unwrap();

    assert!(b.cookie.path.as_ref().unwrap().len() > a.cookie.path.as_ref().unwrap().len());
    assert!(CookieStorage::cookie_comparator(&a, &b) == Ordering::Greater);
    assert!(CookieStorage::cookie_comparator(&b, &a) == Ordering::Less);
    assert!(CookieStorage::cookie_comparator(&a, &a_prime) == Ordering::Less);
    assert!(CookieStorage::cookie_comparator(&a_prime, &a) == Ordering::Greater);
    assert!(CookieStorage::cookie_comparator(&a, &a) == Ordering::Equal);
}
<commit_msg>Add path_match tests<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate cookie as cookie_rs;

use net::cookie::Cookie;
use net::cookie_storage::CookieStorage;
use net_traits::CookieSource;

#[test]
fn test_domain_match() {
    assert!(Cookie::domain_match("foo.com", "foo.com"));
    assert!(Cookie::domain_match("bar.foo.com", "foo.com"));
    assert!(Cookie::domain_match("baz.bar.foo.com", "foo.com"));

    assert!(!Cookie::domain_match("bar.foo.com", "bar.com"));
    assert!(!Cookie::domain_match("bar.com", "baz.bar.com"));
    assert!(!Cookie::domain_match("foo.com", "bar.com"));

    assert!(!Cookie::domain_match("bar.com", "bbar.com"));
    assert!(Cookie::domain_match("235.132.2.3", "235.132.2.3"));
    assert!(!Cookie::domain_match("235.132.2.3", "1.1.1.1"));
    assert!(!Cookie::domain_match("235.132.2.3", ".2.3"));
}

#[test]
fn test_path_match() {
    assert!(Cookie::path_match("/", "/"));
    assert!(Cookie::path_match("/index.html", "/"));
    assert!(Cookie::path_match("/w/index.html", "/"));
    assert!(Cookie::path_match("/w/index.html", "/w/index.html"));
    assert!(Cookie::path_match("/w/index.html", "/w/"));
    assert!(Cookie::path_match("/w/index.html", "/w"));

    assert!(!Cookie::path_match("/", "/w/"));
    assert!(!Cookie::path_match("/a", "/w/"));
    assert!(!Cookie::path_match("/", "/w"));
    assert!(!Cookie::path_match("/w/index.html", "/w/index"));
    assert!(!Cookie::path_match("/windex.html", "/w/"));
    assert!(!Cookie::path_match("/windex.html", "/w"));
}

#[test]
fn test_default_path() {
    assert!(&*Cookie::default_path("/foo/bar/baz/") == "/foo/bar/baz");
    assert!(&*Cookie::default_path("/foo/bar/baz") == "/foo/bar");
    assert!(&*Cookie::default_path("/foo/") == "/foo");
    assert!(&*Cookie::default_path("/foo") == "/");
    assert!(&*Cookie::default_path("/") == "/");
    assert!(&*Cookie::default_path("") == "/");
    assert!(&*Cookie::default_path("foo") == "/");
}

#[test]
fn fn_cookie_constructor() {
    use net_traits::CookieSource;

    let url = &url!("http://example.com/foo");

    let gov_url = &url!("http://gov.ac/foo");
    // cookie name/value test
    assert!(cookie_rs::Cookie::parse(" baz ").is_err());
    assert!(cookie_rs::Cookie::parse(" = bar  ").is_err());
    assert!(cookie_rs::Cookie::parse(" baz = ").is_ok());

    // cookie domains test
    let cookie = cookie_rs::Cookie::parse(" baz = bar; Domain =  ").unwrap();
    assert!(Cookie::new_wrapped(cookie.clone(), url, CookieSource::HTTP).is_some());
    let cookie = Cookie::new_wrapped(cookie, url, CookieSource::HTTP).unwrap();
    assert!(&**cookie.cookie.domain.as_ref().unwrap() == "example.com");

    // cookie public domains test
    let cookie = cookie_rs::Cookie::parse(" baz = bar; Domain =  gov.ac").unwrap();
    assert!(Cookie::new_wrapped(cookie.clone(), url, CookieSource::HTTP).is_none());
    assert!(Cookie::new_wrapped(cookie, gov_url, CookieSource::HTTP).is_some());

    // cookie domain matching test
    let cookie = cookie_rs::Cookie::parse(" baz = bar ; Secure; Domain = bazample.com").unwrap();
    assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none());

    let cookie = cookie_rs::Cookie::parse(" baz = bar ; Secure; Path = /foo/bar/").unwrap();
    assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_some());

    let cookie = cookie_rs::Cookie::parse(" baz = bar ; HttpOnly").unwrap();
    assert!(Cookie::new_wrapped(cookie, url, CookieSource::NonHTTP).is_none());

    let cookie = cookie_rs::Cookie::parse(" baz = bar ; Secure; Path = /foo/bar/").unwrap();
    let cookie = Cookie::new_wrapped(cookie, url, CookieSource::HTTP).unwrap();
    assert!(cookie.cookie.value == "bar");
    assert!(cookie.cookie.name == "baz");
    assert!(cookie.cookie.secure);
    assert!(&cookie.cookie.path.as_ref().unwrap()[..] == "/foo/bar/");
    assert!(&cookie.cookie.domain.as_ref().unwrap()[..] == "example.com");
    assert!(cookie.host_only);

    let u = &url!("http://example.com/foobar");
    let cookie = cookie_rs::Cookie::parse("foobar=value;path=/").unwrap();
    assert!(Cookie::new_wrapped(cookie, u, CookieSource::HTTP).is_some());
}

#[test]
fn test_sort_order() {
    use std::cmp::Ordering;

    let url = &url!("http://example.com/foo");
    let a_wrapped = cookie_rs::Cookie::parse("baz=bar; Path=/foo/bar/").unwrap();
    let a = Cookie::new_wrapped(a_wrapped.clone(), url, CookieSource::HTTP).unwrap();
    let a_prime = Cookie::new_wrapped(a_wrapped, url, CookieSource::HTTP).unwrap();
    let b = cookie_rs::Cookie::parse("baz=bar;Path=/foo/bar/baz/").unwrap();
    let b = Cookie::new_wrapped(b, url, CookieSource::HTTP).unwrap();

    assert!(b.cookie.path.as_ref().unwrap().len() > a.cookie.path.as_ref().unwrap().len());
    assert!(CookieStorage::cookie_comparator(&a, &b) == Ordering::Greater);
    assert!(CookieStorage::cookie_comparator(&b, &a) == Ordering::Less);
    assert!(CookieStorage::cookie_comparator(&a, &a_prime) == Ordering::Less);
    assert!(CookieStorage::cookie_comparator(&a_prime, &a) == Ordering::Greater);
    assert!(CookieStorage::cookie_comparator(&a, &a) == Ordering::Equal);
}
<|endoftext|>


<commit_before>extern crate crc;

use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::io::Read;
use std::path::Path;

use self::crc::{crc32, Hasher32};

fn verify(path: &Path) -> u32
{
    let mut buffer = File::open(path).unwrap();
    let mut digest = crc32::Digest::new(crc32::IEEE);

    for line in buffer.bytes() {
            digest.write(&[line.unwrap()]);
    }

    digest.sum32()
}

<commit_msg>Changing verify(path) to use File instead of Path<commit_after>extern crate crc;

use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::io::Read;
use std::path::Path;

use self::crc::{crc32, Hasher32};

pub fn get_crc32(file: &File) -> u32
{
    let mut digest = crc32::Digest::new(crc32::IEEE);

    for line in file.bytes() {
            digest.write(&[line.unwrap()]);
    }

    digest.sum32()
}

<|endoftext|>


<commit_before>//! Simple graphviz dot file format output.

use std::fmt::{self, Display, Write};

use crate::visit::{
    Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoNodeReferences,
    NodeIndexable, NodeRef,
};

/// `Dot` implements output to graphviz .dot format for a graph.
///
/// Formatting and options are rather simple, this is mostly intended
/// for debugging. Exact output may change.
///
/// # Examples
///
/// ```
/// use petgraph::Graph;
/// use petgraph::dot::{Dot, Config};
///
/// let mut graph = Graph::<_, ()>::new();
/// graph.add_node("A");
/// graph.add_node("B");
/// graph.add_node("C");
/// graph.add_node("D");
/// graph.extend_with_edges(&[
///     (0, 1), (0, 2), (0, 3),
///     (1, 2), (1, 3),
///     (2, 3),
/// ]);
///
/// println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
///
/// // In this case the output looks like this:
/// //
/// // digraph {
/// //     0 [label="\"A\""]
/// //     1 [label="\"B\""]
/// //     2 [label="\"C\""]
/// //     3 [label="\"D\""]
/// //     0 -> 1
/// //     0 -> 2
/// //     0 -> 3
/// //     1 -> 2
/// //     1 -> 3
/// //     2 -> 3
/// // }
///
/// // If you need multiple config options, just list them all in the slice.
/// ```
pub struct Dot<'a, G>
where
    G: IntoEdgeReferences + IntoNodeReferences,
{
    graph: G,
    config: &'a [Config],
    get_edge_attributes: &'a dyn Fn(G, G::EdgeRef) -> String,
    get_node_attributes: &'a dyn Fn(G, G::NodeRef) -> String,
}

static TYPE: [&str; 2] = ["graph", "digraph"];
static EDGE: [&str; 2] = ["--", "->"];
static INDENT: &str = "    ";

impl<'a, G> Dot<'a, G>
where
    G: GraphRef + IntoEdgeReferences + IntoNodeReferences,
{
    /// Create a `Dot` formatting wrapper with default configuration.
    pub fn new(graph: G) -> Self {
        Self::with_config(graph, &[])
    }

    /// Create a `Dot` formatting wrapper with custom configuration.
    pub fn with_config(graph: G, config: &'a [Config]) -> Self {
        Self::with_attr_getters(graph, config, &|_, _| "".to_string(), &|_, _| {
            "".to_string()
        })
    }

    pub fn with_attr_getters(
        graph: G,
        config: &'a [Config],
        get_edge_attributes: &'a dyn Fn(G, G::EdgeRef) -> String,
        get_node_attributes: &'a dyn Fn(G, G::NodeRef) -> String,
    ) -> Self {
        Dot {
            graph,
            config,
            get_edge_attributes,
            get_node_attributes,
        }
    }
}

/// `Dot` configuration.
///
/// This enum does not have an exhaustive definition (will be expanded)
#[derive(Debug, PartialEq, Eq)]
pub enum Config {
    /// Use indices for node labels.
    NodeIndexLabel,
    /// Use indices for edge labels.
    EdgeIndexLabel,
    /// Use no edge labels.
    EdgeNoLabel,
    /// Use no node labels.
    NodeNoLabel,
    /// Do not print the graph/digraph string.
    GraphContentOnly,
    #[doc(hidden)]
    _Incomplete(()),
}

impl<'a, G> Dot<'a, G>
where
    G: GraphBase + IntoNodeReferences + IntoEdgeReferences,
{
    fn graph_fmt<NF, EF, NW, EW>(
        &self,
        g: G,
        f: &mut fmt::Formatter,
        mut node_fmt: NF,
        mut edge_fmt: EF,
    ) -> fmt::Result
    where
        G: NodeIndexable + IntoNodeReferences + IntoEdgeReferences,
        G: GraphProp + GraphBase,
        G: Data<NodeWeight = NW, EdgeWeight = EW>,
        NF: FnMut(&NW, &mut dyn FnMut(&dyn Display) -> fmt::Result) -> fmt::Result,
        EF: FnMut(&EW, &mut dyn FnMut(&dyn Display) -> fmt::Result) -> fmt::Result,
    {
        if !self.config.contains(&Config::GraphContentOnly) {
            writeln!(f, "{} {{", TYPE[g.is_directed() as usize])?;
        }

        // output all labels
        for node in g.node_references() {
            write!(f, "{}{} [ ", INDENT, g.to_index(node.id()),)?;
            if !self.config.contains(&Config::NodeNoLabel) {
                write!(f, "label = \"")?;
                if self.config.contains(&Config::NodeIndexLabel) {
                    write!(f, "{}", g.to_index(node.id()))?;
                } else {
                    node_fmt(node.weight(), &mut |d| Escaped(d).fmt(f))?;
                }
                write!(f, "\" ")?;
            }
            writeln!(f, "{}]", (self.get_node_attributes)(g, node))?;
        }
        // output all edges
        for (i, edge) in g.edge_references().enumerate() {
            write!(
                f,
                "{}{} {} {} [ ",
                INDENT,
                g.to_index(edge.source()),
                EDGE[g.is_directed() as usize],
                g.to_index(edge.target()),
            )?;
            if !self.config.contains(&Config::EdgeNoLabel) {
                write!(f, "label = \"")?;
                if self.config.contains(&Config::EdgeIndexLabel) {
                    write!(f, "{}", i)?;
                } else {
                    edge_fmt(edge.weight(), &mut |d| Escaped(d).fmt(f))?;
                }
                write!(f, "\" ")?;
            }
            writeln!(f, "{}]", (self.get_edge_attributes)(g, edge))?;
        }

        if !self.config.contains(&Config::GraphContentOnly) {
            writeln!(f, "}}")?;
        }
        Ok(())
    }
}

impl<'a, G> fmt::Display for Dot<'a, G>
where
    G: IntoEdgeReferences + IntoNodeReferences + NodeIndexable + GraphProp,
    G::EdgeWeight: fmt::Display,
    G::NodeWeight: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graph_fmt(self.graph, f, |n, cb| cb(n), |e, cb| cb(e))
    }
}

impl<'a, G> fmt::Debug for Dot<'a, G>
where
    G: IntoEdgeReferences + IntoNodeReferences + NodeIndexable + GraphProp,
    G::EdgeWeight: fmt::Debug,
    G::NodeWeight: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graph_fmt(
            self.graph,
            f,
            |n, cb| cb(&DebugFmt(n)),
            |e, cb| cb(&DebugFmt(e)),
        )
    }
}

/// Escape for Graphviz
struct Escaper<W>(W);

impl<W> fmt::Write for Escaper<W>
where
    W: fmt::Write,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for c in s.chars() {
            self.write_char(c)?;
        }
        Ok(())
    }

    fn write_char(&mut self, c: char) -> fmt::Result {
        match c {
            '"' | '\\' => self.0.write_char('\\')?,
            // \l is for left justified linebreak
            '\n' => return self.0.write_str("\\l"),
            _ => {}
        }
        self.0.write_char(c)
    }
}

/// Pass Display formatting through a simple escaping filter
struct Escaped<T>(T);

impl<T> fmt::Display for Escaped<T>
where
    T: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if f.alternate() {
            writeln!(&mut Escaper(f), "{:#}", &self.0)
        } else {
            write!(&mut Escaper(f), "{}", &self.0)
        }
    }
}

/// Pass Debug formatting to Display
struct DebugFmt<T>(T);

impl<T> fmt::Display for DebugFmt<T>
where
    T: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

#[cfg(test)]
mod test {
    use super::{Config, Dot, Escaper};
    use crate::prelude::Graph;
    use crate::visit::NodeRef;
    use std::fmt::Write;

    #[test]
    fn test_escape() {
        let mut buff = String::new();
        {
            let mut e = Escaper(&mut buff);
            let _ = e.write_str("\" \\ \n");
        }
        assert_eq!(buff, "\\\" \\\\ \\l");
    }

    fn simple_graph() -> Graph<&'static str, &'static str> {
        let mut graph = Graph::<&str, &str>::new();
        let a = graph.add_node("A");
        let b = graph.add_node("B");
        graph.add_edge(a, b, "edge_label");
        graph
    }

    #[test]
    fn test_nodeindexlable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::NodeIndexLabel]));
        assert_eq!(dot, "digraph {\n    0 [ label = \"0\" ]\n    1 [ label = \"1\" ]\n    0 -> 1 [ label = \"\\\"edge_label\\\"\" ]\n}\n");
    }

    #[test]
    fn test_edgeindexlable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::EdgeIndexLabel]));
        assert_eq!(dot, "digraph {\n    0 [ label = \"\\\"A\\\"\" ]\n    1 [ label = \"\\\"B\\\"\" ]\n    0 -> 1 [ label = \"0\" ]\n}\n");
    }

    #[test]
    fn test_edgenolable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
        assert_eq!(dot, "digraph {\n    0 [ label = \"\\\"A\\\"\" ]\n    1 [ label = \"\\\"B\\\"\" ]\n    0 -> 1 [ ]\n}\n");
    }

    #[test]
    fn test_nodenolable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::NodeNoLabel]));
        assert_eq!(
            dot,
            "digraph {\n    0 [ ]\n    1 [ ]\n    0 -> 1 [ label = \"\\\"edge_label\\\"\" ]\n}\n"
        );
    }

    #[test]
    fn test_with_attr_getters() {
        let graph = simple_graph();
        let dot = format!(
            "{:?}",
            Dot::with_attr_getters(
                &graph,
                &[Config::NodeNoLabel, Config::EdgeNoLabel],
                &|_, er| format!("label = \"{}\"", er.weight().to_uppercase()),
                &|_, nr| format!("label = \"{}\"", nr.weight().to_lowercase()),
            ),
        );
        assert_eq!(dot, "digraph {\n    0 [ label = \"a\"]\n    1 [ label = \"b\"]\n    0 -> 1 [ label = \"EDGE_LABEL\"]\n}\n");
    }
}
<commit_msg>Simplify/optimize petgraph::dot a bit (#424)<commit_after>//! Simple graphviz dot file format output.

use std::fmt::{self, Display, Write};

use crate::visit::{
    EdgeRef, GraphProp, IntoEdgeReferences, IntoNodeReferences, NodeIndexable, NodeRef,
};

/// `Dot` implements output to graphviz .dot format for a graph.
///
/// Formatting and options are rather simple, this is mostly intended
/// for debugging. Exact output may change.
///
/// # Examples
///
/// ```
/// use petgraph::Graph;
/// use petgraph::dot::{Dot, Config};
///
/// let mut graph = Graph::<_, ()>::new();
/// graph.add_node("A");
/// graph.add_node("B");
/// graph.add_node("C");
/// graph.add_node("D");
/// graph.extend_with_edges(&[
///     (0, 1), (0, 2), (0, 3),
///     (1, 2), (1, 3),
///     (2, 3),
/// ]);
///
/// println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
///
/// // In this case the output looks like this:
/// //
/// // digraph {
/// //     0 [label="\"A\""]
/// //     1 [label="\"B\""]
/// //     2 [label="\"C\""]
/// //     3 [label="\"D\""]
/// //     0 -> 1
/// //     0 -> 2
/// //     0 -> 3
/// //     1 -> 2
/// //     1 -> 3
/// //     2 -> 3
/// // }
///
/// // If you need multiple config options, just list them all in the slice.
/// ```
pub struct Dot<'a, G>
where
    G: IntoEdgeReferences + IntoNodeReferences,
{
    graph: G,
    get_edge_attributes: &'a dyn Fn(G, G::EdgeRef) -> String,
    get_node_attributes: &'a dyn Fn(G, G::NodeRef) -> String,
    config: Configs,
}

static TYPE: [&str; 2] = ["graph", "digraph"];
static EDGE: [&str; 2] = ["--", "->"];
static INDENT: &str = "    ";

impl<'a, G> Dot<'a, G>
where
    G: IntoNodeReferences + IntoEdgeReferences,
{
    /// Create a `Dot` formatting wrapper with default configuration.
    #[inline]
    pub fn new(graph: G) -> Self {
        Self::with_config(graph, &[])
    }

    /// Create a `Dot` formatting wrapper with custom configuration.
    #[inline]
    pub fn with_config(graph: G, config: &'a [Config]) -> Self {
        Self::with_attr_getters(graph, config, &|_, _| String::new(), &|_, _| String::new())
    }

    #[inline]
    pub fn with_attr_getters(
        graph: G,
        config: &'a [Config],
        get_edge_attributes: &'a dyn Fn(G, G::EdgeRef) -> String,
        get_node_attributes: &'a dyn Fn(G, G::NodeRef) -> String,
    ) -> Self {
        let config = Configs::extract(config);
        Dot {
            graph,
            get_edge_attributes,
            get_node_attributes,
            config,
        }
    }
}

/// `Dot` configuration.
///
/// This enum does not have an exhaustive definition (will be expanded)
// TODO: #[non_exhaustive] once MSRV >= 1.40,
// and/or for a breaking change make this something like an EnumSet: https://docs.rs/enumset
#[derive(Debug, PartialEq, Eq)]
pub enum Config {
    /// Use indices for node labels.
    NodeIndexLabel,
    /// Use indices for edge labels.
    EdgeIndexLabel,
    /// Use no edge labels.
    EdgeNoLabel,
    /// Use no node labels.
    NodeNoLabel,
    /// Do not print the graph/digraph string.
    GraphContentOnly,
    #[doc(hidden)]
    _Incomplete(()),
}
macro_rules! make_config_struct {
    ($($variant:ident,)*) => {
        #[allow(non_snake_case)]
        #[derive(Default)]
        struct Configs {
            $($variant: bool,)*
        }
        impl Configs {
            #[inline]
            fn extract(configs: &[Config]) -> Self {
                let mut conf = Self::default();
                for c in configs {
                    match *c {
                        $(Config::$variant => conf.$variant = true,)*
                        Config::_Incomplete(()) => {}
                    }
                }
                conf
            }
        }
    }
}
make_config_struct!(
    NodeIndexLabel,
    EdgeIndexLabel,
    EdgeNoLabel,
    NodeNoLabel,
    GraphContentOnly,
);

impl<'a, G> Dot<'a, G>
where
    G: IntoNodeReferences + IntoEdgeReferences + NodeIndexable + GraphProp,
{
    fn graph_fmt<NF, EF>(&self, f: &mut fmt::Formatter, node_fmt: NF, edge_fmt: EF) -> fmt::Result
    where
        NF: Fn(&G::NodeWeight, &mut fmt::Formatter) -> fmt::Result,
        EF: Fn(&G::EdgeWeight, &mut fmt::Formatter) -> fmt::Result,
    {
        let g = self.graph;
        if !self.config.GraphContentOnly {
            writeln!(f, "{} {{", TYPE[g.is_directed() as usize])?;
        }

        // output all labels
        for node in g.node_references() {
            write!(f, "{}{} [ ", INDENT, g.to_index(node.id()),)?;
            if !self.config.NodeNoLabel {
                write!(f, "label = \"")?;
                if self.config.NodeIndexLabel {
                    write!(f, "{}", g.to_index(node.id()))?;
                } else {
                    Escaped(FnFmt(node.weight(), &node_fmt)).fmt(f)?;
                }
                write!(f, "\" ")?;
            }
            writeln!(f, "{}]", (self.get_node_attributes)(g, node))?;
        }
        // output all edges
        for (i, edge) in g.edge_references().enumerate() {
            write!(
                f,
                "{}{} {} {} [ ",
                INDENT,
                g.to_index(edge.source()),
                EDGE[g.is_directed() as usize],
                g.to_index(edge.target()),
            )?;
            if !self.config.EdgeNoLabel {
                write!(f, "label = \"")?;
                if self.config.EdgeIndexLabel {
                    write!(f, "{}", i)?;
                } else {
                    Escaped(FnFmt(edge.weight(), &edge_fmt)).fmt(f)?;
                }
                write!(f, "\" ")?;
            }
            writeln!(f, "{}]", (self.get_edge_attributes)(g, edge))?;
        }

        if !self.config.GraphContentOnly {
            writeln!(f, "}}")?;
        }
        Ok(())
    }
}

impl<'a, G> fmt::Display for Dot<'a, G>
where
    G: IntoEdgeReferences + IntoNodeReferences + NodeIndexable + GraphProp,
    G::EdgeWeight: fmt::Display,
    G::NodeWeight: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graph_fmt(f, fmt::Display::fmt, fmt::Display::fmt)
    }
}

impl<'a, G> fmt::Debug for Dot<'a, G>
where
    G: IntoEdgeReferences + IntoNodeReferences + NodeIndexable + GraphProp,
    G::EdgeWeight: fmt::Debug,
    G::NodeWeight: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graph_fmt(f, fmt::Debug::fmt, fmt::Debug::fmt)
    }
}

/// Escape for Graphviz
struct Escaper<W>(W);

impl<W> fmt::Write for Escaper<W>
where
    W: fmt::Write,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for c in s.chars() {
            self.write_char(c)?;
        }
        Ok(())
    }

    fn write_char(&mut self, c: char) -> fmt::Result {
        match c {
            '"' | '\\' => self.0.write_char('\\')?,
            // \l is for left justified linebreak
            '\n' => return self.0.write_str("\\l"),
            _ => {}
        }
        self.0.write_char(c)
    }
}

/// Pass Display formatting through a simple escaping filter
struct Escaped<T>(T);

impl<T> fmt::Display for Escaped<T>
where
    T: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if f.alternate() {
            writeln!(&mut Escaper(f), "{:#}", &self.0)
        } else {
            write!(&mut Escaper(f), "{}", &self.0)
        }
    }
}

/// Format data using a specific format function
struct FnFmt<'a, T, F>(&'a T, F);

impl<'a, T, F> fmt::Display for FnFmt<'a, T, F>
where
    F: Fn(&'a T, &mut fmt::Formatter<'_>) -> fmt::Result,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.1(self.0, f)
    }
}

#[cfg(test)]
mod test {
    use super::{Config, Dot, Escaper};
    use crate::prelude::Graph;
    use crate::visit::NodeRef;
    use std::fmt::Write;

    #[test]
    fn test_escape() {
        let mut buff = String::new();
        {
            let mut e = Escaper(&mut buff);
            let _ = e.write_str("\" \\ \n");
        }
        assert_eq!(buff, "\\\" \\\\ \\l");
    }

    fn simple_graph() -> Graph<&'static str, &'static str> {
        let mut graph = Graph::<&str, &str>::new();
        let a = graph.add_node("A");
        let b = graph.add_node("B");
        graph.add_edge(a, b, "edge_label");
        graph
    }

    #[test]
    fn test_nodeindexlable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::NodeIndexLabel]));
        assert_eq!(dot, "digraph {\n    0 [ label = \"0\" ]\n    1 [ label = \"1\" ]\n    0 -> 1 [ label = \"\\\"edge_label\\\"\" ]\n}\n");
    }

    #[test]
    fn test_edgeindexlable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::EdgeIndexLabel]));
        assert_eq!(dot, "digraph {\n    0 [ label = \"\\\"A\\\"\" ]\n    1 [ label = \"\\\"B\\\"\" ]\n    0 -> 1 [ label = \"0\" ]\n}\n");
    }

    #[test]
    fn test_edgenolable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
        assert_eq!(dot, "digraph {\n    0 [ label = \"\\\"A\\\"\" ]\n    1 [ label = \"\\\"B\\\"\" ]\n    0 -> 1 [ ]\n}\n");
    }

    #[test]
    fn test_nodenolable_option() {
        let graph = simple_graph();
        let dot = format!("{:?}", Dot::with_config(&graph, &[Config::NodeNoLabel]));
        assert_eq!(
            dot,
            "digraph {\n    0 [ ]\n    1 [ ]\n    0 -> 1 [ label = \"\\\"edge_label\\\"\" ]\n}\n"
        );
    }

    #[test]
    fn test_with_attr_getters() {
        let graph = simple_graph();
        let dot = format!(
            "{:?}",
            Dot::with_attr_getters(
                &graph,
                &[Config::NodeNoLabel, Config::EdgeNoLabel],
                &|_, er| format!("label = \"{}\"", er.weight().to_uppercase()),
                &|_, nr| format!("label = \"{}\"", nr.weight().to_lowercase()),
            ),
        );
        assert_eq!(dot, "digraph {\n    0 [ label = \"a\"]\n    1 [ label = \"b\"]\n    0 -> 1 [ label = \"EDGE_LABEL\"]\n}\n");
    }
}
<|endoftext|>


<commit_before>extern crate chrono;

use self::chrono::*;

pub enum IssuePattern { IntensityOnly, LowAccuracy, HighAccuracy, Cancel }
pub enum Source { Sapporo, Sendai, Tokyo, Osaka, Fukuoka, Okinawa }
pub enum Kind { Normal, Drill, Cancel, DrillCancel, Reference, Test }
pub enum Status { Normal, Correction, CancelCorrection, LastWithCorrection, Last, Unknown }

pub enum EpicenterAccuracy {
	Single, Territory, GridSearchLow, GridSearchHigh,
	NIEDLow, NIEDHigh, EPOSLow, EPOSHigh, Reserved, Unknown
}

pub enum DepthAccuracy {
	Single, Territory, GridSearchLow, GridSearchHigh,
	NIEDLow, NIEDHigh, EPOSLow, EPOSHigh, Reserved, Unknown
}

pub enum MagnitudeAccuracy {
	NIED, PWave, PSMixed, SWave, EPOS, Level,
	Undefined, Reserved, Unknown
}

pub enum EpicenterCategory { Land, Sea, Undefined, Unknown }
pub enum WarningStatus { Forecast, Alert, Undefined, Unknown }
pub enum IntensityChange { Same, Up, Down, Undefined, Unknown }
pub enum ChangeReason { Nothing, Magnitude, Epicenter, Mixed, Depth, Undefined, Unknown }
pub enum WaveStatus { Unreached, Reached, Undefined, Unknown }

pub struct AreaEEW {

	area_name: String,
	minimum_intensity: f32,
	maximum_intensity: Option<f32>,
	reached_at: DateTime<UTC>,
	warning_status: WarningStatus,
	wave_status: WaveStatus,
}

pub struct EEW {

	pattern: IssuePattern,
	source: Source,
	kind: Kind,
	issued_at: DateTime<UTC>,

	occurred_at: DateTime<UTC>,
	id: String,
	status: Status,
	number: Option<u32>,
	epicenter_name: String,

	epicenter: (f32, f32),
	depth: f32,
	magnitude: f32,
	maximum_intensity: f32,

	epicenter_accuracy: EpicenterAccuracy,
	depth_accuracy: DepthAccuracy,
	magnitude_accuracy: MagnitudeAccuracy,

	epicenter_caterogy: EpicenterCategory,
	warning_status: WarningStatus,
	intensity_change: IntensityChange,
	change_reason: ChangeReason,

	area_eew: Vec<AreaEEW>,
}
<commit_msg>Change EEW format in order to adjust it to the latest JMA EEW format<commit_after>extern crate chrono;

use std::cmp::{PartialEq, Eq};
use self::chrono::*;

#[derive(PartialEq, Eq, Debug)]
pub enum IssuePattern { IntensityOnly, LowAccuracy, HighAccuracy }

#[derive(PartialEq, Eq, Debug)]
pub enum Source { Tokyo, Osaka }

#[derive(PartialEq, Eq, Debug)]
pub enum Kind { Normal, Drill, Cancel, DrillCancel, Reference, Test }

#[derive(PartialEq, Eq, Debug)]
pub enum Status { Normal, Correction, CancelCorrection, LastWithCorrection, Last, Unknown }

#[derive(PartialEq, Eq, Debug)]
pub enum EpicenterAccuracy {
	Single, Territory, GridSearchLow, GridSearchHigh,
	NIEDLow, NIEDHigh, EPOSLow, EPOSHigh, Unknown
}

#[derive(PartialEq, Eq, Debug)]
pub enum DepthAccuracy {
	Single, Territory, GridSearchLow, GridSearchHigh,
	NIEDLow, NIEDHigh, EPOSLow, EPOSHigh, Unknown
}

#[derive(PartialEq, Eq, Debug)]
pub enum MagnitudeAccuracy {
	NIED, PWave, PSMixed, SWave, EPOS, Level, Unknown
}

#[derive(PartialEq, Eq, Debug)]
pub enum EpicenterCategory { Land, Sea, Unknown }

#[derive(PartialEq, Eq, Debug)]
pub enum WarningStatus { Forecast, Alert, Unknown }

#[derive(PartialEq, Eq, Debug)]
pub enum IntensityChange { Same, Up, Down, Unknown }

#[derive(PartialEq, Eq, Debug)]
pub enum ChangeReason { Nothing, Magnitude, Epicenter, Mixed, Depth, Unknown }

#[derive(PartialEq, Eq, Debug)]
pub enum WaveStatus { Unreached, Reached, Unknown }

#[derive(PartialEq, Debug)]
pub enum EEWDetail {
	Full(FullEEW),
	Cancel,
}

#[derive(PartialEq, Debug)]
pub struct AreaEEW {

	pub area_name: String,
	pub minimum_intensity: f32,
	pub maximum_intensity: Option<f32>,
	pub reached_at: Option<DateTime<UTC>>,
	pub warning_status: WarningStatus,
	pub wave_status: WaveStatus,
}

#[derive(PartialEq, Debug)]
pub struct EEW {

	pub source: Source,
	pub kind: Kind,
	pub issued_at: DateTime<UTC>,

	pub occurred_at: DateTime<UTC>,
	pub id: String,
	pub status: Status,
	pub number: u32, // we don't accept an EEW which has no telegram number

	pub detail: EEWDetail,
}

#[derive(PartialEq, Debug)]
pub struct FullEEW {

	pub issue_pattern: IssuePattern,

	pub epicenter_name: String,
	pub epicenter: (f32, f32),
	pub depth: Option<f32>,
	pub magnitude: Option<f32>,
	pub maximum_intensity: Option<f32>,

	pub epicenter_accuracy: EpicenterAccuracy,
	pub depth_accuracy: DepthAccuracy,
	pub magnitude_accuracy: MagnitudeAccuracy,

	pub epicenter_caterogy: EpicenterCategory,
	pub warning_status: WarningStatus,
	pub intensity_change: IntensityChange,
	pub change_reason: ChangeReason,

	pub area_eew: Vec<AreaEEW>,
}
<|endoftext|>


<commit_before>//! Accessors for workflow environment variables
//!
//! See https://www.alfredapp.com/help/workflows/script-environment-variables/
//! for more info.

use std::env;
use std::path::PathBuf;

/// Returns the location of the Alfred.alfredpreferences.
///
/// Example output: `"/Users/Crayons/Dropbox/Alfred/Alfred.alfredpreferences"`
pub fn preferences() -> Option<PathBuf> {
    env::var("alfred_preferences").ok().map(PathBuf::from)
}

/// Returns the location of local (Mac-specific) preferences.
///
/// Example output: `"/Users/Crayons/Dropbox/Alfred/Alfred.alfredpreferences/preferences/local/adbd4f66bc3ae8493832af61a41ee609b20d8705"`
pub fn local_preferences() -> Option<PathBuf> {
    match (preferences(),env::var("alfred_preferences_localhash")) {
        (Some(mut prefs),Ok(hash)) => {
            prefs.extend(["preferences","local",&hash].iter());
            Some(prefs)
        }
        _ => None
    }
}

/// Returns the current Alfred theme.
///
/// Example output: `"alfred.theme.yosemite"`
pub fn theme() -> Option<String> {
    env::var("alfred_theme").ok()
}

/// Returns the color of the theme background.
///
/// Example output: `"rgba(255,255,255,0.98)"`
// TODO: can we parse this?
// Is this always in rgba(), or can it be any web color?
pub fn theme_background_str() -> Option<String> {
    env::var("alfred_theme_background").ok()
}

/// Returns the color of the theme's selected item background.
///
/// Example output: `"rgba(255,255,255,0.98)"`
// TODO: see `theme_background_str()`
pub fn theme_selection_background_str() -> Option<String> {
    env::var("alfred_theme_selection_background").ok()
}

/// The subtext mode in the Appearance preferences.
#[derive(Copy,Clone,Debug,PartialEq,Eq,Hash)]
pub enum Subtext {
    /// Always show subtext.
    Always,
    /// Only show subtext for alternative actions.
    AlternativeActions,
    /// Only show subtext for the selected result.
    SelectedResult,
    /// Never show subtext.
    Never
}

/// Returns the subtext mode the user has selected in the Appearance preferences.
pub fn theme_subtext() -> Option<Subtext> {
    match env::var("alfred_theme_subtext").as_ref().map(|s| s.as_ref()) {
        Ok("0") => Some(Subtext::Always),
        Ok("1") => Some(Subtext::AlternativeActions),
        Ok("2") => Some(Subtext::SelectedResult),
        Ok("3") => Some(Subtext::Never),
        _ => None
    }
}

/// Returns the version of Alfred.
///
/// Example output: `"3.2.1"`
pub fn version() -> Option<String> {
    env::var("alfred_version").ok()
}

/// Returns the build of Alfred.
///
/// Example output: `768`
pub fn version_build() -> Option<i32> {
    env::var("alfred_version_build").ok().and_then(|s| s.parse().ok())
}

/// Returns the bundle ID of the current running workflow.
///
/// Example output: `"com.alfredapp.david.googlesuggest"`
pub fn workflow_bundle_id() -> Option<String> {
    env::var("alfred_workflow_bundleid").ok()
}

/// Returns the recommended location for volatile workflow data.
///
/// Example output: `"/Users/Crayons/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data/com.alfredapp.david.googlesuggest"`
pub fn workflow_cache() -> Option<PathBuf> {
    env::var("alfred_workflow_cache").ok().map(PathBuf::from)
}

/// Returns the recommended location for non-volatile workflow data.
///
/// Example output: `"/Users/Crayons/Library/Application Support/Alfred 2/Workflow Data/com.alfredapp.david.googlesuggest"`
pub fn workflow_data() -> Option<PathBuf> {
    env::var("alfred_workflow_data").ok().map(PathBuf::from)
}

/// Returns the name of the currently running workflow.
///
/// Example output: `"Google Suggest"`
pub fn workflow_name() -> Option<String> {
    env::var("alfred_workflow_name").ok()
}

/// Returns the unique ID of the currently running workflow.
///
/// Example output: `"user.workflow.B0AC54EC-601C-479A-9428-01F9FD732959"`
pub fn workflow_uid() -> Option<String> {
    env::var("alfred_workflow_uid").ok()
}

/// Returns the version of the currently running workflow.
pub fn workflow_version() -> Option<String> {
    env::var("alfred_workflow_version").ok()
}

/// Returns `true` if the user has the debug panel open for the workflow.
pub fn is_debug() -> bool {
    match env::var("alfred_debug") {
        Ok(val) => val == "1",
        _ => false
    }
}
<commit_msg>Add notes about possibly missing data<commit_after>//! Accessors for workflow environment variables
//!
//! See https://www.alfredapp.com/help/workflows/script-environment-variables/
//! for more info.

use std::env;
use std::path::PathBuf;

/// Returns the location of the Alfred.alfredpreferences.
///
/// Example output: `"/Users/Crayons/Dropbox/Alfred/Alfred.alfredpreferences"`
pub fn preferences() -> Option<PathBuf> {
    env::var("alfred_preferences").ok().map(PathBuf::from)
}

/// Returns the location of local (Mac-specific) preferences.
///
/// Example output: `"/Users/Crayons/Dropbox/Alfred/Alfred.alfredpreferences/preferences/local/adbd4f66bc3ae8493832af61a41ee609b20d8705"`
pub fn local_preferences() -> Option<PathBuf> {
    match (preferences(),env::var("alfred_preferences_localhash")) {
        (Some(mut prefs),Ok(hash)) => {
            prefs.extend(["preferences","local",&hash].iter());
            Some(prefs)
        }
        _ => None
    }
}

/// Returns the current Alfred theme.
///
/// Example output: `"alfred.theme.yosemite"`
pub fn theme() -> Option<String> {
    env::var("alfred_theme").ok()
}

/// Returns the color of the theme background.
///
/// Example output: `"rgba(255,255,255,0.98)"`
// TODO: can we parse this?
// Is this always in rgba(), or can it be any web color?
pub fn theme_background_str() -> Option<String> {
    env::var("alfred_theme_background").ok()
}

/// Returns the color of the theme's selected item background.
///
/// Example output: `"rgba(255,255,255,0.98)"`
// TODO: see `theme_background_str()`
pub fn theme_selection_background_str() -> Option<String> {
    env::var("alfred_theme_selection_background").ok()
}

/// The subtext mode in the Appearance preferences.
#[derive(Copy,Clone,Debug,PartialEq,Eq,Hash)]
pub enum Subtext {
    /// Always show subtext.
    Always,
    /// Only show subtext for alternative actions.
    AlternativeActions,
    /// Only show subtext for the selected result.
    SelectedResult,
    /// Never show subtext.
    Never
}

/// Returns the subtext mode the user has selected in the Appearance preferences.
pub fn theme_subtext() -> Option<Subtext> {
    match env::var("alfred_theme_subtext").as_ref().map(|s| s.as_ref()) {
        Ok("0") => Some(Subtext::Always),
        Ok("1") => Some(Subtext::AlternativeActions),
        Ok("2") => Some(Subtext::SelectedResult),
        Ok("3") => Some(Subtext::Never),
        _ => None
    }
}

/// Returns the version of Alfred.
///
/// Example output: `"3.2.1"`
pub fn version() -> Option<String> {
    env::var("alfred_version").ok()
}

/// Returns the build of Alfred.
///
/// Example output: `768`
pub fn version_build() -> Option<i32> {
    env::var("alfred_version_build").ok().and_then(|s| s.parse().ok())
}

/// Returns the bundle ID of the current running workflow.
///
/// Example output: `"com.alfredapp.david.googlesuggest"`
pub fn workflow_bundle_id() -> Option<String> {
    env::var("alfred_workflow_bundleid").ok()
}

/// Returns the recommended location for volatile workflow data.
/// Will only be populated if the workflow has a bundle identifier set.
///
/// Example output: `"/Users/Crayons/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data/com.alfredapp.david.googlesuggest"`
pub fn workflow_cache() -> Option<PathBuf> {
    env::var("alfred_workflow_cache").ok().map(PathBuf::from)
}

/// Returns the recommended location for non-volatile workflow data.
/// Will only be populated if the workflow has a bundle identifier set.
///
/// Example output: `"/Users/Crayons/Library/Application Support/Alfred 2/Workflow Data/com.alfredapp.david.googlesuggest"`
pub fn workflow_data() -> Option<PathBuf> {
    env::var("alfred_workflow_data").ok().map(PathBuf::from)
}

/// Returns the name of the currently running workflow.
///
/// Example output: `"Google Suggest"`
pub fn workflow_name() -> Option<String> {
    env::var("alfred_workflow_name").ok()
}

/// Returns the unique ID of the currently running workflow.
///
/// Example output: `"user.workflow.B0AC54EC-601C-479A-9428-01F9FD732959"`
pub fn workflow_uid() -> Option<String> {
    env::var("alfred_workflow_uid").ok()
}

/// Returns the version of the currently running workflow.
pub fn workflow_version() -> Option<String> {
    env::var("alfred_workflow_version").ok()
}

/// Returns `true` if the user has the debug panel open for the workflow.
pub fn is_debug() -> bool {
    match env::var("alfred_debug") {
        Ok(val) => val == "1",
        _ => false
    }
}
<|endoftext|>