<commit_before>extern crate time_steward;

#[macro_use]
extern crate glium;

extern crate nalgebra;
extern crate rand;
extern crate docopt;

extern crate serde;
#[macro_use]
extern crate serde_derive;

//use docopt::Docopt;

const USAGE: &'static str = "
Bouncy Circles, a simple TimeSteward test case.

Usage:
  bouncy_circles
  bouncy_circles (-l | --listen) <host> <port>
  bouncy_circles (-c | --connect) <host> <port>

Options:
  -l, --listen   Start a synchronized simulation by listening for TCP connections.
  -c, --connect  Start a synchronized simulation by making a TCP connection.
";

#[derive(Debug, Deserialize)]
struct Args {
  flag_listen: bool,
  flag_connect: bool,

  arg_host: Option <String>,
  arg_port: Option <u16>,
}

use std::time::{Instant};
use glium::{DisplayBuild, Surface};

use time_steward::{DeterministicRandomId};
//use time_steward::stewards::{simple_full as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, Accessor, simple_timeline};
use simple_timeline::{query};

#[path = "../dev-shared/bouncy_circles.rs"] mod bouncy_circles;
use bouncy_circles::*;
#[path = "../dev-shared/emscripten_compatibility.rs"] mod emscripten_compatibility;
pub use emscripten_compatibility::canvas_click;

#[derive(Copy, Clone)]

struct Vertex {
  direction: [f32; 2],
  center: [f32; 2],
  radius: f32,
}
implement_vertex!(Vertex, direction, center, radius);

//use std::net::{TcpListener, TcpStream};
//use std::io::{BufReader, BufWriter};

fn main() {
  // For some reason, docopt checking the arguments caused build_glium() to fail in emscripten.
  /*if !cfg!(target_os = "emscripten") {
    let arguments: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());

    if arguments.flag_listen {
      let listener = TcpListener::bind ((arguments.arg_host.as_ref().map_or("localhost", | string | string as & str), arguments.arg_port.unwrap())).unwrap();
      let stream = listener.accept().unwrap().0;
      let mut steward: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> = simply_synchronized::Steward::new(DeterministicRandomId::new (& 0u32), 0, SECOND>>3,(), BufReader::new (stream.try_clone().unwrap()), BufWriter::new (stream));
      steward.insert_fiat_event(0, DeterministicRandomId::new(&0), Initialize::new()).unwrap();
      run (steward, |a,b| (a.settle_before (b)));
      return;
    }
    else if arguments.flag_connect {
      let stream = TcpStream::connect ((arguments.arg_host.as_ref().map_or("localhost", | string | string as & str), arguments.arg_port.unwrap())).unwrap();
      let steward: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> = simply_synchronized::Steward::new(DeterministicRandomId::new (& 1u32), 0, SECOND>>3,(), BufReader::new (stream.try_clone().unwrap()), BufWriter::new (stream));
      run (steward, |a,b| (a.settle_before (b)));
      return;
    }
  }*/
  {
    //let mut steward: s::Steward<Basics,
                                //inefficient_flat::Steward<Basics>,
                                //memoized_flat::Steward<Basics>> = s::Steward::from_constants(());
    let mut steward: Steward = Steward::from_globals(make_globals());
    steward.insert_fiat_event(0, DeterministicRandomId::new(&0), Initialize{}).unwrap();
    run (steward, |_,_|());
  }
}

fn run <F: Fn (&mut Steward, Time)>(mut stew: Steward, settle:F) {

  let vertex_shader_source = r#"
#version 100
attribute lowp vec2 direction;
attribute lowp vec2 center;
attribute lowp float radius;
varying lowp vec2 direction_transfer;

void main() {
direction_transfer = direction*1.5;
gl_Position = vec4 ( center + direction*1.5*radius, 0.0, 1.0);
}

"#;

  let fragment_shader_source = r#"
#version 100
varying lowp vec2 direction_transfer;

void main() {
if (dot (direction_transfer,direction_transfer) <1.0) {
gl_FragColor = vec4 (1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = vec4 (0.0, 0.0, 0.0, 0.0);

}
}

"#;

  //let mut snapshots = Vec::new();

  let mut event_index = 0u64;
  let mut mouse_coordinates = [0,0];

  if true {
    let display = glium::glutin::WindowBuilder::new()
      .with_dimensions(600, 600)
      .build_glium()
      .expect("failed to create window");
    let program =
      glium::Program::from_source(&display, vertex_shader_source, fragment_shader_source, None)
        .expect("glium program generation failed");
    let parameters = glium::DrawParameters {
      blend: glium::draw_parameters::Blend::alpha_blending(),
      ..Default::default()
    };
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    // take care of the expensive initial predictions before starting the timer
    stew.snapshot_before(&1);
    let start = Instant::now();

    let frame = || {
      let frame_begin = Instant::now();
      let time = 1+((start.elapsed().as_secs() as i64 * 1000000000i64) +
                            start.elapsed().subsec_nanos() as i64) *
                           SECOND / 1000000000i64;
      for ev in display.poll_events() {
        match ev {
          glium::glutin::Event::Closed => return true,
          glium::glutin::Event::MouseMoved (x,y) => {
            mouse_coordinates [0] = ((x as SpaceCoordinate) - 150) * ARENA_SIZE / 300;
            mouse_coordinates [1] = (450-(y as SpaceCoordinate)) * ARENA_SIZE / 300;
            //println!("mouse {} {} {:?}", x,y,mouse_coordinates);
          },
          glium::glutin::Event::MouseInput (_,_) => {
            event_index += 1;
            stew.insert_fiat_event (time, DeterministicRandomId::new (& event_index), Disturb {coordinates: [mouse_coordinates [0], mouse_coordinates [1]]}).unwrap();
          },
          _ => (),
        }
      }
      while let Some ((x,y)) = emscripten_compatibility::pop_click() {
        // TODO duplicate code
        mouse_coordinates [0] = (((x*600.0) as SpaceCoordinate) - 150) * ARENA_SIZE / 300;
        mouse_coordinates [1] = (450-((y*600.0) as SpaceCoordinate)) * ARENA_SIZE / 300;
        event_index += 1;
        stew.insert_fiat_event (time, DeterministicRandomId::new (& event_index), Disturb {coordinates: [mouse_coordinates [0], mouse_coordinates [1]]}).unwrap();
      }

      let mut target = display.draw();
      target.clear_color(0.0, 0.0, 0.0, 1.0);
      let mut vertices = Vec::<Vertex>::new();

      let accessor = stew.snapshot_before(& time)
        .expect("steward failed to provide snapshot");
      stew.forget_before(& time);
      settle (&mut stew, time);
      for handle in accessor.globals().circles.iter() {
        let circle = query (& accessor, &handle.varying);
        let position = circle.position.updated_by(accessor.now() - circle.last_change).unwrap().evaluate();
        let center = [position[0] as f32 / ARENA_SIZE as f32 - 0.5,
                      position[1] as f32 / ARENA_SIZE as f32 - 0.5];
        let radius = handle.radius as f32 / ARENA_SIZE as f32;
        // println!("drawing circ at {}, {}", center[0],center[1]);
        vertices.extend(&[Vertex {
                            center: center,
                            radius: radius,
                            direction: [1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [-1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [0.0, 1.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [-1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [0.0, -1.0],
                          }]);
      }
      target.draw(&glium::VertexBuffer::new(&display, &vertices)
                .expect("failed to generate glium Vertex buffer"),
              &indices,
              &program,
              &glium::uniforms::EmptyUniforms,
              &parameters)
        .expect("failed target.draw");

      target.finish().expect("failed to finish drawing");

      /*while frame_begin.elapsed() < Duration::from_millis (10) && stew.updated_until_before().map_or (false, | limitation | limitation < time + SECOND) {
        for _ in 0..8 {stew.step();}
      }*/
      false
    };

    emscripten_compatibility::main_loop (frame);
  }

  /*
  for increment in 1..21 {
    snapshots.push(stew.snapshot_before(&(increment * SECOND * 2)));
  }
  for snapshot in snapshots.iter_mut()
    .map(|option| option.as_mut().expect("all these snapshots should have been valid")) {
    println!("snapshot for {}", snapshot.now());
    // for index in 0..HOW_MANY_CIRCLES {
    // println!("{}", snapshot.get::<Circle> (get_circle_id (index)).expect("missing circle").position);
    // }
  }*/
  // panic!("anyway")
}
<commit_msg>Cleaned up more warnings<commit_after>extern crate time_steward;

#[macro_use]
extern crate glium;

extern crate nalgebra;
extern crate rand;
extern crate docopt;

extern crate serde;
#[macro_use]
extern crate serde_derive;

//use docopt::Docopt;

/*const USAGE: &'static str = "
Bouncy Circles, a simple TimeSteward test case.

Usage:
  bouncy_circles
  bouncy_circles (-l | --listen) <host> <port>
  bouncy_circles (-c | --connect) <host> <port>

Options:
  -l, --listen   Start a synchronized simulation by listening for TCP connections.
  -c, --connect  Start a synchronized simulation by making a TCP connection.
";*/

#[derive(Debug, Deserialize)]
struct Args {
  flag_listen: bool,
  flag_connect: bool,

  arg_host: Option <String>,
  arg_port: Option <u16>,
}

use std::time::{Instant};
use glium::{DisplayBuild, Surface};

use time_steward::{DeterministicRandomId};
//use time_steward::stewards::{simple_full as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, Accessor, simple_timeline};
use simple_timeline::{query};

#[path = "../dev-shared/bouncy_circles.rs"] mod bouncy_circles;
use bouncy_circles::*;
#[path = "../dev-shared/emscripten_compatibility.rs"] mod emscripten_compatibility;
pub use emscripten_compatibility::canvas_click;

#[derive(Copy, Clone)]

struct Vertex {
  direction: [f32; 2],
  center: [f32; 2],
  radius: f32,
}
implement_vertex!(Vertex, direction, center, radius);

//use std::net::{TcpListener, TcpStream};
//use std::io::{BufReader, BufWriter};

fn main() {
  // For some reason, docopt checking the arguments caused build_glium() to fail in emscripten.
  /*if !cfg!(target_os = "emscripten") {
    let arguments: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());

    if arguments.flag_listen {
      let listener = TcpListener::bind ((arguments.arg_host.as_ref().map_or("localhost", | string | string as & str), arguments.arg_port.unwrap())).unwrap();
      let stream = listener.accept().unwrap().0;
      let mut steward: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> = simply_synchronized::Steward::new(DeterministicRandomId::new (& 0u32), 0, SECOND>>3,(), BufReader::new (stream.try_clone().unwrap()), BufWriter::new (stream));
      steward.insert_fiat_event(0, DeterministicRandomId::new(&0), Initialize::new()).unwrap();
      run (steward, |a,b| (a.settle_before (b)));
      return;
    }
    else if arguments.flag_connect {
      let stream = TcpStream::connect ((arguments.arg_host.as_ref().map_or("localhost", | string | string as & str), arguments.arg_port.unwrap())).unwrap();
      let steward: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> = simply_synchronized::Steward::new(DeterministicRandomId::new (& 1u32), 0, SECOND>>3,(), BufReader::new (stream.try_clone().unwrap()), BufWriter::new (stream));
      run (steward, |a,b| (a.settle_before (b)));
      return;
    }
  }*/
  {
    //let mut steward: s::Steward<Basics,
                                //inefficient_flat::Steward<Basics>,
                                //memoized_flat::Steward<Basics>> = s::Steward::from_constants(());
    let mut steward: Steward = Steward::from_globals(make_globals());
    steward.insert_fiat_event(0, DeterministicRandomId::new(&0), Initialize{}).unwrap();
    run (steward, |_,_|());
  }
}

fn run <F: Fn (&mut Steward, Time)>(mut stew: Steward, settle:F) {

  let vertex_shader_source = r#"
#version 100
attribute lowp vec2 direction;
attribute lowp vec2 center;
attribute lowp float radius;
varying lowp vec2 direction_transfer;

void main() {
direction_transfer = direction*1.5;
gl_Position = vec4 ( center + direction*1.5*radius, 0.0, 1.0);
}

"#;

  let fragment_shader_source = r#"
#version 100
varying lowp vec2 direction_transfer;

void main() {
if (dot (direction_transfer,direction_transfer) <1.0) {
gl_FragColor = vec4 (1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = vec4 (0.0, 0.0, 0.0, 0.0);

}
}

"#;

  //let mut snapshots = Vec::new();

  let mut event_index = 0u64;
  let mut mouse_coordinates = [0,0];

  if true {
    let display = glium::glutin::WindowBuilder::new()
      .with_dimensions(600, 600)
      .build_glium()
      .expect("failed to create window");
    let program =
      glium::Program::from_source(&display, vertex_shader_source, fragment_shader_source, None)
        .expect("glium program generation failed");
    let parameters = glium::DrawParameters {
      blend: glium::draw_parameters::Blend::alpha_blending(),
      ..Default::default()
    };
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    // take care of the expensive initial predictions before starting the timer
    stew.snapshot_before(&1);
    let start = Instant::now();

    let frame = || {
      //let frame_begin = Instant::now();
      let time = 1+((start.elapsed().as_secs() as i64 * 1000000000i64) +
                            start.elapsed().subsec_nanos() as i64) *
                           SECOND / 1000000000i64;
      for ev in display.poll_events() {
        match ev {
          glium::glutin::Event::Closed => return true,
          glium::glutin::Event::MouseMoved (x,y) => {
            mouse_coordinates [0] = ((x as SpaceCoordinate) - 150) * ARENA_SIZE / 300;
            mouse_coordinates [1] = (450-(y as SpaceCoordinate)) * ARENA_SIZE / 300;
            //println!("mouse {} {} {:?}", x,y,mouse_coordinates);
          },
          glium::glutin::Event::MouseInput (_,_) => {
            event_index += 1;
            stew.insert_fiat_event (time, DeterministicRandomId::new (& event_index), Disturb {coordinates: [mouse_coordinates [0], mouse_coordinates [1]]}).unwrap();
          },
          _ => (),
        }
      }
      while let Some ((x,y)) = emscripten_compatibility::pop_click() {
        // TODO duplicate code
        mouse_coordinates [0] = (((x*600.0) as SpaceCoordinate) - 150) * ARENA_SIZE / 300;
        mouse_coordinates [1] = (450-((y*600.0) as SpaceCoordinate)) * ARENA_SIZE / 300;
        event_index += 1;
        stew.insert_fiat_event (time, DeterministicRandomId::new (& event_index), Disturb {coordinates: [mouse_coordinates [0], mouse_coordinates [1]]}).unwrap();
      }

      let mut target = display.draw();
      target.clear_color(0.0, 0.0, 0.0, 1.0);
      let mut vertices = Vec::<Vertex>::new();

      let accessor = stew.snapshot_before(& time)
        .expect("steward failed to provide snapshot");
      stew.forget_before(& time);
      settle (&mut stew, time);
      for handle in accessor.globals().circles.iter() {
        let circle = query (& accessor, &handle.varying);
        let position = circle.position.updated_by(accessor.now() - circle.last_change).unwrap().evaluate();
        let center = [position[0] as f32 / ARENA_SIZE as f32 - 0.5,
                      position[1] as f32 / ARENA_SIZE as f32 - 0.5];
        let radius = handle.radius as f32 / ARENA_SIZE as f32;
        // println!("drawing circ at {}, {}", center[0],center[1]);
        vertices.extend(&[Vertex {
                            center: center,
                            radius: radius,
                            direction: [1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [-1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [0.0, 1.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [-1.0, 0.0],
                          },
                          Vertex {
                            center: center,
                            radius: radius,
                            direction: [0.0, -1.0],
                          }]);
      }
      target.draw(&glium::VertexBuffer::new(&display, &vertices)
                .expect("failed to generate glium Vertex buffer"),
              &indices,
              &program,
              &glium::uniforms::EmptyUniforms,
              &parameters)
        .expect("failed target.draw");

      target.finish().expect("failed to finish drawing");

      /*while frame_begin.elapsed() < Duration::from_millis (10) && stew.updated_until_before().map_or (false, | limitation | limitation < time + SECOND) {
        for _ in 0..8 {stew.step();}
      }*/
      false
    };

    emscripten_compatibility::main_loop (frame);
  }

  /*
  for increment in 1..21 {
    snapshots.push(stew.snapshot_before(&(increment * SECOND * 2)));
  }
  for snapshot in snapshots.iter_mut()
    .map(|option| option.as_mut().expect("all these snapshots should have been valid")) {
    println!("snapshot for {}", snapshot.now());
    // for index in 0..HOW_MANY_CIRCLES {
    // println!("{}", snapshot.get::<Circle> (get_circle_id (index)).expect("missing circle").position);
    // }
  }*/
  // panic!("anyway")
}
<|endoftext|>


<commit_before>// This example drives c-ares using an mio::EventLoop.
extern crate c_ares;
extern crate mio;

use std::collections::HashSet;
use std::mem;
use std::os::unix::io;
use std::sync::mpsc;
use std::thread;

// Messages for the event loop.
enum CAresHandlerMessage {
    // 'Notify me when this file descriptor becomes readable, or writable'
    // The first bool is for 'readable' and the second is for 'writable'.  It's
    // allowed to set both of these - or neither, meaning 'I am no longer
    // interested in this file descriptor'.
    RegisterInterest(io::RawFd, bool, bool),

    // 'Shut down'.
    ShutDown,
}

struct CAresEventHandler {
    // Since the event handler owns the Channel, it won't be possible to submit
    // further queries once the event loop is running.  If you want to do that,
    // use an Arc<Mutex<c_ares::Channel>>.
    ares_channel: c_ares::Channel,
    tracked_fds: HashSet<io::RawFd>,
}

impl mio::Handler for CAresEventHandler {
    type Timeout = ();
    type Message = CAresHandlerMessage;

    // mio notifies us that a file descriptor is readable or writable, so we
    // tell the Channel the same.
    fn ready(
        &mut self,
        _event_loop: &mut mio::EventLoop<CAresEventHandler>,
        token: mio::Token,
        events: mio::EventSet) {
        let fd = token.as_usize() as io::RawFd;
        let read_fd = if events.is_readable() { fd } else { c_ares::INVALID_FD };
        let write_fd = if events.is_writable() { fd } else { c_ares::INVALID_FD };
        self.ares_channel.process_fd(read_fd, write_fd);
    }

    // Process received messages.  Either:
    // - we're asked to register interest (or non-interest) in a file
    // descriptor
    // - we're asked to shut down the event loop.
    fn notify(
        &mut self,
        event_loop:&mut mio::EventLoop<CAresEventHandler>,
        msg: Self::Message) {
        match msg {
            CAresHandlerMessage::RegisterInterest(fd, readable, writable) => {
                let io = mio::Io::from(fd);
                if !readable && !writable {
                    self.tracked_fds.remove(&fd);
                    event_loop
                        .deregister(&io)
                        .ok()
                        .expect("failed to deregister interest");
                } else {
                    let mut interest = mio::EventSet::none();
                    if readable {
                        interest = interest | mio::EventSet::readable();
                    }
                    if writable {
                        interest = interest | mio::EventSet::writable();
                    }
                    let token = mio::Token(fd as usize);
                    let register_result = if !self.tracked_fds.insert(fd) {
                        event_loop
                            .reregister(
                                &io,
                                token,
                                interest,
                                mio::PollOpt::level())
                    } else {
                        event_loop
                            .register_opt(
                                &io,
                                token,
                                interest,
                                mio::PollOpt::level())
                    };
                    register_result.ok().expect("failed to register interest");
                }

                // Don't accidentally close the file descriptor by dropping io!
                mem::forget(io);
            },

            CAresHandlerMessage::ShutDown => event_loop.shutdown(),
        }
    }

    // We run a recurring timer so that we can spot non-responsive servers.
    //
    // In that case we won't get a callback saying that anything is happening
    // on any file descriptor, but nevertheless need to give the Channel an
    // opportunity to notice that it has timed-out requests pending.
    fn timeout(
        &mut self,
        event_loop: &mut mio::EventLoop<CAresEventHandler>,
        _timeout: Self::Timeout) {
        self.ares_channel.process_fd(c_ares::INVALID_FD, c_ares::INVALID_FD);
        event_loop.timeout_ms((), 500).unwrap();
    }
}

impl CAresEventHandler {
    fn new(ares_channel: c_ares::Channel) -> CAresEventHandler {
        CAresEventHandler {
            ares_channel: ares_channel,
            tracked_fds: HashSet::new(),
        }
    }
}

fn print_a_result(result: Result<c_ares::AResult, c_ares::AresError>) {
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("Lookup failed with error '{:}'", err_string);
        }
        Ok(result) => {
            println!("Successful lookup...");
            for addr in &result.ip_addrs {
                println!("{:}", addr);
            }
        }
    }
}

fn print_aaaa_result(result: Result<c_ares::AAAAResult, c_ares::AresError>) {
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("Lookup failed with error '{:}'", err_string);
        }
        Ok(result) => {
            println!("Successful lookup...");
            for addr in &result.ip_addrs {
                println!("{:}", addr);
            }
        }
    }
}

fn main() {
    // Create an event loop, and a c_ares::Channel.
    let mut event_loop = mio::EventLoop::new()
        .ok()
        .expect("failed to create event loop");
    let event_loop_channel = event_loop.channel();
    let event_loop_channel_clone = event_loop_channel.clone();
    let sock_callback = move |fd: io::RawFd, readable: bool, writable: bool| {
        event_loop_channel_clone
            .send(CAresHandlerMessage::RegisterInterest(fd, readable, writable))
            .ok()
            .expect("Failed to send RegisterInterest");
    };
    let mut ares_channel = c_ares::Channel::new(sock_callback)
        .ok()
        .expect("Failed to create channel");

    // Set up a couple of queries.
    let (results_tx, results_rx) = mpsc::channel();
    let tx = results_tx.clone();
    ares_channel.query_a("apple.com", move |result| {
        print_a_result(result);
        tx.send(()).unwrap()
    });

    let tx = results_tx.clone();
    ares_channel.query_aaaa("google.com", move |result| {
        print_aaaa_result(result);
        tx.send(()).unwrap()
    });

    // Set the first instance of the recurring timer on the event loop.
    event_loop.timeout_ms((), 500).unwrap();

    // Kick off the event loop.
    let mut event_handler = CAresEventHandler::new(ares_channel);
    let handle = thread::spawn(move || {
        event_loop
            .run(&mut event_handler)
            .ok()
            .expect("failed to run event loop")
    });

    // Wait for results to roll in.
    for _ in 0..2 {
        results_rx.recv().unwrap();
    }

    // Shut down the event loop and wait for it to finish.
    event_loop_channel
        .send(CAresHandlerMessage::ShutDown)
        .ok()
        .expect("failed to shut down event loop");
    handle.join().unwrap();
}
<commit_msg>Update commenting for example<commit_after>// This example drives c-ares using an mio::EventLoop.
extern crate c_ares;
extern crate mio;

use std::collections::HashSet;
use std::mem;
use std::os::unix::io;
use std::sync::mpsc;
use std::thread;

// Messages for the event loop.
enum CAresHandlerMessage {
    // 'Notify me when this file descriptor becomes readable, or writable'
    // The first bool is for 'readable' and the second is for 'writable'.  It's
    // allowed to set both of these - or neither, meaning 'I am no longer
    // interested in this file descriptor'.
    RegisterInterest(io::RawFd, bool, bool),

    // 'Shut down'.
    ShutDown,
}

struct CAresEventHandler {
    // Since the event handler owns the Channel, it's tricky to submit further
    // queries once the event loop is running.  If you want to do that,
    // either:
    //
    // -  share the Channel by using an Arc<Mutex<c_ares::Channel>>, OR
    // -  send requests to the event handler as messages, and have it make the
    //    queries
    ares_channel: c_ares::Channel,
    tracked_fds: HashSet<io::RawFd>,
}

impl mio::Handler for CAresEventHandler {
    type Timeout = ();
    type Message = CAresHandlerMessage;

    // mio notifies us that a file descriptor is readable or writable, so we
    // tell the Channel the same.
    fn ready(
        &mut self,
        _event_loop: &mut mio::EventLoop<CAresEventHandler>,
        token: mio::Token,
        events: mio::EventSet) {
        let fd = token.as_usize() as io::RawFd;
        let read_fd = if events.is_readable() { fd } else { c_ares::INVALID_FD };
        let write_fd = if events.is_writable() { fd } else { c_ares::INVALID_FD };
        self.ares_channel.process_fd(read_fd, write_fd);
    }

    // Process received messages.  Either:
    // - we're asked to register interest (or non-interest) in a file
    // descriptor
    // - we're asked to shut down the event loop.
    fn notify(
        &mut self,
        event_loop:&mut mio::EventLoop<CAresEventHandler>,
        msg: Self::Message) {
        match msg {
            CAresHandlerMessage::RegisterInterest(fd, readable, writable) => {
                let io = mio::Io::from(fd);
                if !readable && !writable {
                    self.tracked_fds.remove(&fd);
                    event_loop
                        .deregister(&io)
                        .ok()
                        .expect("failed to deregister interest");
                } else {
                    let mut interest = mio::EventSet::none();
                    if readable {
                        interest = interest | mio::EventSet::readable();
                    }
                    if writable {
                        interest = interest | mio::EventSet::writable();
                    }
                    let token = mio::Token(fd as usize);
                    let register_result = if !self.tracked_fds.insert(fd) {
                        event_loop
                            .reregister(
                                &io,
                                token,
                                interest,
                                mio::PollOpt::level())
                    } else {
                        event_loop
                            .register_opt(
                                &io,
                                token,
                                interest,
                                mio::PollOpt::level())
                    };
                    register_result.ok().expect("failed to register interest");
                }

                // Don't accidentally close the file descriptor by dropping io!
                mem::forget(io);
            },

            CAresHandlerMessage::ShutDown => event_loop.shutdown(),
        }
    }

    // We run a recurring timer so that we can spot non-responsive servers.
    //
    // In that case we won't get a callback saying that anything is happening
    // on any file descriptor, but nevertheless need to give the Channel an
    // opportunity to notice that it has timed-out requests pending.
    fn timeout(
        &mut self,
        event_loop: &mut mio::EventLoop<CAresEventHandler>,
        _timeout: Self::Timeout) {
        self.ares_channel.process_fd(c_ares::INVALID_FD, c_ares::INVALID_FD);
        event_loop.timeout_ms((), 500).unwrap();
    }
}

impl CAresEventHandler {
    fn new(ares_channel: c_ares::Channel) -> CAresEventHandler {
        CAresEventHandler {
            ares_channel: ares_channel,
            tracked_fds: HashSet::new(),
        }
    }
}

fn print_a_result(result: Result<c_ares::AResult, c_ares::AresError>) {
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("Lookup failed with error '{:}'", err_string);
        }
        Ok(result) => {
            println!("Successful lookup...");
            for addr in &result.ip_addrs {
                println!("{:}", addr);
            }
        }
    }
}

fn print_aaaa_result(result: Result<c_ares::AAAAResult, c_ares::AresError>) {
    match result {
        Err(e) => {
            let err_string = c_ares::str_error(e);
            println!("Lookup failed with error '{:}'", err_string);
        }
        Ok(result) => {
            println!("Successful lookup...");
            for addr in &result.ip_addrs {
                println!("{:}", addr);
            }
        }
    }
}

fn main() {
    // Create an event loop, and a c_ares::Channel.
    let mut event_loop = mio::EventLoop::new()
        .ok()
        .expect("failed to create event loop");
    let event_loop_channel = event_loop.channel();
    let event_loop_channel_clone = event_loop_channel.clone();
    let sock_callback = move |fd: io::RawFd, readable: bool, writable: bool| {
        event_loop_channel_clone
            .send(CAresHandlerMessage::RegisterInterest(fd, readable, writable))
            .ok()
            .expect("Failed to send RegisterInterest");
    };
    let mut ares_channel = c_ares::Channel::new(sock_callback)
        .ok()
        .expect("Failed to create channel");

    // Set up a couple of queries.
    let (results_tx, results_rx) = mpsc::channel();
    let tx = results_tx.clone();
    ares_channel.query_a("apple.com", move |result| {
        print_a_result(result);
        tx.send(()).unwrap()
    });

    let tx = results_tx.clone();
    ares_channel.query_aaaa("google.com", move |result| {
        print_aaaa_result(result);
        tx.send(()).unwrap()
    });

    // Set the first instance of the recurring timer on the event loop.
    event_loop.timeout_ms((), 500).unwrap();

    // Kick off the event loop.
    let mut event_handler = CAresEventHandler::new(ares_channel);
    let handle = thread::spawn(move || {
        event_loop
            .run(&mut event_handler)
            .ok()
            .expect("failed to run event loop")
    });

    // Wait for results to roll in.
    for _ in 0..2 {
        results_rx.recv().unwrap();
    }

    // Shut down the event loop and wait for it to finish.
    event_loop_channel
        .send(CAresHandlerMessage::ShutDown)
        .ok()
        .expect("failed to shut down event loop");
    handle.join().unwrap();
}
<|endoftext|>


<commit_before>use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{HirId, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Const;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute.
    ///
    /// ### Why is this bad?
    /// Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjuction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed.
    ///
    /// ### Example
    /// ```rust
    /// struct RarelyUseful {
    ///     some_field: usize,
    ///     last: [SomeType; 0],
    /// }
    /// ```
    ///
    /// Use instead:
    /// ```rust
    /// #[repr(C)]
    /// struct MoreOftenUseful {
    ///     some_field: usize,
    ///     last: [SomeType; 0],
    /// }
    /// ```
    pub TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
    nursery,
    "struct with a trailing zero-sized array but without `#[repr(C)]` or another `repr` attribute"
}
declare_lint_pass!(TrailingZeroSizedArrayWithoutRepr => [TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR]);

impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutRepr {
    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
        if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_attr(cx, item.hir_id()) {
            span_lint_and_help(
                cx,
                TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
                item.span,
                "trailing zero-sized array in a struct which is not marked with a `repr` attribute",
                None,
                &format!(
                    "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute",
                    cx.tcx.def_path_str(item.def_id.to_def_id())
                ),
            );
        }
    }
}

fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool {
    if_chain! {
        // First check if last field is an array
        if let ItemKind::Struct(data, _) = &item.kind;
        if let Some(last_field) = data.fields().last();
        if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind;

        // Then check if that that array zero-sized
        let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
        let length = Const::from_anon_const(cx.tcx, length_ldid);
        let length = length.try_eval_usize(cx.tcx, cx.param_env);
        if let Some(length) = length;
        then {
            length == 0
        } else {
            false
        }
    }
}

fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
    cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::repr))
}
<commit_msg>Use real type in doc examples<commit_after>use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{HirId, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Const;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute.
    ///
    /// ### Why is this bad?
    /// Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjuction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed.
    ///
    /// ### Example
    /// ```rust
    /// struct RarelyUseful {
    ///     some_field: u32,
    ///     last: [u32; 0],
    /// }
    /// ```
    ///
    /// Use instead:
    /// ```rust
    /// #[repr(C)]
    /// struct MoreOftenUseful {
    ///     some_field: usize,
    ///     last: [u32; 0],
    /// }
    /// ```
    pub TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
    nursery,
    "struct with a trailing zero-sized array but without `#[repr(C)]` or another `repr` attribute"
}
declare_lint_pass!(TrailingZeroSizedArrayWithoutRepr => [TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR]);

impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutRepr {
    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
        if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_attr(cx, item.hir_id()) {
            span_lint_and_help(
                cx,
                TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
                item.span,
                "trailing zero-sized array in a struct which is not marked with a `repr` attribute",
                None,
                &format!(
                    "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute",
                    cx.tcx.def_path_str(item.def_id.to_def_id())
                ),
            );
        }
    }
}

fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool {
    if_chain! {
        // First check if last field is an array
        if let ItemKind::Struct(data, _) = &item.kind;
        if let Some(last_field) = data.fields().last();
        if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind;

        // Then check if that that array zero-sized
        let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
        let length = Const::from_anon_const(cx.tcx, length_ldid);
        let length = length.try_eval_usize(cx.tcx, cx.param_env);
        if let Some(length) = length;
        then {
            length == 0
        } else {
            false
        }
    }
}

fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
    cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::repr))
}
<|endoftext|>


<commit_before>#![deny(warnings)]
#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
#![cfg_attr(feature = "cargo-clippy", allow(explicit_iter_loop))]

extern crate bufstream;
extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate glob;
extern crate hex;
extern crate libc;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate tar;
extern crate toml;
extern crate url;
#[cfg(windows)]
extern crate winapi;

#[macro_use]
mod support;

mod alt_registry;
mod bad_config;
mod bad_manifest_path;
mod bench;
mod build;
mod build_auth;
mod build_lib;
mod build_plan;
mod build_script;
mod build_script_env;
mod cargo_alias_config;
mod cargo_command;
mod cargo_features;
mod cfg;
mod check;
mod clean;
mod concurrent;
mod config;
mod corrupt_git;
mod cross_compile;
mod cross_publish;
mod custom_target;
mod death;
mod dep_info;
mod directory;
mod doc;
mod edition;
mod features;
mod fetch;
mod fix;
mod freshness;
mod generate_lockfile;
mod git;
mod init;
mod install;
mod jobserver;
mod local_registry;
mod lockfile_compat;
mod login;
mod metabuild;
mod metadata;
mod net_config;
mod new;
mod out_dir;
mod overrides;
mod package;
mod patch;
mod path;
mod plugins;
mod proc_macro;
mod profile_config;
mod profile_overrides;
mod profile_targets;
mod profiles;
mod publish;
mod read_manifest;
mod registry;
mod rename_deps;
mod required_features;
mod resolve;
mod run;
mod rustc;
mod rustc_info_cache;
mod rustdoc;
mod rustdocflags;
mod rustflags;
mod search;
mod shell_quoting;
mod small_fd_limits;
mod test;
mod tool_paths;
mod update;
mod verify_project;
mod version;
mod warn_on_failure;
mod workspaces;
<commit_msg>Auto merge of #6033 - dwijnand:run-cross-compile-disable-check-asap, r=alexcrichton<commit_after>#![deny(warnings)]
#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
#![cfg_attr(feature = "cargo-clippy", allow(explicit_iter_loop))]

extern crate bufstream;
extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate glob;
extern crate hex;
extern crate libc;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate tar;
extern crate toml;
extern crate url;
#[cfg(windows)]
extern crate winapi;

#[macro_use]
mod support;

mod alt_registry;
mod bad_config;
mod bad_manifest_path;
mod bench;
mod build;
mod build_auth;
mod build_lib;
mod build_plan;
mod build_script;
mod build_script_env;
mod cargo_alias_config;
mod cargo_command;
mod cargo_features;
mod cfg;
mod check;
mod clean;
mod concurrent;
mod config;
mod corrupt_git;
mod cross_compile;
mod cross_publish;
mod custom_target;
mod death;
mod dep_info;
mod directory;
mod doc;
mod edition;
mod features;
mod fetch;
mod fix;
mod freshness;
mod generate_lockfile;
mod git;
mod init;
mod install;
mod jobserver;
mod local_registry;
mod lockfile_compat;
mod login;
mod metabuild;
mod metadata;
mod net_config;
mod new;
mod out_dir;
mod overrides;
mod package;
mod patch;
mod path;
mod plugins;
mod proc_macro;
mod profile_config;
mod profile_overrides;
mod profile_targets;
mod profiles;
mod publish;
mod read_manifest;
mod registry;
mod rename_deps;
mod required_features;
mod resolve;
mod run;
mod rustc;
mod rustc_info_cache;
mod rustdoc;
mod rustdocflags;
mod rustflags;
mod search;
mod shell_quoting;
mod small_fd_limits;
mod test;
mod tool_paths;
mod update;
mod verify_project;
mod version;
mod warn_on_failure;
mod workspaces;

#[test]
fn aaa_trigger_cross_compile_disabled_check() {
    // This triggers the cross compile disabled check to run ASAP, see #5141
    support::cross_compile::disabled();
}
<|endoftext|>


<commit_before><commit_msg>Correctly building hashtable from SQLite 3 db<commit_after><|endoftext|>


<commit_before><commit_msg>`PyArrayDescr::shape` returns empty vec if scalar<commit_after><|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{LinkArgs, TargetOptions, RelroLevel};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Gcc, vec![
        // GNU-style linkers will use this to omit linking to libraries
        // which don't actually fulfill any relocations, but only for
        // libraries which follow this flag.  Thus, use it before
        // specifying libraries to link to.
        "-Wl,--as-needed".to_string(),

        // Always enable NX protection when it is available
        "-Wl,-z,noexecstack".to_string(),
    ]);

    TargetOptions {
        dynamic_linking: true,
        executables: true,
        target_family: Some("unix".to_string()),
        linker_is_gnu: true,
        has_rpath: true,
        pre_link_args: args,
        position_independent_executables: true,
        eliminate_frame_pointer: false, // FIXME 43575
        relro_level: RelroLevel::Full,
        exe_allocation_crate: super::maybe_jemalloc(),
        .. Default::default()
    }
}
<commit_msg>FreeBSD uses Clang which can return small structs as an integer.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{LinkArgs, TargetOptions, RelroLevel};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Gcc, vec![
        // GNU-style linkers will use this to omit linking to libraries
        // which don't actually fulfill any relocations, but only for
        // libraries which follow this flag.  Thus, use it before
        // specifying libraries to link to.
        "-Wl,--as-needed".to_string(),

        // Always enable NX protection when it is available
        "-Wl,-z,noexecstack".to_string(),
    ]);

    TargetOptions {
        dynamic_linking: true,
        executables: true,
        target_family: Some("unix".to_string()),
        linker_is_gnu: true,
        has_rpath: true,
        pre_link_args: args,
        position_independent_executables: true,
        eliminate_frame_pointer: false, // FIXME 43575
        relro_level: RelroLevel::Full,
        exe_allocation_crate: super::maybe_jemalloc(),
        abi_return_struct_as_int: true,
        .. Default::default()
    }
}
<|endoftext|>


<commit_before>use crate::spec::{crt_objects, LinkArgs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();
    pre_link_args.insert(
        LinkerFlavor::Lld(LldFlavor::Ld),
        vec![
            "--build-id".to_string(),
            "--eh-frame-hdr".to_string(),
            "--hash-style=gnu".to_string(),
            "-z".to_string(),
            "rodynamic".to_string(),
        ],
    );

    TargetOptions {
        linker: Some("rust-lld".to_owned()),
        lld_flavor: LldFlavor::Ld,
        dynamic_linking: true,
        executables: true,
        target_family: Some("unix".to_string()),
        is_like_fuchsia: true,
        linker_is_gnu: true,
        has_rpath: false,
        pre_link_args,
        pre_link_objects: crt_objects::new(&[
            (LinkOutputKind::DynamicNoPicExe, &["Scrt1.o"]),
            (LinkOutputKind::DynamicPicExe, &["Scrt1.o"]),
            (LinkOutputKind::StaticNoPicExe, &["Scrt1.o"]),
            (LinkOutputKind::StaticPicExe, &["Scrt1.o"]),
        ]),
        position_independent_executables: true,
        has_elf_tls: true,
        ..Default::default()
    }
}
<commit_msg>Auto merge of #72116 - petrhosek:fuchsia-ld-flags, r=tmandry<commit_after>use crate::spec::{crt_objects, LinkArgs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();
    pre_link_args.insert(
        LinkerFlavor::Lld(LldFlavor::Ld),
        vec![
            "--build-id".to_string(),
            "--eh-frame-hdr".to_string(),
            "--hash-style=gnu".to_string(),
            "-z".to_string(),
            "max-page-size=4096".to_string(),
            "-z".to_string(),
            "now".to_string(),
            "-z".to_string(),
            "rodynamic".to_string(),
            "-z".to_string(),
            "separate-loadable-segments".to_string(),
            "--pack-dyn-relocs=relr".to_string(),
        ],
    );

    TargetOptions {
        linker: Some("rust-lld".to_owned()),
        lld_flavor: LldFlavor::Ld,
        dynamic_linking: true,
        executables: true,
        target_family: Some("unix".to_string()),
        is_like_fuchsia: true,
        linker_is_gnu: true,
        has_rpath: false,
        pre_link_args,
        pre_link_objects: crt_objects::new(&[
            (LinkOutputKind::DynamicNoPicExe, &["Scrt1.o"]),
            (LinkOutputKind::DynamicPicExe, &["Scrt1.o"]),
            (LinkOutputKind::StaticNoPicExe, &["Scrt1.o"]),
            (LinkOutputKind::StaticPicExe, &["Scrt1.o"]),
        ]),
        position_independent_executables: true,
        has_elf_tls: true,
        ..Default::default()
    }
}
<|endoftext|>


<commit_before>extern crate ispc;

fn main() {
    // Only re-run the build script if the ISPC files have been changed
    let ispc_files = vec!["src/simple.ispc"];
    for s in &ispc_files[..] {
        println!("cargo:rerun-if-changed={}", s);
    }
    if !ispc::compile_library("simple", &ispc_files[..]) {
        panic!("Failed to compile ISPC library 'simple'");
    }
}

<commit_msg>Remove trailing space<commit_after>extern crate ispc;

fn main() {
    // Only re-run the build script if the ISPC files have been changed
    let ispc_files = vec!["src/simple.ispc"];
    for s in &ispc_files[..] {
        println!("cargo:rerun-if-changed={}", s);
    }
    if !ispc::compile_library("simple", &ispc_files[..]) {
        panic!("Failed to compile ISPC library 'simple'");
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2020 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use lazy_static::lazy_static;
use std::io::BufRead;
use std::{
    collections::BTreeMap,
    env,
    net::{SocketAddr, ToSocketAddrs},
    path::PathBuf,
};
use url::Url;

lazy_static! {
    static ref RUNNING_IN_DOCKER: bool = {
        match std::fs::File::open("/proc/self/cgroup") {
            Err(_) => false,
            Ok(file) => {
                let reader = std::io::BufReader::new(file);
                reader.lines().any(|l| {
                    l.as_ref().unwrap_or(&"".to_string()).split(':').nth(1) == Some("docker")
                })
            }
        }
    };
}

/// Get the environment variable or panic
fn get_var(name: &str) -> String {
    env::var(name).unwrap_or_else(|_| panic!("{} environment variable is required.", name))
}

/// Convert a given host and port to a `SocketAddr` or panic
fn to_socket_addr(host: &str, port: &str) -> SocketAddr {
    let raw_addr = format!("{}:{}", host, port);

    let mut addrs_iter = raw_addr.to_socket_addrs().unwrap_or_else(|_| {
        panic!(
            "Address not parsable to SocketAddr. host: {}, port: {}",
            host, port
        )
    });

    addrs_iter
        .next()
        .expect("Could not convert to a SocketAddr")
}

fn empty_str_to_none(x: String) -> Option<String> {
    match x.as_ref() {
        "" => None,
        _ => Some(x),
    }
}

fn string_to_bool(x: String) -> bool {
    match x.trim().to_lowercase().as_ref() {
        "true" => true,
        _ => false,
    }
}

pub fn get_log_path() -> PathBuf {
    get_var("LOG_PATH").into()
}

pub fn get_dblog_hw() -> u32 {
    get_var("DBLOG_HW").parse().unwrap()
}

pub fn get_dblog_lw() -> u32 {
    get_var("DBLOG_LW").parse().unwrap()
}

/// Determine if local node is a docker volume
pub fn running_in_docker() -> bool {
    *RUNNING_IN_DOCKER
}

/// Get anonymous read permission from the env or panic
pub fn get_allow_anonymous_read() -> bool {
    string_to_bool(get_var("ALLOW_ANONYMOUS_READ"))
}

/// Get build num from the env or panic
pub fn get_build() -> String {
    get_var("BUILD")
}

/// Get is release from the env or panic
pub fn get_is_release() -> bool {
    string_to_bool(get_var("IS_RELEASE"))
}

/// Get version from the env or panic
pub fn get_version() -> String {
    get_var("VERSION")
}

/// Get exascaler version
pub fn get_exa_version() -> Option<String> {
    env::var("EXA_VERSION").ok()
}

/// Get the broker URL from the env or panic
pub fn get_amqp_broker_url() -> String {
    get_var("AMQP_BROKER_URL")
}

/// Get the broker user from the env or panic
pub fn get_user() -> String {
    get_var("AMQP_BROKER_USER")
}

/// Get the broker password from the env or panic
pub fn get_password() -> String {
    get_var("AMQP_BROKER_PASSWORD")
}

/// Get the broker vhost from the env or panic
pub fn get_vhost() -> String {
    get_var("AMQP_BROKER_VHOST")
}

/// Get the broker host from the env or panic
pub fn get_host() -> String {
    get_var("AMQP_BROKER_HOST")
}

/// Get the broker port from the env or panic
pub fn get_port() -> String {
    get_var("AMQP_BROKER_PORT")
}

/// Get the IML API port from the env or panic
pub fn get_iml_api_port() -> String {
    get_var("IML_API_PORT")
}

/// Get the IML API address from the env or panic
pub fn get_iml_api_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_iml_api_port())
}

/// Get the `http_agent2` port from the env or panic
pub fn get_http_agent2_port() -> String {
    get_var("HTTP_AGENT2_PORT")
}

pub fn get_http_agent2_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_http_agent2_port())
}

/// Get the server host from the env or panic
pub fn get_server_host() -> String {
    get_var("PROXY_HOST")
}

/// Get the AMQP server address or panic
pub fn get_addr() -> SocketAddr {
    to_socket_addr(&get_host(), &get_port())
}

/// Get the warp drive port from the env or panic
pub fn get_warp_drive_port() -> String {
    get_var("WARP_DRIVE_PORT")
}

/// Get the warp drive address from the env or panic
pub fn get_warp_drive_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_warp_drive_port())
}

/// Get the mailbox port from the env or panic
pub fn get_mailbox_port() -> String {
    get_var("MAILBOX_PORT")
}
/// Get the mailbox address from the env or panic
pub fn get_mailbox_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_mailbox_port())
}

/// Get the timer port
pub fn get_timer_port() -> String {
    get_var("TIMER_PORT")
}

/// Get the timer address from the env or panic
pub fn get_timer_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_timer_port())
}

/// Get the influxdb port from the env or panic
pub fn get_influxdb_port() -> String {
    get_var("INFLUXDB_PORT")
}

/// Get the influxdb address from the env or panic
pub fn get_influxdb_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_influxdb_port())
}

/// Get the metrics influxdb database name
pub fn get_influxdb_metrics_db() -> String {
    get_var("INFLUXDB_IML_STATS_DB")
}

/// Get the path to the mailbox from the env or panic
pub fn get_mailbox_path() -> PathBuf {
    get_var("MAILBOX_PATH").into()
}

/// Get the devices port or panic
pub fn get_device_aggregator_port() -> String {
    get_var("DEVICE_AGGREGATOR_PORT")
}

pub fn get_device_aggregator_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_device_aggregator_port())
}

/// Get the api key from the env or panic
pub fn get_api_key() -> String {
    get_var("API_KEY")
}

/// Get the api user from the env or panic
pub fn get_api_user() -> String {
    get_var("API_USER")
}

pub fn get_manager_url() -> String {
    get_var("SERVER_HTTP_URL")
}

pub fn get_db_user() -> String {
    get_var("DB_USER")
}

pub fn get_db_host() -> Option<String> {
    empty_str_to_none(get_var("DB_HOST"))
}

pub fn get_db_name() -> Option<String> {
    empty_str_to_none(get_var("DB_NAME"))
}

pub fn get_db_password() -> Option<String> {
    empty_str_to_none(get_var("DB_PASSWORD"))
}

pub fn get_branding() -> String {
    get_var("BRANDING")
}

pub fn get_use_stratagem() -> bool {
    string_to_bool(get_var("USE_STRATAGEM"))
}

pub fn get_action_runner_connect() -> String {
    if running_in_docker() {
        format!(
            "http://{}:{}",
            get_server_host(),
            get_var("ACTION_RUNNER_PORT")
        )
    } else {
        "http+unix://%2Fvar%2Frun%2Fiml-action-runner.sock/".to_string()
    }
}

pub fn get_sfa_endpoints() -> Option<Vec<Vec<Url>>> {
    let xs: BTreeMap<_, _> = env::vars()
        .filter(|(k, _)| k.starts_with("SFA_ENDPOINTS_"))
        .collect();

    let xs = xs.values().fold(vec![], |mut acc, x| {
        let xs: Vec<_> = x
            .split('|')
            .filter(|x| !x.is_empty())
            .map(|x| Url::parse(x).expect("Could not parse URL entry"))
            .collect();

        if !xs.is_empty() {
            acc.push(xs);
        }

        acc
    });

    if xs.is_empty() {
        None
    } else {
        Some(xs)
    }
}

/// Gets a connection string from the IML env
pub fn get_db_conn_string() -> String {
    let mut xs = vec![format!("user={}", get_db_user())];

    let host = match get_db_host() {
        Some(x) => x,
        None => "/var/run/postgresql".into(),
    };

    xs.push(format!("host={}", host));

    if let Some(x) = get_db_name() {
        xs.push(format!("dbname={}", x));
    }

    if let Some(x) = get_db_password() {
        xs.push(format!("password={}", x));
    }

    xs.join(" ")
}
<commit_msg>Update iml-manager-env for docker and postgres (#2074)<commit_after>// Copyright (c) 2020 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use lazy_static::lazy_static;
use std::{
    collections::{BTreeMap, HashMap},
    env,
    net::{SocketAddr, ToSocketAddrs},
    path::PathBuf,
};
use url::Url;

lazy_static! {
    static ref RUNNING_IN_DOCKER: bool = std::fs::metadata("/.dockerenv").is_ok();
}

/// Get the environment variable or panic
fn get_var(name: &str) -> String {
    env::var(name).unwrap_or_else(|_| panic!("{} environment variable is required.", name))
}

/// Convert a given host and port to a `SocketAddr` or panic
fn to_socket_addr(host: &str, port: &str) -> SocketAddr {
    let raw_addr = format!("{}:{}", host, port);

    let mut addrs_iter = raw_addr.to_socket_addrs().unwrap_or_else(|_| {
        panic!(
            "Address not parsable to SocketAddr. host: {}, port: {}",
            host, port
        )
    });

    addrs_iter
        .next()
        .expect("Could not convert to a SocketAddr")
}

fn empty_str_to_none(x: String) -> Option<String> {
    match x.as_ref() {
        "" => None,
        _ => Some(x),
    }
}

fn string_to_bool(x: String) -> bool {
    match x.trim().to_lowercase().as_ref() {
        "true" => true,
        _ => false,
    }
}

pub fn get_log_path() -> PathBuf {
    get_var("LOG_PATH").into()
}

pub fn get_dblog_hw() -> u32 {
    get_var("DBLOG_HW").parse().unwrap()
}

pub fn get_dblog_lw() -> u32 {
    get_var("DBLOG_LW").parse().unwrap()
}

/// Determine if local node is a docker volume
pub fn running_in_docker() -> bool {
    *RUNNING_IN_DOCKER
}

/// Get anonymous read permission from the env or panic
pub fn get_allow_anonymous_read() -> bool {
    string_to_bool(get_var("ALLOW_ANONYMOUS_READ"))
}

/// Get build num from the env or panic
pub fn get_build() -> String {
    get_var("BUILD")
}

/// Get is release from the env or panic
pub fn get_is_release() -> bool {
    string_to_bool(get_var("IS_RELEASE"))
}

/// Get version from the env or panic
pub fn get_version() -> String {
    get_var("VERSION")
}

/// Get exascaler version
pub fn get_exa_version() -> Option<String> {
    env::var("EXA_VERSION").ok()
}

/// Get the broker URL from the env or panic
pub fn get_amqp_broker_url() -> String {
    get_var("AMQP_BROKER_URL")
}

/// Get the broker user from the env or panic
pub fn get_user() -> String {
    get_var("AMQP_BROKER_USER")
}

/// Get the broker password from the env or panic
pub fn get_password() -> String {
    get_var("AMQP_BROKER_PASSWORD")
}

/// Get the broker vhost from the env or panic
pub fn get_vhost() -> String {
    get_var("AMQP_BROKER_VHOST")
}

/// Get the broker host from the env or panic
pub fn get_host() -> String {
    get_var("AMQP_BROKER_HOST")
}

/// Get the broker port from the env or panic
pub fn get_port() -> String {
    get_var("AMQP_BROKER_PORT")
}

/// Get the IML API port from the env or panic
pub fn get_iml_api_port() -> String {
    get_var("IML_API_PORT")
}

/// Get the IML API address from the env or panic
pub fn get_iml_api_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_iml_api_port())
}

/// Get the `http_agent2` port from the env or panic
pub fn get_http_agent2_port() -> String {
    get_var("HTTP_AGENT2_PORT")
}

pub fn get_http_agent2_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_http_agent2_port())
}

/// Get the server host from the env or panic
pub fn get_server_host() -> String {
    get_var("PROXY_HOST")
}

/// Get the AMQP server address or panic
pub fn get_addr() -> SocketAddr {
    to_socket_addr(&get_host(), &get_port())
}

/// Get the warp drive port from the env or panic
pub fn get_warp_drive_port() -> String {
    get_var("WARP_DRIVE_PORT")
}

/// Get the warp drive address from the env or panic
pub fn get_warp_drive_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_warp_drive_port())
}

/// Get the mailbox port from the env or panic
pub fn get_mailbox_port() -> String {
    get_var("MAILBOX_PORT")
}
/// Get the mailbox address from the env or panic
pub fn get_mailbox_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_mailbox_port())
}

/// Get the timer port
pub fn get_timer_port() -> String {
    get_var("TIMER_PORT")
}

/// Get the timer address from the env or panic
pub fn get_timer_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_timer_port())
}

/// Get the influxdb port from the env or panic
pub fn get_influxdb_port() -> String {
    get_var("INFLUXDB_PORT")
}

/// Get the influxdb address from the env or panic
pub fn get_influxdb_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_influxdb_port())
}

/// Get the metrics influxdb database name
pub fn get_influxdb_metrics_db() -> String {
    get_var("INFLUXDB_IML_STATS_DB")
}

/// Get the path to the mailbox from the env or panic
pub fn get_mailbox_path() -> PathBuf {
    get_var("MAILBOX_PATH").into()
}

/// Get the devices port or panic
pub fn get_device_aggregator_port() -> String {
    get_var("DEVICE_AGGREGATOR_PORT")
}

pub fn get_device_aggregator_addr() -> SocketAddr {
    to_socket_addr(&get_server_host(), &get_device_aggregator_port())
}

/// Get the api key from the env or panic
pub fn get_api_key() -> String {
    get_var("API_KEY")
}

/// Get the api user from the env or panic
pub fn get_api_user() -> String {
    get_var("API_USER")
}

pub fn get_manager_url() -> String {
    get_var("SERVER_HTTP_URL")
}

pub fn get_db_user() -> String {
    get_var("DB_USER")
}

pub fn get_db_host() -> Option<String> {
    empty_str_to_none(get_var("DB_HOST"))
}

pub fn get_db_name() -> Option<String> {
    empty_str_to_none(get_var("DB_NAME"))
}

pub fn get_db_password() -> Option<String> {
    empty_str_to_none(get_var("DB_PASSWORD"))
}

pub fn get_branding() -> String {
    get_var("BRANDING")
}

pub fn get_use_stratagem() -> bool {
    string_to_bool(get_var("USE_STRATAGEM"))
}

pub fn get_action_runner_connect() -> String {
    if running_in_docker() {
        format!(
            "http://{}:{}",
            get_server_host(),
            get_var("ACTION_RUNNER_PORT")
        )
    } else {
        "http+unix://%2Fvar%2Frun%2Fiml-action-runner.sock/".to_string()
    }
}

pub fn get_sfa_endpoints() -> Option<Vec<Vec<Url>>> {
    let xs: BTreeMap<_, _> = env::vars()
        .filter(|(k, _)| k.starts_with("SFA_ENDPOINTS_"))
        .collect();

    let xs = xs.values().fold(vec![], |mut acc, x| {
        let xs: Vec<_> = x
            .split('|')
            .filter(|x| !x.is_empty())
            .map(|x| Url::parse(x).expect("Could not parse URL entry"))
            .collect();

        if !xs.is_empty() {
            acc.push(xs);
        }

        acc
    });

    if xs.is_empty() {
        None
    } else {
        Some(xs)
    }
}

/// Gets a hash of db connection values
pub fn get_db_conn_hash() -> HashMap<String, String> {
    let mut xs = HashMap::new();

    xs.insert("user".to_string(), get_db_user());

    let host = match get_db_host() {
        Some(x) => x,
        None => "/var/run/postgresql".into(),
    };

    xs.insert("host".to_string(), host);

    if let Some(x) = get_db_name() {
        xs.insert("dbname".to_string(), x);
    }

    if let Some(x) = get_db_password() {
        xs.insert("password".to_string(), x);
    }

    // Convert executable name to application_name for Postgres
    if let Some(x) = std::env::current_exe()
        .unwrap_or_else(|_| "".into())
        .file_name()
    {
        xs.insert(
            "application_name".to_string(),
            x.to_string_lossy().to_string(),
        );
    }

    xs
}

/// Gets a connection string from the IML env
pub fn get_db_conn_string() -> String {
    let xs = get_db_conn_hash();
    xs.iter()
        .map(|(k, v)| format!("{}={}", k, v))
        .collect::<Vec<String>>()
        .join(" ")
}
<|endoftext|>


<commit_before>#![allow(unused_macros)]

macro_rules! feature {
    (
        #![$meta:meta]
        $($item:item)*
    ) => {
        $(
            #[cfg($meta)]
            #[cfg_attr(docsrs, doc(cfg($meta)))]
            $item
        )*
    }
}

/// Enables enter::block_on.
macro_rules! cfg_block_on {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                    feature = "fs",
                    feature = "net",
                    feature = "io-std",
                    feature = "rt",
                    ))]
            $item
        )*
    }
}

/// Enables internal `AtomicWaker` impl.
macro_rules! cfg_atomic_waker_impl {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                feature = "net",
                feature = "process",
                feature = "rt",
                feature = "signal",
                feature = "time",
            ))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_aio {
    ($($item:item)*) => {
        $(
            #[cfg(all(any(docsrs, target_os = "freebsd"), feature = "net"))]
            #[cfg_attr(docsrs,
                doc(cfg(all(target_os = "freebsd", feature = "net")))
            )]
            $item
        )*
    }
}

macro_rules! cfg_fs {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "fs")]
            #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
            $item
        )*
    }
}

macro_rules! cfg_io_blocking {
    ($($item:item)*) => {
        $( #[cfg(any(feature = "io-std", feature = "fs"))] $item )*
    }
}

macro_rules! cfg_io_driver {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            ))]
            #[cfg_attr(docsrs, doc(cfg(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            ))))]
            $item
        )*
    }
}

macro_rules! cfg_io_driver_impl {
    ( $( $item:item )* ) => {
        $(
            #[cfg(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            ))]
            $item
        )*
    }
}

macro_rules! cfg_not_io_driver {
    ($($item:item)*) => {
        $(
            #[cfg(not(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            )))]
            $item
        )*
    }
}

macro_rules! cfg_io_readiness {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "net")]
            $item
        )*
    }
}

macro_rules! cfg_io_std {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "io-std")]
            #[cfg_attr(docsrs, doc(cfg(feature = "io-std")))]
            $item
        )*
    }
}

macro_rules! cfg_io_util {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "io-util")]
            #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
            $item
        )*
    }
}

macro_rules! cfg_not_io_util {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "io-util"))] $item )*
    }
}

macro_rules! cfg_loom {
    ($($item:item)*) => {
        $( #[cfg(loom)] $item )*
    }
}

macro_rules! cfg_not_loom {
    ($($item:item)*) => {
        $( #[cfg(not(loom))] $item )*
    }
}

macro_rules! cfg_macros {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "macros")]
            #[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
            $item
        )*
    }
}

macro_rules! cfg_stats {
    ($($item:item)*) => {
        $(
            #[cfg(all(tokio_unstable, feature = "stats"))]
            #[cfg_attr(docsrs, doc(cfg(feature = "stats")))]
            $item
        )*
    }
}

macro_rules! cfg_not_stats {
    ($($item:item)*) => {
        $(
            #[cfg(not(all(tokio_unstable, feature = "stats")))]
            $item
        )*
    }
}

macro_rules! cfg_net {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "net")]
            #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
            $item
        )*
    }
}

macro_rules! cfg_net_unix {
    ($($item:item)*) => {
        $(
            #[cfg(all(unix, feature = "net"))]
            #[cfg_attr(docsrs, doc(cfg(all(unix, feature = "net"))))]
            $item
        )*
    }
}

macro_rules! cfg_net_windows {
    ($($item:item)*) => {
        $(
            #[cfg(all(any(all(doc, docsrs), windows), feature = "net"))]
            #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "net"))))]
            $item
        )*
    }
}

macro_rules! cfg_process {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "process")]
            #[cfg_attr(docsrs, doc(cfg(feature = "process")))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_process_driver {
    ($($item:item)*) => {
        #[cfg(unix)]
        #[cfg(not(loom))]
        cfg_process! { $($item)* }
    }
}

macro_rules! cfg_not_process_driver {
    ($($item:item)*) => {
        $(
            #[cfg(not(all(unix, not(loom), feature = "process")))]
            $item
        )*
    }
}

macro_rules! cfg_signal {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "signal")]
            #[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_signal_internal {
    ($($item:item)*) => {
        $(
            #[cfg(any(feature = "signal", all(unix, feature = "process")))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_not_signal_internal {
    ($($item:item)*) => {
        $(
            #[cfg(any(loom, not(unix), not(any(feature = "signal", all(unix, feature = "process")))))]
            $item
        )*
    }
}

macro_rules! cfg_sync {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "sync")]
            #[cfg_attr(docsrs, doc(cfg(feature = "sync")))]
            $item
        )*
    }
}

macro_rules! cfg_not_sync {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "sync"))] $item )*
    }
}

macro_rules! cfg_rt {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "rt")]
            #[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
            $item
        )*
    }
}

macro_rules! cfg_not_rt {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "rt"))] $item )*
    }
}

macro_rules! cfg_rt_multi_thread {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "rt-multi-thread")]
            #[cfg_attr(docsrs, doc(cfg(feature = "rt-multi-thread")))]
            $item
        )*
    }
}

macro_rules! cfg_not_rt_multi_thread {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "rt-multi-thread"))] $item )*
    }
}

macro_rules! cfg_test_util {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "test-util")]
            #[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
            $item
        )*
    }
}

macro_rules! cfg_not_test_util {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "test-util"))] $item )*
    }
}

macro_rules! cfg_time {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "time")]
            #[cfg_attr(docsrs, doc(cfg(feature = "time")))]
            $item
        )*
    }
}

macro_rules! cfg_not_time {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "time"))] $item )*
    }
}

macro_rules! cfg_trace {
    ($($item:item)*) => {
        $(
            #[cfg(all(tokio_unstable, feature = "tracing"))]
            #[cfg_attr(docsrs, doc(cfg(feature = "tracing")))]
            $item
        )*
    }
}

macro_rules! cfg_not_trace {
    ($($item:item)*) => {
        $(
            #[cfg(any(not(tokio_unstable), not(feature = "tracing")))]
            $item
        )*
    }
}

macro_rules! cfg_coop {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                    feature = "fs",
                    feature = "io-std",
                    feature = "net",
                    feature = "process",
                    feature = "rt",
                    feature = "signal",
                    feature = "sync",
                    feature = "time",
                    ))]
            $item
        )*
    }
}

macro_rules! cfg_not_coop {
    ($($item:item)*) => {
        $(
            #[cfg(not(any(
                    feature = "fs",
                    feature = "io-std",
                    feature = "net",
                    feature = "process",
                    feature = "rt",
                    feature = "signal",
                    feature = "sync",
                    feature = "time",
                    )))]
            $item
        )*
    }
}

macro_rules! cfg_has_atomic_u64 {
    ($($item:item)*) => {
        $(
            #[cfg(not(any(
                    target_arch = "arm",
                    target_arch = "mips",
                    target_arch = "powerpc"
                    )))]
            $item
        )*
    }
}

macro_rules! cfg_not_has_atomic_u64 {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                    target_arch = "arm",
                    target_arch = "mips",
                    target_arch = "powerpc"
                    ))]
            $item
        )*
    }
}
<commit_msg>tokio: add riscv32 to non atomic64 architectures (#4185)<commit_after>#![allow(unused_macros)]

macro_rules! feature {
    (
        #![$meta:meta]
        $($item:item)*
    ) => {
        $(
            #[cfg($meta)]
            #[cfg_attr(docsrs, doc(cfg($meta)))]
            $item
        )*
    }
}

/// Enables enter::block_on.
macro_rules! cfg_block_on {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                    feature = "fs",
                    feature = "net",
                    feature = "io-std",
                    feature = "rt",
                    ))]
            $item
        )*
    }
}

/// Enables internal `AtomicWaker` impl.
macro_rules! cfg_atomic_waker_impl {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                feature = "net",
                feature = "process",
                feature = "rt",
                feature = "signal",
                feature = "time",
            ))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_aio {
    ($($item:item)*) => {
        $(
            #[cfg(all(any(docsrs, target_os = "freebsd"), feature = "net"))]
            #[cfg_attr(docsrs,
                doc(cfg(all(target_os = "freebsd", feature = "net")))
            )]
            $item
        )*
    }
}

macro_rules! cfg_fs {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "fs")]
            #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
            $item
        )*
    }
}

macro_rules! cfg_io_blocking {
    ($($item:item)*) => {
        $( #[cfg(any(feature = "io-std", feature = "fs"))] $item )*
    }
}

macro_rules! cfg_io_driver {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            ))]
            #[cfg_attr(docsrs, doc(cfg(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            ))))]
            $item
        )*
    }
}

macro_rules! cfg_io_driver_impl {
    ( $( $item:item )* ) => {
        $(
            #[cfg(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            ))]
            $item
        )*
    }
}

macro_rules! cfg_not_io_driver {
    ($($item:item)*) => {
        $(
            #[cfg(not(any(
                feature = "net",
                feature = "process",
                all(unix, feature = "signal"),
            )))]
            $item
        )*
    }
}

macro_rules! cfg_io_readiness {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "net")]
            $item
        )*
    }
}

macro_rules! cfg_io_std {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "io-std")]
            #[cfg_attr(docsrs, doc(cfg(feature = "io-std")))]
            $item
        )*
    }
}

macro_rules! cfg_io_util {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "io-util")]
            #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
            $item
        )*
    }
}

macro_rules! cfg_not_io_util {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "io-util"))] $item )*
    }
}

macro_rules! cfg_loom {
    ($($item:item)*) => {
        $( #[cfg(loom)] $item )*
    }
}

macro_rules! cfg_not_loom {
    ($($item:item)*) => {
        $( #[cfg(not(loom))] $item )*
    }
}

macro_rules! cfg_macros {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "macros")]
            #[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
            $item
        )*
    }
}

macro_rules! cfg_stats {
    ($($item:item)*) => {
        $(
            #[cfg(all(tokio_unstable, feature = "stats"))]
            #[cfg_attr(docsrs, doc(cfg(feature = "stats")))]
            $item
        )*
    }
}

macro_rules! cfg_not_stats {
    ($($item:item)*) => {
        $(
            #[cfg(not(all(tokio_unstable, feature = "stats")))]
            $item
        )*
    }
}

macro_rules! cfg_net {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "net")]
            #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
            $item
        )*
    }
}

macro_rules! cfg_net_unix {
    ($($item:item)*) => {
        $(
            #[cfg(all(unix, feature = "net"))]
            #[cfg_attr(docsrs, doc(cfg(all(unix, feature = "net"))))]
            $item
        )*
    }
}

macro_rules! cfg_net_windows {
    ($($item:item)*) => {
        $(
            #[cfg(all(any(all(doc, docsrs), windows), feature = "net"))]
            #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "net"))))]
            $item
        )*
    }
}

macro_rules! cfg_process {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "process")]
            #[cfg_attr(docsrs, doc(cfg(feature = "process")))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_process_driver {
    ($($item:item)*) => {
        #[cfg(unix)]
        #[cfg(not(loom))]
        cfg_process! { $($item)* }
    }
}

macro_rules! cfg_not_process_driver {
    ($($item:item)*) => {
        $(
            #[cfg(not(all(unix, not(loom), feature = "process")))]
            $item
        )*
    }
}

macro_rules! cfg_signal {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "signal")]
            #[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_signal_internal {
    ($($item:item)*) => {
        $(
            #[cfg(any(feature = "signal", all(unix, feature = "process")))]
            #[cfg(not(loom))]
            $item
        )*
    }
}

macro_rules! cfg_not_signal_internal {
    ($($item:item)*) => {
        $(
            #[cfg(any(loom, not(unix), not(any(feature = "signal", all(unix, feature = "process")))))]
            $item
        )*
    }
}

macro_rules! cfg_sync {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "sync")]
            #[cfg_attr(docsrs, doc(cfg(feature = "sync")))]
            $item
        )*
    }
}

macro_rules! cfg_not_sync {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "sync"))] $item )*
    }
}

macro_rules! cfg_rt {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "rt")]
            #[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
            $item
        )*
    }
}

macro_rules! cfg_not_rt {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "rt"))] $item )*
    }
}

macro_rules! cfg_rt_multi_thread {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "rt-multi-thread")]
            #[cfg_attr(docsrs, doc(cfg(feature = "rt-multi-thread")))]
            $item
        )*
    }
}

macro_rules! cfg_not_rt_multi_thread {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "rt-multi-thread"))] $item )*
    }
}

macro_rules! cfg_test_util {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "test-util")]
            #[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
            $item
        )*
    }
}

macro_rules! cfg_not_test_util {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "test-util"))] $item )*
    }
}

macro_rules! cfg_time {
    ($($item:item)*) => {
        $(
            #[cfg(feature = "time")]
            #[cfg_attr(docsrs, doc(cfg(feature = "time")))]
            $item
        )*
    }
}

macro_rules! cfg_not_time {
    ($($item:item)*) => {
        $( #[cfg(not(feature = "time"))] $item )*
    }
}

macro_rules! cfg_trace {
    ($($item:item)*) => {
        $(
            #[cfg(all(tokio_unstable, feature = "tracing"))]
            #[cfg_attr(docsrs, doc(cfg(feature = "tracing")))]
            $item
        )*
    }
}

macro_rules! cfg_not_trace {
    ($($item:item)*) => {
        $(
            #[cfg(any(not(tokio_unstable), not(feature = "tracing")))]
            $item
        )*
    }
}

macro_rules! cfg_coop {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                    feature = "fs",
                    feature = "io-std",
                    feature = "net",
                    feature = "process",
                    feature = "rt",
                    feature = "signal",
                    feature = "sync",
                    feature = "time",
                    ))]
            $item
        )*
    }
}

macro_rules! cfg_not_coop {
    ($($item:item)*) => {
        $(
            #[cfg(not(any(
                    feature = "fs",
                    feature = "io-std",
                    feature = "net",
                    feature = "process",
                    feature = "rt",
                    feature = "signal",
                    feature = "sync",
                    feature = "time",
                    )))]
            $item
        )*
    }
}

macro_rules! cfg_has_atomic_u64 {
    ($($item:item)*) => {
        $(
            #[cfg(not(any(
                    target_arch = "arm",
                    target_arch = "mips",
                    target_arch = "powerpc",
                    target_arch = "riscv32"
                    )))]
            $item
        )*
    }
}

macro_rules! cfg_not_has_atomic_u64 {
    ($($item:item)*) => {
        $(
            #[cfg(any(
                    target_arch = "arm",
                    target_arch = "mips",
                    target_arch = "powerpc",
                    target_arch = "riscv32"
                    ))]
            $item
        )*
    }
}
<|endoftext|>


<commit_before>use iron::{Middleware, Request, Response, Url, Status, Continue};
use typemap::Assoc;

/// Exposes the original, unmodified path to be stored in `Request::extensions`.
pub struct OriginalUrl;
impl Assoc<Url> for OriginalUrl {}

/// `Mount` is a simple mounting middleware.
///
/// `Mount` allows you to mount other middleware within a larger chain.
///
/// Mounted middleware will receive a modified version of the request
/// url with the mount pattern removed from the start of the url.
#[deriving(Clone)]
pub struct Mount<M> {
    route: String,
    matches: Vec<String>,
    middleware: M
}

impl<M: Middleware + Send> Mount<M> {
    /// Creates a new instance of `Mount` mounting the given instance of Iron
    /// on the given path.
    pub fn new(route: &str, middleware: M) -> Mount<M> {
        Mount {
            route: route.to_string(),
            middleware: middleware,
            matches: Path::new(route)
                        .str_components()
                        .map(|s| s.unwrap().to_string())
                        .collect()
        }
    }
}

impl<M: Middleware + Send> Middleware for Mount<M> {
    fn enter(&mut self,
             req: &mut Request,
             res: &mut Response) -> Status {
        // Check for a route match.
        if !req.url.path.as_slice().starts_with(self.matches.as_slice()) {
            return Continue;
        }

        // We have a match, so fire off the child middleware.
        // If another mount middleware hasn't already, insert the unmodified url
        // into the extensions as the "original url".
        let is_outer_mount = !req.extensions.contains::<OriginalUrl, Url>();
        if is_outer_mount {
            req.extensions.insert::<OriginalUrl, Url>(req.url.clone());
        }

        // Remove the prefix from the request's path before passing it to the mounted middleware.
        // Preserve the rust-url invariant that the path list is non-empty ("" corresponds to /).
        req.url.path = match req.url.path.as_slice().slice_from(self.matches.len()) {
            [] => vec!["".to_string()],
            list => list.to_vec()
        };

        let terminator = self.middleware.enter(req, res);
        let _ = self.middleware.exit(req, res);

        // Reverse the URL munging, for future middleware.
        req.url = match req.extensions.find::<OriginalUrl, Url>() {
            Some(original) => original.clone(),
            None => fail!("OriginalUrl unexpectedly removed from req.extensions.")
        };

        // If this middleware is the outermost mount middleware,
        // remove the original url from the extensions map to prevent leakage.
        if is_outer_mount {
            req.extensions.remove::<OriginalUrl, Url>();
        }

        // We dispatched the request, so return the terminator.
        terminator
    }
}

<commit_msg>(fix) Fix URL modification and redirect behaviour.<commit_after>use iron::{Middleware, Request, Response, Url, Status, Continue};
use typemap::Assoc;

/// Exposes the original, unmodified path to be stored in `Request::extensions`.
pub struct OriginalUrl;
impl Assoc<Url> for OriginalUrl {}

/// `Mount` is a simple mounting middleware.
///
/// `Mount` allows you to mount other middleware within a larger chain.
///
/// Mounted middleware will receive a modified version of the request
/// url with the mount pattern removed from the start of the url.
#[deriving(Clone)]
pub struct Mount<M> {
    route: String,
    matches: Vec<String>,
    middleware: M
}

impl<M: Middleware + Send> Mount<M> {
    /// Creates a new instance of `Mount` mounting the given instance of Iron
    /// on the given path.
    pub fn new(route: &str, middleware: M) -> Mount<M> {
        Mount {
            route: route.to_string(),
            middleware: middleware,
            matches: Path::new(route)
                        .str_components()
                        .map(|s| s.unwrap().to_string())
                        .collect()
        }
    }
}

impl<M: Middleware + Send> Middleware for Mount<M> {
    fn enter(&mut self,
             req: &mut Request,
             res: &mut Response) -> Status {
        // Check for a route match.
        if !req.url.path.as_slice().starts_with(self.matches.as_slice()) {
            return Continue;
        }

        // We have a match, so fire off the child middleware.
        // If another mount middleware hasn't already, insert the unmodified url
        // into the extensions as the "original url".
        let is_outer_mount = !req.extensions.contains::<OriginalUrl, Url>();
        if is_outer_mount {
            req.extensions.insert::<OriginalUrl, Url>(req.url.clone());
        }

        // Remove the prefix from the request's path before passing it to the mounted middleware.
        // If the prefix is entirely removed and no trailing slash was present, the new path
        // will be the empty list. For the purposes of redirection, conveying that the path
        // did not include a trailing slash is more important than providing a non-empty list.
        req.url.path = req.url.path.as_slice().slice_from(self.matches.len()).to_vec();

        let terminator = self.middleware.enter(req, res);
        let _ = self.middleware.exit(req, res);

        // Reverse the URL munging, for future middleware.
        req.url = match req.extensions.find::<OriginalUrl, Url>() {
            Some(original) => original.clone(),
            None => fail!("OriginalUrl unexpectedly removed from req.extensions.")
        };

        // If this middleware is the outermost mount middleware,
        // remove the original url from the extensions map to prevent leakage.
        if is_outer_mount {
            req.extensions.remove::<OriginalUrl, Url>();
        }

        // We dispatched the request, so return the terminator.
        terminator
    }
}

<|endoftext|>