<commit_before>use serde::{Deserialize, Serialize};

/// GeoIP2 Country record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Country<'a> {
    #[serde(borrow)]
    pub continent: Option<country::Continent<'a>>,
    pub country: Option<country::Country<'a>>,
    pub registered_country: Option<country::Country<'a>>,
    pub represented_country: Option<country::RepresentedCountry<'a>>,
    pub traits: Option<country::Traits>,
}

/// GeoIP2 City record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct City<'a> {
    pub city: Option<city::City<'a>>,
    #[serde(borrow)]
    pub continent: Option<city::Continent<'a>>,
    pub country: Option<city::Country<'a>>,
    pub location: Option<city::Location<'a>>,
    pub postal: Option<city::Postal<'a>>,
    pub registered_country: Option<city::Country<'a>>,
    pub represented_country: Option<city::RepresentedCountry<'a>>,
    pub subdivisions: Option<Vec<city::Subdivision<'a>>>,
    pub traits: Option<city::Traits>,
}

/// GeoIP2 Enterprise record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Enterprise<'a> {
    pub city: Option<enterprise::City<'a>>,
    #[serde(borrow)]
    pub continent: Option<enterprise::Continent<'a>>,
    pub country: Option<enterprise::Country<'a>>,
    pub location: Option<enterprise::Location<'a>>,
    pub postal: Option<enterprise::Postal<'a>>,
    pub registered_country: Option<enterprise::Country<'a>>,
    pub represented_country: Option<enterprise::RepresentedCountry<'a>>,
    pub subdivisions: Option<Vec<enterprise::Subdivision<'a>>>,
    pub traits: Option<enterprise::Traits<'a>>,
}

/// GeoIP2 ISP record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Isp<'a> {
    pub autonomous_system_number: Option<u32>,
    pub autonomous_system_organization: Option<&'a str>,
    pub isp: Option<&'a str>,
    pub mobile_country_code: Option<&'a str>,
    pub mobile_network_code: Option<&'a str>,
    pub organization: Option<&'a str>,
}

/// GeoIP2 Connection-Type record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct ConnectionType<'a> {
    pub connection_type: Option<&'a str>,
}

/// GeoIP2 Anonymous Ip record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct AnonymousIp {
    pub is_anonymous: Option<bool>,
    pub is_anonymous_vpn: Option<bool>,
    pub is_hosting_provider: Option<bool>,
    pub is_public_proxy: Option<bool>,
    pub is_residential_proxy: Option<bool>,
    pub is_tor_exit_node: Option<bool>,
}

/// GeoIP2 DensityIncome record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct DensityIncome {
    pub average_income: Option<u32>,
    pub population_density: Option<u32>,
}

/// GeoIP2 Domain record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Domain<'a> {
    pub domain: Option<&'a str>,
}

/// GeoIP2 Asn record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Asn<'a> {
    pub autonomous_system_number: Option<u32>,
    pub autonomous_system_organization: Option<&'a str>,
}

/// Country model structs
pub mod country {
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Continent<'a> {
        pub code: Option<&'a str>,
        pub geoname_id: Option<u32>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Country<'a> {
        pub geoname_id: Option<u32>,
        pub is_in_european_union: Option<bool>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct RepresentedCountry<'a> {
        pub geoname_id: Option<u32>,
        pub is_in_european_union: Option<bool>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
        #[serde(rename = "type")]
        pub representation_type: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Traits {
        pub is_anonymous_proxy: Option<bool>,
        pub is_satellite_provider: Option<bool>,
    }
}

/// Country model structs
pub mod city {
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    pub use super::country::{Continent, Country, RepresentedCountry, Traits};

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct City<'a> {
        pub geoname_id: Option<u32>,
        #[serde(borrow)]
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Location<'a> {
        pub accuracy_radius: Option<u16>,
        pub latitude: Option<f64>,
        pub longitude: Option<f64>,
        pub metro_code: Option<u16>,
        pub time_zone: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Postal<'a> {
        pub code: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Subdivision<'a> {
        pub geoname_id: Option<u32>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }
}

/// Enterprise model structs
pub mod enterprise {
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    pub use super::country::{Continent, RepresentedCountry};

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct City<'a> {
        pub confidence: Option<u8>,
        pub geoname_id: Option<u32>,
        #[serde(borrow)]
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Country<'a> {
        pub confidence: Option<u8>,
        pub geoname_id: Option<u32>,
        pub is_in_european_union: Option<bool>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Location<'a> {
        pub accuracy_radius: Option<u16>,
        pub latitude: Option<f64>,
        pub longitude: Option<f64>,
        pub metro_code: Option<u16>,
        pub time_zone: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Postal<'a> {
        pub confidence: Option<u8>,
        pub code: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Subdivision<'a> {
        pub confidence: Option<u8>,
        pub geoname_id: Option<u32>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Traits<'a> {
        pub autonomous_system_number: Option<u32>,
        pub autonomous_system_organization: Option<&'a str>,
        pub connection_type: Option<&'a str>,
        pub domain: Option<&'a str>,
        pub is_anonymous: Option<bool>,
        pub is_anonymous_proxy: Option<bool>,
        pub is_anonymous_vpn: Option<bool>,
        pub is_hosting_provider: Option<bool>,
        pub isp: Option<&'a str>,
        pub is_public_proxy: Option<bool>,
        pub is_residential_proxy: Option<bool>,
        pub is_satellite_provider: Option<bool>,
        pub is_tor_exit_node: Option<bool>,
        pub mobile_country_code: Option<&'a str>,
        pub mobile_network_code: Option<&'a str>,
        pub organization: Option<&'a str>,
        pub user_type: Option<&'a str>,
    }
}
<commit_msg>Make ordering more consistent<commit_after>use serde::{Deserialize, Serialize};

/// GeoIP2 Country record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Country<'a> {
    #[serde(borrow)]
    pub continent: Option<country::Continent<'a>>,
    pub country: Option<country::Country<'a>>,
    pub registered_country: Option<country::Country<'a>>,
    pub represented_country: Option<country::RepresentedCountry<'a>>,
    pub traits: Option<country::Traits>,
}

/// GeoIP2 City record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct City<'a> {
    #[serde(borrow)]
    pub city: Option<city::City<'a>>,
    pub continent: Option<city::Continent<'a>>,
    pub country: Option<city::Country<'a>>,
    pub location: Option<city::Location<'a>>,
    pub postal: Option<city::Postal<'a>>,
    pub registered_country: Option<city::Country<'a>>,
    pub represented_country: Option<city::RepresentedCountry<'a>>,
    pub subdivisions: Option<Vec<city::Subdivision<'a>>>,
    pub traits: Option<city::Traits>,
}

/// GeoIP2 Enterprise record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Enterprise<'a> {
    #[serde(borrow)]
    pub city: Option<enterprise::City<'a>>,
    pub continent: Option<enterprise::Continent<'a>>,
    pub country: Option<enterprise::Country<'a>>,
    pub location: Option<enterprise::Location<'a>>,
    pub postal: Option<enterprise::Postal<'a>>,
    pub registered_country: Option<enterprise::Country<'a>>,
    pub represented_country: Option<enterprise::RepresentedCountry<'a>>,
    pub subdivisions: Option<Vec<enterprise::Subdivision<'a>>>,
    pub traits: Option<enterprise::Traits<'a>>,
}

/// GeoIP2 ISP record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Isp<'a> {
    pub autonomous_system_number: Option<u32>,
    pub autonomous_system_organization: Option<&'a str>,
    pub isp: Option<&'a str>,
    pub mobile_country_code: Option<&'a str>,
    pub mobile_network_code: Option<&'a str>,
    pub organization: Option<&'a str>,
}

/// GeoIP2 Connection-Type record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct ConnectionType<'a> {
    pub connection_type: Option<&'a str>,
}

/// GeoIP2 Anonymous Ip record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct AnonymousIp {
    pub is_anonymous: Option<bool>,
    pub is_anonymous_vpn: Option<bool>,
    pub is_hosting_provider: Option<bool>,
    pub is_public_proxy: Option<bool>,
    pub is_residential_proxy: Option<bool>,
    pub is_tor_exit_node: Option<bool>,
}

/// GeoIP2 DensityIncome record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct DensityIncome {
    pub average_income: Option<u32>,
    pub population_density: Option<u32>,
}

/// GeoIP2 Domain record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Domain<'a> {
    pub domain: Option<&'a str>,
}

/// GeoIP2 Asn record
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Asn<'a> {
    pub autonomous_system_number: Option<u32>,
    pub autonomous_system_organization: Option<&'a str>,
}

/// Country model structs
pub mod country {
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Continent<'a> {
        pub code: Option<&'a str>,
        pub geoname_id: Option<u32>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Country<'a> {
        pub geoname_id: Option<u32>,
        pub is_in_european_union: Option<bool>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct RepresentedCountry<'a> {
        pub geoname_id: Option<u32>,
        pub is_in_european_union: Option<bool>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
        #[serde(rename = "type")]
        pub representation_type: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Traits {
        pub is_anonymous_proxy: Option<bool>,
        pub is_satellite_provider: Option<bool>,
    }
}

/// Country model structs
pub mod city {
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    pub use super::country::{Continent, Country, RepresentedCountry, Traits};

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct City<'a> {
        pub geoname_id: Option<u32>,
        #[serde(borrow)]
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Location<'a> {
        pub accuracy_radius: Option<u16>,
        pub latitude: Option<f64>,
        pub longitude: Option<f64>,
        pub metro_code: Option<u16>,
        pub time_zone: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Postal<'a> {
        pub code: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Subdivision<'a> {
        pub geoname_id: Option<u32>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }
}

/// Enterprise model structs
pub mod enterprise {
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    pub use super::country::{Continent, RepresentedCountry};

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct City<'a> {
        pub confidence: Option<u8>,
        pub geoname_id: Option<u32>,
        #[serde(borrow)]
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Country<'a> {
        pub confidence: Option<u8>,
        pub geoname_id: Option<u32>,
        pub is_in_european_union: Option<bool>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Location<'a> {
        pub accuracy_radius: Option<u16>,
        pub latitude: Option<f64>,
        pub longitude: Option<f64>,
        pub metro_code: Option<u16>,
        pub time_zone: Option<&'a str>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Postal<'a> {
        pub code: Option<&'a str>,
        pub confidence: Option<u8>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Subdivision<'a> {
        pub confidence: Option<u8>,
        pub geoname_id: Option<u32>,
        pub iso_code: Option<&'a str>,
        pub names: Option<BTreeMap<&'a str, &'a str>>,
    }

    #[derive(Deserialize, Serialize, Clone, Debug)]
    pub struct Traits<'a> {
        pub autonomous_system_number: Option<u32>,
        pub autonomous_system_organization: Option<&'a str>,
        pub connection_type: Option<&'a str>,
        pub domain: Option<&'a str>,
        pub is_anonymous: Option<bool>,
        pub is_anonymous_proxy: Option<bool>,
        pub is_anonymous_vpn: Option<bool>,
        pub is_hosting_provider: Option<bool>,
        pub isp: Option<&'a str>,
        pub is_public_proxy: Option<bool>,
        pub is_residential_proxy: Option<bool>,
        pub is_satellite_provider: Option<bool>,
        pub is_tor_exit_node: Option<bool>,
        pub mobile_country_code: Option<&'a str>,
        pub mobile_network_code: Option<&'a str>,
        pub organization: Option<&'a str>,
        pub user_type: Option<&'a str>,
    }
}
<|endoftext|>


<commit_before>
//! Prepend another stream.

use event;
use modifier;
use transform;
use builder;

/// Prepends another stream after the current.
pub struct Prepend<S, N> {
    stream: modifier::Combine<N, S>,
}

impl<S, N> Prepend<S, N>
where
    S: event::Stream,
    N: event::Stream,
{
    pub(crate) fn new(stream: S, new_stream: N) -> Prepend<S, N> {
        Prepend {
            stream: modifier::Combine::new(new_stream, stream),
        }
    }
}

impl<S, N> event::Stream for Prepend<S, N>
where
    S: event::Stream,
    N: event::Stream,
{
    fn next_event(&mut self) -> event::StreamResult {
        self.stream.next_event()
    }
}

/// Prepends another stream to the contents of the current element.
pub struct PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    stream: modifier::select::SelectContent<S, Builder<N>>,
}

impl<S, N> PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    pub(crate) fn new(stream: S, new_stream: N) -> PrependContent<S, N> {
        PrependContent {
            stream: modifier::select::SelectContent::new(stream, Builder { new_stream }),
        }
    }
}

impl<S, N> event::ElementStream for PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{}

impl<S, N> event::Stream for PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    fn next_event(&mut self) -> event::StreamResult {
        self.stream.next_event()
    }
}

struct Builder<N> {
    new_stream: N,
}

impl<S, N> builder::BuildOnce<modifier::select::CurrentContent<S>> for Builder<N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    type Stream = Prepend<modifier::select::CurrentContent<S>, N>;

    fn build_once(self, stream: transform::Api<modifier::select::CurrentContent<S>>)
    -> transform::Api<Self::Stream> {
        transform::Api::pack(Prepend::new(stream.unpack(), self.new_stream))
    }
}

#[cfg(test)]
mod tests {
    use std::str::{ FromStr };

    #[test]
    fn prepend_contents() {
        let new = "foo";
        let new_template = ::Template::from_str(new, Default::default()).unwrap();
        test_transform!(
            Default::default(),
            "23<c>42</c>93",
            "23<c>foo42</c>93",
            |html| html
                .select(::select::Tag::from_str("c").unwrap(), |html| html
                    .prepend_contents(&new_template)
                )
        );
    }

    #[test]
    fn prepend() {
        let new = "foo";
        let new_template = ::Template::from_str(new, Default::default()).unwrap();
        test_transform!(
            Default::default(),
            "23<c>42</c>93",
            "23foo<c>42</c>93",
            |html| html
                .select(::select::Tag::from_str("c").unwrap(), |html| html
                    .prepend(&new_template)
                )
        );
    }
}
<commit_msg>moved prepend to new test structure<commit_after>
//! Prepend another stream.

use event;
use modifier;
use transform;
use builder;

/// Prepends another stream after the current.
pub struct Prepend<S, N> {
    stream: modifier::Combine<N, S>,
}

impl<S, N> Prepend<S, N>
where
    S: event::Stream,
    N: event::Stream,
{
    pub(crate) fn new(stream: S, new_stream: N) -> Prepend<S, N> {
        Prepend {
            stream: modifier::Combine::new(new_stream, stream),
        }
    }
}

impl<S, N> event::Stream for Prepend<S, N>
where
    S: event::Stream,
    N: event::Stream,
{
    fn next_event(&mut self) -> event::StreamResult {
        self.stream.next_event()
    }
}

/// Prepends another stream to the contents of the current element.
pub struct PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    stream: modifier::select::SelectContent<S, Builder<N>>,
}

impl<S, N> PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    pub(crate) fn new(stream: S, new_stream: N) -> PrependContent<S, N> {
        PrependContent {
            stream: modifier::select::SelectContent::new(stream, Builder { new_stream }),
        }
    }
}

impl<S, N> event::ElementStream for PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{}

impl<S, N> event::Stream for PrependContent<S, N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    fn next_event(&mut self) -> event::StreamResult {
        self.stream.next_event()
    }
}

struct Builder<N> {
    new_stream: N,
}

impl<S, N> builder::BuildOnce<modifier::select::CurrentContent<S>> for Builder<N>
where
    S: event::ElementStream,
    N: event::Stream,
{
    type Stream = Prepend<modifier::select::CurrentContent<S>, N>;

    fn build_once(self, stream: transform::Api<modifier::select::CurrentContent<S>>)
    -> transform::Api<Self::Stream> {
        transform::Api::pack(Prepend::new(stream.unpack(), self.new_stream))
    }
}

#[cfg(test)]
mod tests {

    test_group!(prepend_contents:
        "prepend to existing" => transform_test!(
            "23<c>42</c>93",
            "23<c>foo42</c>93",
            |html| html.select("c", |html| html.prepend_contents("foo")),
        ),
        "prepend to existing" => transform_test!(
            "23<c></c>93",
            "23<c>foo</c>93",
            |html| html.select("c", |html| html.prepend_contents("foo")),
        ),
    );

    test_group!(prepend:
        "prepend" => transform_test!(
            "23<c>42</c>93",
            "23foo<c>42</c>93",
            |html| html.select("c", |html| html.prepend("foo")),
        ),
    );
}
<|endoftext|>


<commit_before>use nannou::prelude::*;

fn main() {
    nannou::app(model).update(update).view(view).run();
}

struct Model {
    a: WindowId,
    b: WindowId,
    c: WindowId,
}

fn model(app: &App) -> Model {
    let a = app
        .new_window()
        .with_title("window a")
        .event(event_a)
        .build()
        .unwrap();
    let b = app
        .new_window()
        .with_title("window b")
        .event(event_b)
        .build()
        .unwrap();
    let c = app
        .new_window()
        .with_title("window c")
        .event(event_c)
        .build()
        .unwrap();
    Model { a, b, c }
}

fn update(_app: &App, _model: &mut Model, _update: Update) {}

fn event_a(_app: &App, _model: &mut Model, event: WindowEvent) {
    println!("window a: {:?}", event);
}

fn event_b(_app: &App, _model: &mut Model, event: WindowEvent) {
    println!("window b: {:?}", event);
}

fn event_c(_app: &App, _model: &mut Model, event: WindowEvent) {
    println!("window c: {:?}", event);
}

fn view(_app: &App, model: &Model, frame: &Frame) {
    match frame.window_id() {
        id if id == model.a => frame.clear(RED),
        id if id == model.b => frame.clear(GREEN),
        id if id == model.c => frame.clear(BLUE),
        _ => (),
    }
}
<commit_msg>Make multi_window example colors less abrasive<commit_after>use nannou::prelude::*;

fn main() {
    nannou::app(model).update(update).view(view).run();
}

struct Model {
    a: WindowId,
    b: WindowId,
    c: WindowId,
}

fn model(app: &App) -> Model {
    let a = app
        .new_window()
        .with_title("window a")
        .event(event_a)
        .build()
        .unwrap();
    let b = app
        .new_window()
        .with_title("window b")
        .event(event_b)
        .build()
        .unwrap();
    let c = app
        .new_window()
        .with_title("window c")
        .event(event_c)
        .build()
        .unwrap();
    Model { a, b, c }
}

fn update(_app: &App, _model: &mut Model, _update: Update) {}

fn event_a(_app: &App, _model: &mut Model, event: WindowEvent) {
    println!("window a: {:?}", event);
}

fn event_b(_app: &App, _model: &mut Model, event: WindowEvent) {
    println!("window b: {:?}", event);
}

fn event_c(_app: &App, _model: &mut Model, event: WindowEvent) {
    println!("window c: {:?}", event);
}

fn view(_app: &App, model: &Model, frame: &Frame) {
    match frame.window_id() {
        id if id == model.a => frame.clear(INDIANRED),
        id if id == model.b => frame.clear(LIGHTGREEN),
        id if id == model.c => frame.clear(CORNFLOWERBLUE),
        _ => (),
    }
}
<|endoftext|>


<commit_before>//! Describe type of surface content

///  cairo_content_t is used to describe the content that a surface will contain, whether color information, alpha information (translucence vs. opacity), or both.
///
/// Note: The large values here are designed to keep cairo_content_t values distinct from cairo_format_t values so that the implementation can detect the error if users confuse the two types.
///
/// Since 1.0
#[repr(i32)]
pub enum Content {
  /// The surface will hold color content only. (Since 1.0)
  Color = 0x1000,
  /// The surface will hold alpha content only. (Since 1.0)
  Alpha = 0x2000,
  /// The surface will hold color and alpha content. (Since 1.0)
  ColorAlpha = 0x3000
}

<commit_msg>Replaced Cairo '_t' types with Rust-Cairo types<commit_after>//! Describe type of surface content

/// surface::content::Content is used to describe the content that a surface will contain, whether color information, alpha information (translucence vs. opacity), or both.
///
/// Note: The large values here are designed to keep surface::content::Content values distinct from surface::format::Format values so that the implementation can detect the error if users confuse the two types.
///
/// Since 1.0
#[repr(i32)]
pub enum Content {
  /// The surface will hold color content only. (Since 1.0)
  Color = 0x1000,
  /// The surface will hold alpha content only. (Since 1.0)
  Alpha = 0x2000,
  /// The surface will hold color and alpha content. (Since 1.0)
  ColorAlpha = 0x3000
}

<|endoftext|>


<commit_before>use std::vec;
use nalgebra::mat::Translation;
use nalgebra::vec::{Dim, VecExt};
use partitioning::bvt_visitor::BVTVisitor;
use bounding_volume::{BoundingVolume, AABB};

/// A Boundig Volume Tree.
#[deriving(Encodable, Decodable)]
pub struct BVT<B, BV> {
    priv tree: Option<BVTNode<B, BV>>
}

#[deriving(Encodable, Decodable)]
enum BVTNode<B, BV> {
    Internal(BV, ~[BVTNode<B, BV>]),
    Leaf(BV, B)
}

type PartFnResult<B, BV> = (BV, Either<B, ~[~[(B, BV)]]>);

impl<B, BV> BVT<B, BV> {
    /// Builds a bounding volume tree using an user-defined construction function.
    pub fn new_with_partitioner(leaves:      ~[(B, BV)],
                                partitioner: @fn(~[(B, BV)]) -> PartFnResult<B, BV>)
                                -> BVT<B, BV> {
        if leaves.len() == 0 {
            BVT {
                tree: None
            }
        }
        else {
            BVT {
                tree: Some(new_with_partitioner(leaves, partitioner))
            }
        }
    }

    /// Visit this tree using… a visitor!
    pub fn visit<Vis: BVTVisitor<B, BV>>(&self, visitor: &mut Vis) {
        match self.tree {
            Some(ref t) => t.visit(visitor),
            None        => { }
        }
    }

    /// Visit this tree using… a visitor! Visitor arguments are mutable.
    pub fn visit_mut<Vis: BVTVisitor<B, BV>>(&mut self, visitor: &mut Vis) {
        match self.tree {
            Some(ref mut t) => t.visit(visitor),
            None        => { }
        }
    }
}

impl<B, BV> BVTNode<B, BV> {
    fn visit<Vis: BVTVisitor<B, BV>>(&self, visitor: &mut Vis) {
        match *self {
            Internal(ref bv, ref children) => {
                if visitor.visit_internal(bv) {
                    for child in children.iter() {
                        child.visit(visitor)
                    }
                }
            },
            Leaf(ref bv, ref b) => {
                visitor.visit_leaf(b, bv);
            }
        }
    }

    fn visit_mut<Vis: BVTVisitor<B, BV>>(&mut self, visitor: &mut Vis) {
        match *self {
            Internal(ref mut bv, ref mut children) => {
                if visitor.visit_internal_mut(bv) {
                    for child in children.mut_iter() {
                        child.visit_mut(visitor)
                    }
                }
            },
            Leaf(ref mut bv, ref mut b) => {
                visitor.visit_leaf_mut(b, bv);
            }
        }
    }
}

/// Construction function for quadtree in 2d, an octree in 4d, and a 2^n tree in n-d. Use this as a
/// parameter of `new_with_partitioner`.
pub fn dim_pow_2_aabb_partitioner<N: Primitive + Orderable + NumCast + Signed + ToStr,
                                  V: VecExt<N> + ToStr,
                                  B>(leaves: ~[(B, AABB<N, V>)])
                                  -> PartFnResult<B, AABB<N, V>> {
    println("nleaves: " + leaves.len().to_str());
    if leaves.len() == 0 {
        fail!("Cannot build a tree without leaves.");
    }
    else if leaves.len() == 1 {
        let (b, aabb) = leaves[0];
        (aabb, Left(b))
    }
    else {
        let mut rl = false;
        // merge all bounding boxes
        let bounding_bounding_box =
            do leaves.iter().fold(AABB::new_invalid()) |curr_aabb, &(_, ref other_aabb)| {
                curr_aabb.merged(other_aabb)
            };

        let center = bounding_bounding_box.translation();

        // build the partitions
        let mut partitions = vec::from_fn(1u << Dim::dim(None::<V>), |_| ~[]);
        for (b, aabb) in leaves.move_iter() {
            let dpos    = aabb.translation() - center;
            println("dpos: " + dpos.to_str());
            let mut key = 0u;

            for i in range(0u, Dim::dim(None::<V>)) {
                if dpos.at(i).is_negative() {
                    key = key | (1u << i);
                }
                else if dpos.at(i).is_zero() {
                    rl = !rl;
                    if rl {
                        key = key | (1u << i);
                    }
                }
            }

            partitions[key].push((b, aabb))
        }

        (bounding_bounding_box, Right(partitions))
    }
}

fn new_with_partitioner<B, BV>(leaves:      ~[(B, BV)],
                               partitioner: @fn(~[(B, BV)]) -> PartFnResult<B, BV>)
                               -> BVTNode<B, BV> {
    let (bv, partitions) = partitioner(leaves);

    match partitions {
        Left(b)      => Leaf(bv, b),
        Right(parts) => {
            let mut children = ~[];

            for part in parts.move_iter() {
                if part.len() != 0 {
                    children.push(new_with_partitioner(part, partitioner))
                }
            }

            Internal(bv, children)
        }
    }
}
<commit_msg>Fix a cause of infinite recursion on the quadtree/octree builder.<commit_after>use std::vec;
use nalgebra::mat::Translation;
use nalgebra::vec::{Dim, VecExt};
use partitioning::bvt_visitor::BVTVisitor;
use bounding_volume::{BoundingVolume, AABB};

/// A Boundig Volume Tree.
#[deriving(Encodable, Decodable)]
pub struct BVT<B, BV> {
    priv tree: Option<BVTNode<B, BV>>
}

#[deriving(Encodable, Decodable)]
enum BVTNode<B, BV> {
    Internal(BV, ~[BVTNode<B, BV>]),
    Leaf(BV, B)
}

type PartFnResult<B, BV> = (BV, Either<B, ~[~[(B, BV)]]>);

impl<B, BV> BVT<B, BV> {
    /// Builds a bounding volume tree using an user-defined construction function.
    pub fn new_with_partitioner(leaves:      ~[(B, BV)],
                                partitioner: @fn(~[(B, BV)]) -> PartFnResult<B, BV>)
                                -> BVT<B, BV> {
        if leaves.len() == 0 {
            BVT {
                tree: None
            }
        }
        else {
            BVT {
                tree: Some(new_with_partitioner(leaves, partitioner))
            }
        }
    }

    /// Visit this tree using… a visitor!
    pub fn visit<Vis: BVTVisitor<B, BV>>(&self, visitor: &mut Vis) {
        match self.tree {
            Some(ref t) => t.visit(visitor),
            None        => { }
        }
    }

    /// Visit this tree using… a visitor! Visitor arguments are mutable.
    pub fn visit_mut<Vis: BVTVisitor<B, BV>>(&mut self, visitor: &mut Vis) {
        match self.tree {
            Some(ref mut t) => t.visit(visitor),
            None        => { }
        }
    }
}

impl<B, BV> BVTNode<B, BV> {
    fn visit<Vis: BVTVisitor<B, BV>>(&self, visitor: &mut Vis) {
        match *self {
            Internal(ref bv, ref children) => {
                if visitor.visit_internal(bv) {
                    for child in children.iter() {
                        child.visit(visitor)
                    }
                }
            },
            Leaf(ref bv, ref b) => {
                visitor.visit_leaf(b, bv);
            }
        }
    }

    fn visit_mut<Vis: BVTVisitor<B, BV>>(&mut self, visitor: &mut Vis) {
        match *self {
            Internal(ref mut bv, ref mut children) => {
                if visitor.visit_internal_mut(bv) {
                    for child in children.mut_iter() {
                        child.visit_mut(visitor)
                    }
                }
            },
            Leaf(ref mut bv, ref mut b) => {
                visitor.visit_leaf_mut(b, bv);
            }
        }
    }
}

/// Construction function for quadtree in 2d, an octree in 4d, and a 2^n tree in n-d. Use this as a
/// parameter of `new_with_partitioner`.
pub fn dim_pow_2_aabb_partitioner<N: Primitive + Orderable + NumCast + Signed + ToStr,
                                  V: VecExt<N> + ToStr,
                                  B>(leaves: ~[(B, AABB<N, V>)])
                                  -> PartFnResult<B, AABB<N, V>> {
    if leaves.len() == 0 {
        fail!("Cannot build a tree without leaves.");
    }
    else if leaves.len() == 1 {
        let (b, aabb) = leaves[0];
        (aabb, Left(b))
    }
    else {
        let mut rl = false;
        // merge all bounding boxes
        let bounding_bounding_box =
            do leaves.iter().fold(AABB::new_invalid()) |curr_aabb, &(_, ref other_aabb)| {
                curr_aabb.merged(other_aabb)
            };

        let center = bounding_bounding_box.translation();

        // build the partitions
        let mut partitions = vec::from_fn(1u << Dim::dim(None::<V>), |_| ~[]);
        for (b, aabb) in leaves.move_iter() {
            let dpos    = aabb.translation() - center;
            let mut key = 0u;

            for i in range(0u, Dim::dim(None::<V>)) {
                if dpos.at(i).is_negative() {
                    key = key | (1u << i);
                }
                else if dpos.at(i).is_zero() {
                    if i == 0u { rl = !rl }
                    if rl {
                        key = key | (1u << i);
                    }
                }
            }

            partitions[key].push((b, aabb))
        }

        (bounding_bounding_box, Right(partitions))
    }
}

fn new_with_partitioner<B, BV>(leaves:      ~[(B, BV)],
                               partitioner: @fn(~[(B, BV)]) -> PartFnResult<B, BV>)
                               -> BVTNode<B, BV> {
    let (bv, partitions) = partitioner(leaves);

    match partitions {
        Left(b)      => Leaf(bv, b),
        Right(parts) => {
            let mut children = ~[];

            for part in parts.move_iter() {
                if part.len() != 0 {
                    children.push(new_with_partitioner(part, partitioner))
                }
            }

            Internal(bv, children)
        }
    }
}
<|endoftext|>


<commit_before>use crate::build_utils;
use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::geth_genesis_json;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use std::{env, fs::File};
use tempfile::TempDir;
use unused_port::unused_tcp_port;

// const GETH_BRANCH: &str = "master";
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";

pub fn build_result(repo_dir: &Path) -> Output {
    Command::new("make")
        .arg("geth")
        .current_dir(&repo_dir)
        .output()
        .expect("failed to make geth")
}

pub fn build(execution_clients_dir: &Path) {
    let repo_dir = execution_clients_dir.join("go-ethereum");

    if !repo_dir.exists() {
        // Clone the repo
        build_utils::clone_repo(execution_clients_dir, GETH_REPO_URL).unwrap();
    }

    // TODO: this should be set back to the latest release once the following issue is resolved:
    //
    // - https://github.com/ethereum/go-ethereum/issues/25427
    //
    // Get the latest tag on the branch
    // let last_release = build_utils::get_latest_release(&repo_dir, GETH_BRANCH).unwrap();
    let last_release = "v1.10.20";
    build_utils::checkout(&repo_dir, dbg!(&last_release)).unwrap();

    // Build geth
    build_utils::check_command_output(build_result(&repo_dir), || {
        format!("geth make failed using release {last_release}")
    });
}

/*
 * Geth-specific Implementation for GenericExecutionEngine
 */

#[derive(Clone)]
pub struct GethEngine;

impl GethEngine {
    fn binary_path() -> PathBuf {
        let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
        manifest_dir
            .join("execution_clients")
            .join("go-ethereum")
            .join("build")
            .join("bin")
            .join("geth")
    }
}

impl GenericExecutionEngine for GethEngine {
    fn init_datadir() -> TempDir {
        let datadir = TempDir::new().unwrap();

        let genesis_json_path = datadir.path().join("genesis.json");
        let mut file = File::create(&genesis_json_path).unwrap();
        let json = geth_genesis_json();
        serde_json::to_writer(&mut file, &json).unwrap();

        let output = Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("init")
            .arg(genesis_json_path.to_str().unwrap())
            .output()
            .expect("failed to init geth");

        build_utils::check_command_output(output, || "geth init failed".into());

        datadir
    }

    fn start_client(
        datadir: &TempDir,
        http_port: u16,
        http_auth_port: u16,
        jwt_secret_path: PathBuf,
    ) -> Child {
        let network_port = unused_tcp_port().unwrap();

        Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("--http")
            .arg("--http.api")
            .arg("engine,eth,personal")
            .arg("--http.port")
            .arg(http_port.to_string())
            .arg("--authrpc.port")
            .arg(http_auth_port.to_string())
            .arg("--port")
            .arg(network_port.to_string())
            .arg("--allow-insecure-unlock")
            .arg("--authrpc.jwtsecret")
            .arg(jwt_secret_path.as_path().to_str().unwrap())
            .stdout(build_utils::build_stdio())
            .stderr(build_utils::build_stdio())
            .spawn()
            .expect("failed to start geth")
    }
}
<commit_msg>Use latest Geth release in EE integration tests (#3395)<commit_after>use crate::build_utils;
use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::geth_genesis_json;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use std::{env, fs::File};
use tempfile::TempDir;
use unused_port::unused_tcp_port;

const GETH_BRANCH: &str = "master";
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";

pub fn build_result(repo_dir: &Path) -> Output {
    Command::new("make")
        .arg("geth")
        .current_dir(&repo_dir)
        .output()
        .expect("failed to make geth")
}

pub fn build(execution_clients_dir: &Path) {
    let repo_dir = execution_clients_dir.join("go-ethereum");

    if !repo_dir.exists() {
        // Clone the repo
        build_utils::clone_repo(execution_clients_dir, GETH_REPO_URL).unwrap();
    }

    // Get the latest tag on the branch
    let last_release = build_utils::get_latest_release(&repo_dir, GETH_BRANCH).unwrap();
    build_utils::checkout(&repo_dir, dbg!(&last_release)).unwrap();

    // Build geth
    build_utils::check_command_output(build_result(&repo_dir), || {
        format!("geth make failed using release {last_release}")
    });
}

/*
 * Geth-specific Implementation for GenericExecutionEngine
 */

#[derive(Clone)]
pub struct GethEngine;

impl GethEngine {
    fn binary_path() -> PathBuf {
        let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
        manifest_dir
            .join("execution_clients")
            .join("go-ethereum")
            .join("build")
            .join("bin")
            .join("geth")
    }
}

impl GenericExecutionEngine for GethEngine {
    fn init_datadir() -> TempDir {
        let datadir = TempDir::new().unwrap();

        let genesis_json_path = datadir.path().join("genesis.json");
        let mut file = File::create(&genesis_json_path).unwrap();
        let json = geth_genesis_json();
        serde_json::to_writer(&mut file, &json).unwrap();

        let output = Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("init")
            .arg(genesis_json_path.to_str().unwrap())
            .output()
            .expect("failed to init geth");

        build_utils::check_command_output(output, || "geth init failed".into());

        datadir
    }

    fn start_client(
        datadir: &TempDir,
        http_port: u16,
        http_auth_port: u16,
        jwt_secret_path: PathBuf,
    ) -> Child {
        let network_port = unused_tcp_port().unwrap();

        Command::new(Self::binary_path())
            .arg("--datadir")
            .arg(datadir.path().to_str().unwrap())
            .arg("--http")
            .arg("--http.api")
            .arg("engine,eth,personal")
            .arg("--http.port")
            .arg(http_port.to_string())
            .arg("--authrpc.port")
            .arg(http_auth_port.to_string())
            .arg("--port")
            .arg(network_port.to_string())
            .arg("--allow-insecure-unlock")
            .arg("--authrpc.jwtsecret")
            .arg(jwt_secret_path.as_path().to_str().unwrap())
            // This flag is required to help Geth perform reliably when feeding it blocks
            // one-by-one. For more information, see:
            //
            // https://github.com/sigp/lighthouse/pull/3382#issuecomment-1197680345
            .arg("--syncmode=full")
            .stdout(build_utils::build_stdio())
            .stderr(build_utils::build_stdio())
            .spawn()
            .expect("failed to start geth")
    }
}
<|endoftext|>


<commit_before>use protobuf::descriptor::field_descriptor_proto;

use crate::gen::code_writer::CodeWriter;
use crate::gen::field::FieldElem;
use crate::gen::field::FieldElemEnum;
use crate::gen::field::FieldGen;
use crate::gen::field::FieldKind;
use crate::gen::field::MapField;
use crate::gen::field::OptionKind;
use crate::gen::field::RepeatedField;
use crate::gen::field::RepeatedFieldKind;
use crate::gen::field::SingularField;
use crate::gen::field::SingularFieldFlag;
use crate::gen::inside::protobuf_crate_path;
use crate::gen::oneof::OneofField;
use crate::gen::rust_types_values::RustType;
use crate::gen::scope::WithScope;

struct AccessorFn {
    name: String,
    // function type params after first underscore
    type_params: Vec<String>,
    callback_params: Vec<String>,
}

impl AccessorFn {
    fn sig(&self) -> String {
        let mut s = self.name.clone();
        s.push_str("::<_");
        for p in &self.type_params {
            s.push_str(", ");
            s.push_str(&p);
        }
        s.push_str(">");
        s
    }
}

impl FieldGen<'_> {
    fn make_accessor_fns_lambda(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
            format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_lambda_get(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
            format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_lambda_default_value(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
            format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
            format!("{}", self.xxx_default_value_rust()),
        ]
    }

    fn make_accessor_fns_has_get(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("{}::has_{}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_has_get_set(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("{}::has_{}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
            format!("{}::set_{}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_has_get_mut_set(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("{}::has_{}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
            format!("{}::mut_{}", message, self.rust_name),
            format!("{}::set_{}", message, self.rust_name),
        ]
    }

    fn accessor_fn_map(&self, map_field: &MapField) -> AccessorFn {
        let MapField { .. } = map_field;
        AccessorFn {
            name: "make_map_simpler_accessor".to_owned(),
            type_params: vec![format!("_"), format!("_")],
            callback_params: self.make_accessor_fns_lambda(),
        }
    }

    fn accessor_fn_repeated(&self, repeated_field: &RepeatedField) -> AccessorFn {
        let RepeatedField { .. } = repeated_field;
        let name = match repeated_field.kind() {
            RepeatedFieldKind::Vec => "make_vec_simpler_accessor",
        };
        AccessorFn {
            name: name.to_owned(),
            type_params: vec![format!("_")],
            callback_params: self.make_accessor_fns_lambda(),
        }
    }

    fn accessor_fn_oneof_enum(&self, oneof: &OneofField, en: &FieldElemEnum) -> AccessorFn {
        let message = self.proto_field.message.rust_name();

        let variant_path = oneof.variant_path(
            &self
                .proto_field
                .message
                .scope
                .rust_path_to_file()
                .clone()
                .into_path(),
        );

        let getter = CodeWriter::with_no_error(|w| {
            w.expr_block(
                &format!(
                    "|message: &{}| match &message.{}",
                    message, oneof.oneof_field_name
                ),
                |w| {
                    w.case_expr(
                        &format!("::std::option::Option::Some({}(e))", variant_path),
                        "::std::option::Option::Some(*e)",
                    );
                    w.case_expr("_", "::std::option::Option::None");
                },
            );
        });

        let setter = CodeWriter::with_no_error(|w| {
            w.expr_block(
                &format!(
                    "|message: &mut {}, e: {}::EnumOrUnknown<{}>|",
                    message,
                    protobuf_crate_path(&self.customize),
                    en.enum_rust_type(&self.file_and_mod())
                        .to_code(&self.customize)
                ),
                |w| {
                    w.write_line(&format!(
                        "message.{} = ::std::option::Option::Some({}(e));",
                        oneof.oneof_field_name, variant_path
                    ));
                },
            )
        });

        let default = self.xxx_default_value_rust();

        AccessorFn {
            name: "make_oneof_enum_accessors".to_owned(),
            type_params: vec![format!("_")],
            callback_params: vec![getter, setter, default],
        }
    }

    fn accessor_fn_singular_without_flag(&self, elem: &FieldElem) -> AccessorFn {
        if let &FieldElem::Message(ref m, ..) = elem {
            // TODO: old style, needed because of default instance

            AccessorFn {
                name: "make_singular_message_accessor".to_owned(),
                type_params: vec![format!("{}", m.rust_name_relative(&self.file_and_mod()))],
                callback_params: self.make_accessor_fns_has_get(),
            }
        } else {
            AccessorFn {
                name: "make_simpler_field_accessor".to_owned(),
                type_params: vec![format!("_")],
                callback_params: self.make_accessor_fns_lambda(),
            }
        }
    }

    fn accessor_fn_singular_with_flag(
        &self,
        elem: &FieldElem,
        _option_kind: OptionKind,
    ) -> AccessorFn {
        match elem {
            FieldElem::Message(m) => AccessorFn {
                name: "make_message_field_accessor".to_owned(),
                type_params: vec![format!("{}", m.rust_name_relative(&self.file_and_mod()))],
                callback_params: self.make_accessor_fns_lambda(),
            },
            FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)
            | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => AccessorFn {
                name: "make_option_get_ref_simpler_accessor".to_owned(),
                type_params: vec!["_".to_owned()],
                callback_params: self.make_accessor_fns_lambda_get(),
            },
            FieldElem::Primitive(..) => AccessorFn {
                name: "make_option_get_copy_simpler_accessor".to_owned(),
                type_params: vec!["_".to_owned()],
                callback_params: self.make_accessor_fns_lambda_get(),
            },
            FieldElem::Enum(ref en) => AccessorFn {
                name: "make_option_enum_accessor".to_owned(),
                type_params: vec![format!("{}", en.rust_name_relative(&self.file_and_mod()))],
                callback_params: self.make_accessor_fns_lambda_default_value(),
            },
            FieldElem::Group => {
                unreachable!("no accessor for group field");
            }
        }
    }

    fn accessor_fn_oneof(&self, oneof: &OneofField) -> AccessorFn {
        let OneofField { ref elem, .. } = oneof;
        // TODO: uses old style

        let reference = self
            .proto_field
            .message
            .scope
            .file_and_mod(self.customize.clone());

        if let FieldElem::Enum(en) = &oneof.elem {
            return self.accessor_fn_oneof_enum(oneof, en);
        }

        if elem.is_copy() {
            return AccessorFn {
                name: "make_oneof_copy_has_get_set_simpler_accessors".to_owned(),
                type_params: vec![format!("_")],
                callback_params: self.make_accessor_fns_has_get_set(),
            };
        }

        if let RustType::Message(name) = elem.rust_storage_elem_type(&reference) {
            return AccessorFn {
                name: "make_oneof_message_has_get_mut_set_accessor".to_owned(),
                type_params: vec![format!("{}", name)],
                callback_params: self.make_accessor_fns_has_get_mut_set(),
            };
        }

        // string or bytes
        AccessorFn {
            name: "make_oneof_deref_has_get_set_simpler_accessor".to_owned(),
            type_params: vec![format!("_")],
            callback_params: self.make_accessor_fns_has_get_set(),
        }
    }

    fn accessor_fn(&self) -> AccessorFn {
        match self.kind {
            FieldKind::Repeated(ref repeated_field) => self.accessor_fn_repeated(repeated_field),
            FieldKind::Map(ref map_field) => self.accessor_fn_map(map_field),
            FieldKind::Singular(SingularField {
                ref elem,
                flag: SingularFieldFlag::WithoutFlag,
            }) => self.accessor_fn_singular_without_flag(elem),
            FieldKind::Singular(SingularField {
                ref elem,
                flag: SingularFieldFlag::WithFlag { option_kind, .. },
            }) => self.accessor_fn_singular_with_flag(elem, option_kind),
            FieldKind::Oneof(ref oneof) => self.accessor_fn_oneof(oneof),
        }
    }

    pub fn write_descriptor_field(&self, fields_var: &str, w: &mut CodeWriter) {
        let accessor_fn = self.accessor_fn();
        w.write_line(&format!(
            "{}.push({}::reflect::rt::v2::{}(",
            fields_var,
            protobuf_crate_path(&self.customize),
            accessor_fn.sig()
        ));
        w.indented(|w| {
            w.write_line(&format!("\"{}\",", self.proto_field.name()));
            for callback in &accessor_fn.callback_params {
                let callback_lines: Vec<&str> = callback.lines().collect();
                for (i, callback_line) in callback_lines.iter().enumerate() {
                    let comma = if i == callback_lines.len() - 1 {
                        ","
                    } else {
                        ""
                    };
                    w.write_line(&format!("{}{}", callback_line, comma));
                }
            }
        });
        w.write_line("));");
    }
}
<commit_msg>Remove some dead code<commit_after>use protobuf::descriptor::field_descriptor_proto;

use crate::gen::code_writer::CodeWriter;
use crate::gen::field::FieldElem;
use crate::gen::field::FieldElemEnum;
use crate::gen::field::FieldGen;
use crate::gen::field::FieldKind;
use crate::gen::field::MapField;
use crate::gen::field::OptionKind;
use crate::gen::field::RepeatedField;
use crate::gen::field::RepeatedFieldKind;
use crate::gen::field::SingularField;
use crate::gen::field::SingularFieldFlag;
use crate::gen::inside::protobuf_crate_path;
use crate::gen::oneof::OneofField;
use crate::gen::rust_types_values::RustType;
use crate::gen::scope::WithScope;

struct AccessorFn {
    name: String,
    // function type params after first underscore
    type_params: Vec<String>,
    callback_params: Vec<String>,
}

impl AccessorFn {
    fn sig(&self) -> String {
        let mut s = self.name.clone();
        s.push_str("::<_");
        for p in &self.type_params {
            s.push_str(", ");
            s.push_str(&p);
        }
        s.push_str(">");
        s
    }
}

impl FieldGen<'_> {
    fn make_accessor_fns_lambda(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
            format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_lambda_get(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
            format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_lambda_default_value(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
            format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
            format!("{}", self.xxx_default_value_rust()),
        ]
    }

    fn make_accessor_fns_has_get_set(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("{}::has_{}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
            format!("{}::set_{}", message, self.rust_name),
        ]
    }

    fn make_accessor_fns_has_get_mut_set(&self) -> Vec<String> {
        let message = self.proto_field.message.rust_name();
        vec![
            format!("{}::has_{}", message, self.rust_name),
            format!("{}::{}", message, self.rust_name),
            format!("{}::mut_{}", message, self.rust_name),
            format!("{}::set_{}", message, self.rust_name),
        ]
    }

    fn accessor_fn_map(&self, map_field: &MapField) -> AccessorFn {
        let MapField { .. } = map_field;
        AccessorFn {
            name: "make_map_simpler_accessor".to_owned(),
            type_params: vec![format!("_"), format!("_")],
            callback_params: self.make_accessor_fns_lambda(),
        }
    }

    fn accessor_fn_repeated(&self, repeated_field: &RepeatedField) -> AccessorFn {
        let RepeatedField { .. } = repeated_field;
        let name = match repeated_field.kind() {
            RepeatedFieldKind::Vec => "make_vec_simpler_accessor",
        };
        AccessorFn {
            name: name.to_owned(),
            type_params: vec![format!("_")],
            callback_params: self.make_accessor_fns_lambda(),
        }
    }

    fn accessor_fn_oneof_enum(&self, oneof: &OneofField, en: &FieldElemEnum) -> AccessorFn {
        let message = self.proto_field.message.rust_name();

        let variant_path = oneof.variant_path(
            &self
                .proto_field
                .message
                .scope
                .rust_path_to_file()
                .clone()
                .into_path(),
        );

        let getter = CodeWriter::with_no_error(|w| {
            w.expr_block(
                &format!(
                    "|message: &{}| match &message.{}",
                    message, oneof.oneof_field_name
                ),
                |w| {
                    w.case_expr(
                        &format!("::std::option::Option::Some({}(e))", variant_path),
                        "::std::option::Option::Some(*e)",
                    );
                    w.case_expr("_", "::std::option::Option::None");
                },
            );
        });

        let setter = CodeWriter::with_no_error(|w| {
            w.expr_block(
                &format!(
                    "|message: &mut {}, e: {}::EnumOrUnknown<{}>|",
                    message,
                    protobuf_crate_path(&self.customize),
                    en.enum_rust_type(&self.file_and_mod())
                        .to_code(&self.customize)
                ),
                |w| {
                    w.write_line(&format!(
                        "message.{} = ::std::option::Option::Some({}(e));",
                        oneof.oneof_field_name, variant_path
                    ));
                },
            )
        });

        let default = self.xxx_default_value_rust();

        AccessorFn {
            name: "make_oneof_enum_accessors".to_owned(),
            type_params: vec![format!("_")],
            callback_params: vec![getter, setter, default],
        }
    }

    fn accessor_fn_singular_without_flag(&self, _elem: &FieldElem) -> AccessorFn {
        AccessorFn {
            name: "make_simpler_field_accessor".to_owned(),
            type_params: vec![format!("_")],
            callback_params: self.make_accessor_fns_lambda(),
        }
    }

    fn accessor_fn_singular_with_flag(
        &self,
        elem: &FieldElem,
        _option_kind: OptionKind,
    ) -> AccessorFn {
        match elem {
            FieldElem::Message(m) => AccessorFn {
                name: "make_message_field_accessor".to_owned(),
                type_params: vec![format!("{}", m.rust_name_relative(&self.file_and_mod()))],
                callback_params: self.make_accessor_fns_lambda(),
            },
            FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)
            | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => AccessorFn {
                name: "make_option_get_ref_simpler_accessor".to_owned(),
                type_params: vec!["_".to_owned()],
                callback_params: self.make_accessor_fns_lambda_get(),
            },
            FieldElem::Primitive(..) => AccessorFn {
                name: "make_option_get_copy_simpler_accessor".to_owned(),
                type_params: vec!["_".to_owned()],
                callback_params: self.make_accessor_fns_lambda_get(),
            },
            FieldElem::Enum(ref en) => AccessorFn {
                name: "make_option_enum_accessor".to_owned(),
                type_params: vec![format!("{}", en.rust_name_relative(&self.file_and_mod()))],
                callback_params: self.make_accessor_fns_lambda_default_value(),
            },
            FieldElem::Group => {
                unreachable!("no accessor for group field");
            }
        }
    }

    fn accessor_fn_oneof(&self, oneof: &OneofField) -> AccessorFn {
        let OneofField { ref elem, .. } = oneof;
        // TODO: uses old style

        let reference = self
            .proto_field
            .message
            .scope
            .file_and_mod(self.customize.clone());

        if let FieldElem::Enum(en) = &oneof.elem {
            return self.accessor_fn_oneof_enum(oneof, en);
        }

        if elem.is_copy() {
            return AccessorFn {
                name: "make_oneof_copy_has_get_set_simpler_accessors".to_owned(),
                type_params: vec![format!("_")],
                callback_params: self.make_accessor_fns_has_get_set(),
            };
        }

        if let RustType::Message(name) = elem.rust_storage_elem_type(&reference) {
            return AccessorFn {
                name: "make_oneof_message_has_get_mut_set_accessor".to_owned(),
                type_params: vec![format!("{}", name)],
                callback_params: self.make_accessor_fns_has_get_mut_set(),
            };
        }

        // string or bytes
        AccessorFn {
            name: "make_oneof_deref_has_get_set_simpler_accessor".to_owned(),
            type_params: vec![format!("_")],
            callback_params: self.make_accessor_fns_has_get_set(),
        }
    }

    fn accessor_fn(&self) -> AccessorFn {
        match self.kind {
            FieldKind::Repeated(ref repeated_field) => self.accessor_fn_repeated(repeated_field),
            FieldKind::Map(ref map_field) => self.accessor_fn_map(map_field),
            FieldKind::Singular(SingularField {
                ref elem,
                flag: SingularFieldFlag::WithoutFlag,
            }) => self.accessor_fn_singular_without_flag(elem),
            FieldKind::Singular(SingularField {
                ref elem,
                flag: SingularFieldFlag::WithFlag { option_kind, .. },
            }) => self.accessor_fn_singular_with_flag(elem, option_kind),
            FieldKind::Oneof(ref oneof) => self.accessor_fn_oneof(oneof),
        }
    }

    pub fn write_descriptor_field(&self, fields_var: &str, w: &mut CodeWriter) {
        let accessor_fn = self.accessor_fn();
        w.write_line(&format!(
            "{}.push({}::reflect::rt::v2::{}(",
            fields_var,
            protobuf_crate_path(&self.customize),
            accessor_fn.sig()
        ));
        w.indented(|w| {
            w.write_line(&format!("\"{}\",", self.proto_field.name()));
            for callback in &accessor_fn.callback_params {
                let callback_lines: Vec<&str> = callback.lines().collect();
                for (i, callback_line) in callback_lines.iter().enumerate() {
                    let comma = if i == callback_lines.len() - 1 {
                        ","
                    } else {
                        ""
                    };
                    w.write_line(&format!("{}{}", callback_line, comma));
                }
            }
        });
        w.write_line("));");
    }
}
<|endoftext|>


<commit_before>// CITA
// Copyright 2016-2017 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use bytes::BytesMut;
use citaprotocol::pubsub_message_to_network_message;
use config;
use config::NetConfig;
use libproto::{Message, OperateType};
use notify::DebouncedEvent;
use std::convert::{TryFrom, TryInto};
use std::io::Write;
use std::net::TcpStream;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use std::thread;
use std::time::Duration;
use util::RwLock;

const TIMEOUT: u64 = 15;
type PeerPairs = Arc<RwLock<Vec<(u32, String, Option<TcpStream>)>>>;

pub struct Connection {
    pub id_card: u32,
    pub peers_pair: PeerPairs,
}

impl Connection {
    pub fn new(config: &config::NetConfig) -> Self {
        let id_card = config.id_card.unwrap();
        let mut peers_pair = Vec::default();
        if let Some(peers) = config.peers.as_ref() {
            for peer in peers.iter() {
                let id_card: u32 = peer.id_card.unwrap();
                let addr = format!("{}:{}", peer.ip.clone().unwrap(), peer.port.unwrap());
                let addr = addr.parse::<String>().unwrap();
                peers_pair.push((id_card, addr, None));
            }
        }

        Connection {
            id_card,
            peers_pair: Arc::new(RwLock::new(peers_pair)),
        }
    }

    pub fn is_send(id_card: u32, origin: u32, operate: OperateType) -> bool {
        operate == OperateType::Broadcast || (operate == OperateType::Single && id_card == origin)
            || (operate == OperateType::Subtract && origin != id_card)
    }

    pub fn update(&self, config: &config::NetConfig) {
        //添加更新的配置到self
        match config.peers.as_ref() {
            Some(peers) => {
                let mut peers_addr = Vec::new();
                for peer in self.peers_pair.read().iter() {
                    peers_addr.push(peer.1.clone());
                }
                info!("peers before update {:?}", peers_addr);
                let mut config_addr = Vec::new();
                for peer in peers.iter() {
                    let id_card: u32 = peer.id_card.unwrap();
                    let addr = format!("{}:{}", peer.ip.clone().unwrap(), peer.port.unwrap());
                    config_addr.push(addr.clone());
                    if peers_addr.contains(&addr) {
                        continue;
                    }
                    peers_addr.push(addr.clone());
                    self.peers_pair.write().push((id_card, addr, None));
                }
                loop {
                    let index_opt = peers_addr
                        .iter()
                        .position(|addr| !config_addr.contains(addr));
                    if let Some(index) = index_opt {
                        peers_addr.remove(index);
                        self.peers_pair.write().remove(index);
                    } else {
                        break;
                    }
                }
                info!("peers after update {:?}", peers_addr);
            }
            None => {
                info!("clear all peers after update!");
                self.peers_pair.write().clear();
            }
        }
    }

    pub fn broadcast(&self, key: String, mut msg: Message) {
        let origin = msg.get_origin();
        let operate = msg.get_operate();
        msg.set_origin(self.id_card);

        trace!("broadcast msg {:?} from key {}", msg, key);
        let msg_bytes: Vec<u8> = msg.try_into().unwrap();

        let mut buf = BytesMut::with_capacity(4 + 4 + 1 + key.len() + msg_bytes.len());
        pubsub_message_to_network_message(&mut buf, Some((key, msg_bytes)));

        let mut peers = vec![];
        for peer in self.peers_pair.write().iter_mut() {
            if Connection::is_send(peer.0, origin, operate) {
                if let Some(ref mut stream) = peer.2 {
                    peers.push(peer.0);
                    let _ = stream.write(&buf);
                }
            }
        }

        trace!(
            "{:?} broadcast msg to nodes {:?} {:?}",
            self.id_card,
            operate,
            peers
        );
    }

    pub fn broadcast_rawbytes(&self, key: String, data: &[u8]) {
        let mut msg = Message::try_from(data).unwrap();
        self.broadcast(key, msg);
    }
}

fn connect(con: Arc<Connection>) {
    thread::spawn(move || loop {
        for peer in con.peers_pair.write().iter_mut() {
            let mut need_reconnect = true;
            let mut buf = BytesMut::with_capacity(4 + 4);
            pubsub_message_to_network_message(&mut buf, None);
            if let Some(ref mut stream) = peer.2 {
                let res = stream.write(&buf);
                if res.is_ok() {
                    need_reconnect = false;
                }
            }
            if need_reconnect {
                warn!("connect {:?}!", peer.1);
                peer.2 = TcpStream::connect(peer.1.clone()).ok();
            }
        }

        thread::sleep(Duration::from_millis(TIMEOUT * 1000));
        trace!("after sleep retry connect!");
    });
}

pub fn manage_connect(con: &Arc<Connection>, config_path: &str, rx: Receiver<DebouncedEvent>) {
    connect(Arc::clone(con));
    let config = String::from(config_path);

    let con = Arc::clone(con);
    thread::spawn(move || loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(path_buf) | DebouncedEvent::Write(path_buf) => {
                    if path_buf.is_file() {
                        let file_name = path_buf.file_name().unwrap().to_str().unwrap();
                        if file_name == config.as_str() {
                            info!("file {} change", file_name);
                            let config = NetConfig::new(config.as_str());
                            con.update(&config);
                        }
                    }
                }
                _ => trace!("file notify event: {:?}", event),
            },
            Err(e) => warn!("watch error: {:?}", e),
        }
    });
}

#[cfg(test)]
mod test {
    use super::Connection;
    use libproto::OperateType;
    #[test]
    fn is_send_msg() {
        assert!(Connection::is_send(0, 0, OperateType::Broadcast));
        assert!(Connection::is_send(0, 1, OperateType::Broadcast));

        assert!(Connection::is_send(0, 0, OperateType::Single));
        assert!(!Connection::is_send(0, 1, OperateType::Single));

        assert!(!Connection::is_send(0, 0, OperateType::Subtract));
        assert!(Connection::is_send(0, 1, OperateType::Subtract));
    }
}
<commit_msg>remove redundant code<commit_after>// CITA
// Copyright 2016-2017 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use bytes::BytesMut;
use citaprotocol::pubsub_message_to_network_message;
use config;
use config::NetConfig;
use libproto::{Message, OperateType};
use notify::DebouncedEvent;
use std::convert::{TryFrom, TryInto};
use std::io::Write;
use std::net::TcpStream;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use std::thread;
use std::time::Duration;
use util::RwLock;

const TIMEOUT: u64 = 15;
type PeerPairs = Arc<RwLock<Vec<(u32, String, Option<TcpStream>)>>>;

pub struct Connection {
    pub id_card: u32,
    pub peers_pair: PeerPairs,
}

impl Connection {
    pub fn new(config: &config::NetConfig) -> Self {
        let id_card = config.id_card.unwrap();
        let mut peers_pair = Vec::default();
        if let Some(peers) = config.peers.as_ref() {
            for peer in peers.iter() {
                let id_card: u32 = peer.id_card.unwrap();
                let addr = format!("{}:{}", peer.ip.clone().unwrap(), peer.port.unwrap());
                peers_pair.push((id_card, addr, None));
            }
        }

        Connection {
            id_card,
            peers_pair: Arc::new(RwLock::new(peers_pair)),
        }
    }

    pub fn is_send(id_card: u32, origin: u32, operate: OperateType) -> bool {
        operate == OperateType::Broadcast || (operate == OperateType::Single && id_card == origin)
            || (operate == OperateType::Subtract && origin != id_card)
    }

    pub fn update(&self, config: &config::NetConfig) {
        //添加更新的配置到self
        match config.peers.as_ref() {
            Some(peers) => {
                let mut peers_addr = Vec::new();
                for peer in self.peers_pair.read().iter() {
                    peers_addr.push(peer.1.clone());
                }
                info!("peers before update {:?}", peers_addr);
                let mut config_addr = Vec::new();
                for peer in peers.iter() {
                    let id_card: u32 = peer.id_card.unwrap();
                    let addr = format!("{}:{}", peer.ip.clone().unwrap(), peer.port.unwrap());
                    config_addr.push(addr.clone());
                    if peers_addr.contains(&addr) {
                        continue;
                    }
                    peers_addr.push(addr.clone());
                    self.peers_pair.write().push((id_card, addr, None));
                }
                loop {
                    let index_opt = peers_addr
                        .iter()
                        .position(|addr| !config_addr.contains(addr));
                    if let Some(index) = index_opt {
                        peers_addr.remove(index);
                        self.peers_pair.write().remove(index);
                    } else {
                        break;
                    }
                }
                info!("peers after update {:?}", peers_addr);
            }
            None => {
                info!("clear all peers after update!");
                self.peers_pair.write().clear();
            }
        }
    }

    pub fn broadcast(&self, key: String, mut msg: Message) {
        let origin = msg.get_origin();
        let operate = msg.get_operate();
        msg.set_origin(self.id_card);

        trace!("broadcast msg {:?} from key {}", msg, key);
        let msg_bytes: Vec<u8> = msg.try_into().unwrap();

        let mut buf = BytesMut::with_capacity(4 + 4 + 1 + key.len() + msg_bytes.len());
        pubsub_message_to_network_message(&mut buf, Some((key, msg_bytes)));

        let mut peers = vec![];
        for peer in self.peers_pair.write().iter_mut() {
            if Connection::is_send(peer.0, origin, operate) {
                if let Some(ref mut stream) = peer.2 {
                    peers.push(peer.0);
                    let _ = stream.write(&buf);
                }
            }
        }

        trace!(
            "{:?} broadcast msg to nodes {:?} {:?}",
            self.id_card,
            operate,
            peers
        );
    }

    pub fn broadcast_rawbytes(&self, key: String, data: &[u8]) {
        let mut msg = Message::try_from(data).unwrap();
        self.broadcast(key, msg);
    }
}

fn connect(con: Arc<Connection>) {
    thread::spawn(move || loop {
        for peer in con.peers_pair.write().iter_mut() {
            let mut need_reconnect = true;
            let mut buf = BytesMut::with_capacity(4 + 4);
            pubsub_message_to_network_message(&mut buf, None);
            if let Some(ref mut stream) = peer.2 {
                let res = stream.write(&buf);
                if res.is_ok() {
                    need_reconnect = false;
                }
            }
            if need_reconnect {
                warn!("connect {:?}!", peer.1);
                peer.2 = TcpStream::connect(peer.1.clone()).ok();
            }
        }

        thread::sleep(Duration::from_millis(TIMEOUT * 1000));
        trace!("after sleep retry connect!");
    });
}

pub fn manage_connect(con: &Arc<Connection>, config_path: &str, rx: Receiver<DebouncedEvent>) {
    connect(Arc::clone(con));
    let config = String::from(config_path);

    let con = Arc::clone(con);
    thread::spawn(move || loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(path_buf) | DebouncedEvent::Write(path_buf) => {
                    if path_buf.is_file() {
                        let file_name = path_buf.file_name().unwrap().to_str().unwrap();
                        if file_name == config.as_str() {
                            info!("file {} change", file_name);
                            let config = NetConfig::new(config.as_str());
                            con.update(&config);
                        }
                    }
                }
                _ => trace!("file notify event: {:?}", event),
            },
            Err(e) => warn!("watch error: {:?}", e),
        }
    });
}

#[cfg(test)]
mod test {
    use super::Connection;
    use libproto::OperateType;
    #[test]
    fn is_send_msg() {
        assert!(Connection::is_send(0, 0, OperateType::Broadcast));
        assert!(Connection::is_send(0, 1, OperateType::Broadcast));

        assert!(Connection::is_send(0, 0, OperateType::Single));
        assert!(!Connection::is_send(0, 1, OperateType::Single));

        assert!(!Connection::is_send(0, 0, OperateType::Subtract));
        assert!(Connection::is_send(0, 1, OperateType::Subtract));
    }
}
<|endoftext|>