<commit_before>use fmt;
use io;
use net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use time::Duration;
use sys::{unsupported, Void};
use convert::TryFrom;

pub extern crate libc as netc;

pub struct TcpStream(Void);

impl TcpStream {
    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpStream> {
        match self.0 {}
    }

    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpStream {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct TcpListener(Void);

impl TcpListener {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpListener> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn only_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpListener {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct UdpSocket(Void);

impl UdpSocket {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<UdpSocket> {
        match self.0 {}
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn broadcast(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
        match self.0 {}
    }

    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct LookupHost(Void);

impl LookupHost {
    pub fn port(&self) -> u16 {
        match self.0 {}
    }
}

impl Iterator for LookupHost {
    type Item = SocketAddr;
    fn next(&mut self) -> Option<SocketAddr> {
        match self.0 {}
    }
}

impl<'a> TryFrom<&'a str> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: &'a str) -> io::Result<LookupHost> {
        unsupported()
    }
}

impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
        unsupported()
    }
}
<commit_msg>Fix cloudabi<commit_after>use fmt;
use io::{self, IoVec, IoVecMut};
use net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use time::Duration;
use sys::{unsupported, Void};
use convert::TryFrom;

pub extern crate libc as netc;

pub struct TcpStream(Void);

impl TcpStream {
    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpStream> {
        match self.0 {}
    }

    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpStream {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct TcpListener(Void);

impl TcpListener {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpListener> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn only_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpListener {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct UdpSocket(Void);

impl UdpSocket {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<UdpSocket> {
        match self.0 {}
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn broadcast(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
        match self.0 {}
    }

    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct LookupHost(Void);

impl LookupHost {
    pub fn port(&self) -> u16 {
        match self.0 {}
    }
}

impl Iterator for LookupHost {
    type Item = SocketAddr;
    fn next(&mut self) -> Option<SocketAddr> {
        match self.0 {}
    }
}

impl<'a> TryFrom<&'a str> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: &'a str) -> io::Result<LookupHost> {
        unsupported()
    }
}

impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
        unsupported()
    }
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/smallest-even-multiple/
pub fn smallest_even_multiple(n: i32) -> i32 {
    todo!()
}

fn main() {
    println!("{}", smallest_even_multiple(5)); // 10
    println!("{}", smallest_even_multiple(6)); // 6
}
<commit_msg>Solve problem 2413<commit_after>// https://leetcode.com/problems/smallest-even-multiple/
pub fn smallest_even_multiple(n: i32) -> i32 {
    if n % 2 == 0 {
        n
    } else {
        n * 2
    }
}

fn main() {
    println!("{}", smallest_even_multiple(5)); // 10
    println!("{}", smallest_even_multiple(6)); // 6
    println!("{}", smallest_even_multiple(7)); // 14
    println!("{}", smallest_even_multiple(1)); // 2
    println!("{}", smallest_even_multiple(4)); // 4
}
<|endoftext|>


<commit_before>use anvil_server::error::*;
use anvil_rpc::editor;
use capnp_rpc::{RpcSystem, twoparty, rpc_twoparty_capnp};
use futures::Future;
use tokio_core::reactor::Core;
use tokio_core::io::Io;
use tokio_uds::UnixStream;

use std::path::Path;

pub struct Command {
    core: Core,
    editor: editor::Client<::capnp::text::Owned>,
    rpc_system: RpcSystem<rpc_twoparty_capnp::Side>,
}

impl Command {
    pub fn new<P>(path: P) -> Result<Self>
        where P: AsRef<Path>
    {
        let core = Core::new().chain_err(|| "unable to create event loop")?;
        let handle = core.handle();

        let stream = UnixStream::connect(path, &handle).chain_err(|| "unable to connect to UDS")?;
        let (reader, writer) = stream.split();

        let rpc_network = Box::new(twoparty::VatNetwork::new(reader,
                                                             writer,
                                                             rpc_twoparty_capnp::Side::Client,
                                                             Default::default()));

        let mut rpc_system = RpcSystem::new(rpc_network, None);
        let editor: editor::Client<::capnp::text::Owned> =
            rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server);

        Ok(Command {
            core: core,
            editor: editor,
            rpc_system: rpc_system,
        })
    }

    pub fn insert(mut self, line: u64, column: u64, text: &str) -> Result<()> {
        let mut request = self.editor.insert_request();
        request.get().set_line(line);
        request.get().set_column(column);
        request.get().set_string(text);

        self.core
            .run(self.rpc_system.join(request.send().promise))
            .chain_err(|| "unable to run event loop")?;
        Ok(())
    }
}
<commit_msg>Fix bug where cli-client would not exit<commit_after>use anvil_server::error::*;
use anvil_rpc::editor;
use capnp_rpc::{RpcSystem, twoparty, rpc_twoparty_capnp};
use futures::Future;
use tokio_core::reactor::Core;
use tokio_core::io::Io;
use tokio_uds::UnixStream;

use std::path::Path;

pub struct Command {
    core: Core,
    editor: editor::Client<::capnp::text::Owned>,
}

impl Command {
    pub fn new<P>(path: P) -> Result<Self>
        where P: AsRef<Path>
    {
        let core = Core::new().chain_err(|| "unable to create event loop")?;
        let handle = core.handle();

        let stream = UnixStream::connect(path, &handle).chain_err(|| "unable to connect to UDS")?;
        let (reader, writer) = stream.split();

        let rpc_network = Box::new(twoparty::VatNetwork::new(reader,
                                                             writer,
                                                             rpc_twoparty_capnp::Side::Client,
                                                             Default::default()));

        let mut rpc_system = RpcSystem::new(rpc_network, None);
        let editor: editor::Client<::capnp::text::Owned> =
            rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server);

        handle.spawn(rpc_system.map_err(|_e| ()));

        Ok(Command {
            core: core,
            editor: editor,
        })
    }

    pub fn insert(mut self, line: u64, column: u64, text: &str) -> Result<()> {
        let mut request = self.editor.insert_request();
        request.get().set_line(line);
        request.get().set_column(column);
        request.get().set_string(text);

        self.core
            .run(request.send().promise)
            .chain_err(|| "unable to run event loop")?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::cell::Cell;

use cairo::{self, MatrixTrait};

use crate::attributes::Attribute;
use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::RenderingError;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;

coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);

pub struct NodeClipPath {
    units: Cell<ClipPathUnits>,
}

impl NodeClipPath {
    pub fn new() -> NodeClipPath {
        NodeClipPath {
            units: Cell::new(ClipPathUnits::default()),
        }
    }

    pub fn get_units(&self) -> ClipPathUnits {
        self.units.get()
    }

    pub fn to_cairo_context(
        &self,
        node: &RsvgNode,
        affine_before_clip: &cairo::Matrix,
        draw_ctx: &mut DrawingCtx,
        bbox: &BoundingBox,
    ) -> Result<(), RenderingError> {
        let cascaded = node.get_cascaded_values();

        let clip_units = self.units.get();

        let child_matrix = if clip_units == ClipPathUnits(CoordUnits::ObjectBoundingBox) {
            if bbox.rect.is_none() {
                // The node being clipped is empty / doesn't have a
                // bounding box, so there's nothing to clip!
                return Ok(());
            }

            let rect = bbox.rect.as_ref().unwrap();

            let bbtransform = cairo::Matrix::new(rect.width, 0.0, 0.0, rect.height, rect.x, rect.y);
            cairo::Matrix::multiply(&bbtransform, affine_before_clip)
        } else {
            *affine_before_clip
        };

        let cr = draw_ctx.get_cairo_context();
        let save_affine = cr.get_matrix();
        cr.set_matrix(child_matrix);

        // here we don't push a layer because we are clipping
        let res = node.draw_children(&cascaded, draw_ctx, true);

        cr.set_matrix(save_affine);

        let cr = draw_ctx.get_cairo_context();
        cr.clip();

        res
    }
}

impl NodeTrait for NodeClipPath {
    fn set_atts(&self, _: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr {
                Attribute::ClipPathUnits => self.units.set(attr.parse(value)?),
                _ => (),
            }
        }

        Ok(())
    }
}
<commit_msg>clip_path.rs: Remove superfluous rebinding of the cr<commit_after>use std::cell::Cell;

use cairo::{self, MatrixTrait};

use crate::attributes::Attribute;
use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::RenderingError;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;

coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);

pub struct NodeClipPath {
    units: Cell<ClipPathUnits>,
}

impl NodeClipPath {
    pub fn new() -> NodeClipPath {
        NodeClipPath {
            units: Cell::new(ClipPathUnits::default()),
        }
    }

    pub fn get_units(&self) -> ClipPathUnits {
        self.units.get()
    }

    pub fn to_cairo_context(
        &self,
        node: &RsvgNode,
        affine_before_clip: &cairo::Matrix,
        draw_ctx: &mut DrawingCtx,
        bbox: &BoundingBox,
    ) -> Result<(), RenderingError> {
        let cascaded = node.get_cascaded_values();

        let clip_units = self.units.get();

        let child_matrix = if clip_units == ClipPathUnits(CoordUnits::ObjectBoundingBox) {
            if bbox.rect.is_none() {
                // The node being clipped is empty / doesn't have a
                // bounding box, so there's nothing to clip!
                return Ok(());
            }

            let rect = bbox.rect.as_ref().unwrap();

            let bbtransform = cairo::Matrix::new(rect.width, 0.0, 0.0, rect.height, rect.x, rect.y);
            cairo::Matrix::multiply(&bbtransform, affine_before_clip)
        } else {
            *affine_before_clip
        };

        let cr = draw_ctx.get_cairo_context();
        let save_affine = cr.get_matrix();
        cr.set_matrix(child_matrix);

        // here we don't push a layer because we are clipping
        let res = node.draw_children(&cascaded, draw_ctx, true);

        cr.set_matrix(save_affine);

        cr.clip();

        res
    }
}

impl NodeTrait for NodeClipPath {
    fn set_atts(&self, _: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr {
                Attribute::ClipPathUnits => self.units.set(attr.parse(value)?),
                _ => (),
            }
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>extern crate cbindgen;

use cbindgen::*;
use std::path::Path;
use std::process::Command;
use std::{env, fs, str};

fn style_str(style: Style) -> &'static str {
    match style {
        Style::Both => "both",
        Style::Tag => "tag",
        Style::Type => "type",
    }
}

fn run_cbindgen(
    cbindgen_path: &'static str,
    path: &Path,
    output: &Path,
    language: Language,
    cpp_compat: bool,
    style: Option<Style>,
) {
    let program = Path::new(cbindgen_path);
    let mut command = Command::new(&program);
    match language {
        Language::Cxx => {}
        Language::C => {
            command.arg("--lang").arg("c");

            if cpp_compat {
                command.arg("--cpp-compat");
            }
        }
    }

    if let Some(style) = style {
        command.arg("--style").arg(style_str(style));
    }

    command.arg("-o").arg(output);

    if env::var("CBINDGEN_TEST_VERIFY").is_ok() {
        command.arg("--verify");
    }

    let mut config = path.clone().to_path_buf();
    config.set_extension("toml");
    if config.exists() {
        command.arg("--config").arg(config);
    }

    command.arg(path);

    println!("Running: {:?}", command);
    let cbindgen_output = command.output().expect("failed to execute process");
    assert!(
        cbindgen_output.status.success(),
        "cbindgen failed: {:?} with error: {}",
        output,
        str::from_utf8(&cbindgen_output.stderr).unwrap_or_default()
    );
}

fn compile(cbindgen_output: &Path, tests_path: &Path, language: Language, style: Option<Style>) {
    let cc = match language {
        Language::Cxx => env::var("CXX").unwrap_or_else(|_| "g++".to_owned()),
        Language::C => env::var("CC").unwrap_or_else(|_| "gcc".to_owned()),
    };

    let mut object = cbindgen_output.to_path_buf();
    object.set_extension("o");

    let mut command = Command::new(cc);
    command.arg("-D").arg("DEFINED");
    command.arg("-c").arg(cbindgen_output);
    command.arg("-o").arg(&object);
    command.arg("-I").arg(tests_path);
    command.arg("-Wall");
    command.arg("-Werror");
    // `swift_name` is not recognzied by gcc.
    command.arg("-Wno-attributes");
    if let Language::Cxx = language {
        // enum class is a c++11 extension which makes g++ on macos 10.14 error out
        // inline variables are are a c++17 extension
        command.arg("-std=c++17");
    }

    if let Some(style) = style {
        command.arg("-D");
        command.arg(format!(
            "CBINDGEN_STYLE_{}",
            style_str(style).to_uppercase()
        ));
    }

    println!("Running: {:?}", command);
    let out = command.output().expect("failed to compile");
    assert!(out.status.success(), "Output failed to compile: {:?}", out);

    if object.exists() {
        fs::remove_file(object).unwrap();
    }
}

fn run_compile_test(
    cbindgen_path: &'static str,
    name: &'static str,
    path: &Path,
    language: Language,
    cpp_compat: bool,
    style: Option<Style>,
) {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let tests_path = Path::new(&crate_dir).join("tests");
    let mut output = tests_path.join("expectations");
    if let Some(style) = style {
        match style {
            Style::Both => {
                output.push("both");
            }
            Style::Tag => {
                output.push("tag");
            }
            Style::Type => {}
        }
    }

    let ext = match language {
        Language::Cxx => "cpp",
        Language::C => {
            if cpp_compat {
                "compat.c"
            } else {
                "c"
            }
        }
    };

    output.push(format!("{}.{}", name, ext));

    run_cbindgen(cbindgen_path, path, &output, language, cpp_compat, style);
    compile(&output, &tests_path, language, style);

    if language == Language::C && cpp_compat {
        compile(&output, &tests_path, Language::Cxx, style)
    }
}

fn test_file(cbindgen_path: &'static str, name: &'static str, filename: &'static str) {
    let test = Path::new(filename);
    for style in &[Style::Type, Style::Tag, Style::Both] {
        for cpp_compat in &[true, false] {
            run_compile_test(
                cbindgen_path,
                name,
                &test,
                Language::C,
                *cpp_compat,
                Some(*style),
            );
        }
    }
    run_compile_test(
        cbindgen_path,
        name,
        &test,
        Language::Cxx,
        /* cpp_compat = */ false,
        None,
    );
}

macro_rules! test_file {
    ($cbindgen_path:expr, $test_function_name:ident, $name:expr, $file:tt) => {
        #[test]
        fn $test_function_name() {
            test_file($cbindgen_path, $name, $file);
        }
    };
}

// This file is generated by build.rs
include!(concat!(env!("OUT_DIR"), "/tests.rs"));
<commit_msg>Check for CFLAGS and CXXFLAGS when running tests<commit_after>extern crate cbindgen;

use cbindgen::*;
use std::path::Path;
use std::process::Command;
use std::{env, fs, str};

fn style_str(style: Style) -> &'static str {
    match style {
        Style::Both => "both",
        Style::Tag => "tag",
        Style::Type => "type",
    }
}

fn run_cbindgen(
    cbindgen_path: &'static str,
    path: &Path,
    output: &Path,
    language: Language,
    cpp_compat: bool,
    style: Option<Style>,
) {
    let program = Path::new(cbindgen_path);
    let mut command = Command::new(&program);
    match language {
        Language::Cxx => {}
        Language::C => {
            command.arg("--lang").arg("c");

            if cpp_compat {
                command.arg("--cpp-compat");
            }
        }
    }

    if let Some(style) = style {
        command.arg("--style").arg(style_str(style));
    }

    command.arg("-o").arg(output);

    if env::var("CBINDGEN_TEST_VERIFY").is_ok() {
        command.arg("--verify");
    }

    let mut config = path.clone().to_path_buf();
    config.set_extension("toml");
    if config.exists() {
        command.arg("--config").arg(config);
    }

    command.arg(path);

    println!("Running: {:?}", command);
    let cbindgen_output = command.output().expect("failed to execute process");
    assert!(
        cbindgen_output.status.success(),
        "cbindgen failed: {:?} with error: {}",
        output,
        str::from_utf8(&cbindgen_output.stderr).unwrap_or_default()
    );
}

fn compile(cbindgen_output: &Path, tests_path: &Path, language: Language, style: Option<Style>) {
    let cc = match language {
        Language::Cxx => env::var("CXX").unwrap_or_else(|_| "g++".to_owned()),
        Language::C => env::var("CC").unwrap_or_else(|_| "gcc".to_owned()),
    };

    let mut object = cbindgen_output.to_path_buf();
    object.set_extension("o");

    let mut command = Command::new(cc);
    command.arg("-D").arg("DEFINED");
    command.arg("-c").arg(cbindgen_output);
    command.arg("-o").arg(&object);
    command.arg("-I").arg(tests_path);
    command.arg("-Wall");
    command.arg("-Werror");
    // `swift_name` is not recognzied by gcc.
    command.arg("-Wno-attributes");
    if let Language::Cxx = language {
        // enum class is a c++11 extension which makes g++ on macos 10.14 error out
        // inline variables are are a c++17 extension
        command.arg("-std=c++17");
        if let Ok(extra_flags) = env::var("CXXFLAGS") {
            command.args(extra_flags.split_whitespace());
        }
    } else {
        if let Ok(extra_flags) = env::var("CFLAGS") {
            command.args(extra_flags.split_whitespace());
        }
    }

    if let Some(style) = style {
        command.arg("-D");
        command.arg(format!(
            "CBINDGEN_STYLE_{}",
            style_str(style).to_uppercase()
        ));
    }

    println!("Running: {:?}", command);
    let out = command.output().expect("failed to compile");
    assert!(out.status.success(), "Output failed to compile: {:?}", out);

    if object.exists() {
        fs::remove_file(object).unwrap();
    }
}

fn run_compile_test(
    cbindgen_path: &'static str,
    name: &'static str,
    path: &Path,
    language: Language,
    cpp_compat: bool,
    style: Option<Style>,
) {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let tests_path = Path::new(&crate_dir).join("tests");
    let mut output = tests_path.join("expectations");
    if let Some(style) = style {
        match style {
            Style::Both => {
                output.push("both");
            }
            Style::Tag => {
                output.push("tag");
            }
            Style::Type => {}
        }
    }

    let ext = match language {
        Language::Cxx => "cpp",
        Language::C => {
            if cpp_compat {
                "compat.c"
            } else {
                "c"
            }
        }
    };

    output.push(format!("{}.{}", name, ext));

    run_cbindgen(cbindgen_path, path, &output, language, cpp_compat, style);
    compile(&output, &tests_path, language, style);

    if language == Language::C && cpp_compat {
        compile(&output, &tests_path, Language::Cxx, style)
    }
}

fn test_file(cbindgen_path: &'static str, name: &'static str, filename: &'static str) {
    let test = Path::new(filename);
    for style in &[Style::Type, Style::Tag, Style::Both] {
        for cpp_compat in &[true, false] {
            run_compile_test(
                cbindgen_path,
                name,
                &test,
                Language::C,
                *cpp_compat,
                Some(*style),
            );
        }
    }
    run_compile_test(
        cbindgen_path,
        name,
        &test,
        Language::Cxx,
        /* cpp_compat = */ false,
        None,
    );
}

macro_rules! test_file {
    ($cbindgen_path:expr, $test_function_name:ident, $name:expr, $file:tt) => {
        #[test]
        fn $test_function_name() {
            test_file($cbindgen_path, $name, $file);
        }
    };
}

// This file is generated by build.rs
include!(concat!(env!("OUT_DIR"), "/tests.rs"));
<|endoftext|>


<commit_before>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate habitat_sup as sup;
extern crate habitat_core as hcore;
extern crate rustc_serialize;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate ansi_term;
extern crate libc;
#[macro_use]
extern crate clap;

use std::process;
use std::result;
use std::str::FromStr;

use ansi_term::Colour::Yellow;
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
use hcore::env as henv;
use hcore::fs;
use hcore::crypto::{default_cache_key_path, SymKey};
use hcore::crypto::init as crypto_init;
use hcore::package::PackageIdent;
use hcore::url::{DEFAULT_DEPOT_URL, DEPOT_URL_ENVVAR};

use sup::config::{Command, Config, UpdateStrategy};
use sup::error::{Error, Result, SupError};
use sup::command::*;
use sup::topology::Topology;
use sup::util::parse_ip_port_with_defaults;
use sup::util::path::busybox_paths;
use sup::util::sys::ip;

/// Our output key
static LOGKEY: &'static str = "MN";

/// The version number
const VERSION: &'static str = include_str!(concat!(env!("OUT_DIR"), "/VERSION"));

/// CLI defaults
static DEFAULT_GROUP: &'static str = "default";

static DEFAULT_HTTP_LISTEN_IP: &'static str = "0.0.0.0";
static DEFAULT_HTTP_LISTEN_PORT: u16 = 9631;

const DEFAULT_GOSSIP_LISTEN_PORT: u16 = 9634;

static RING_ENVVAR: &'static str = "HAB_RING";
static RING_KEY_ENVVAR: &'static str = "HAB_RING_KEY";

/// Creates a [Config](config/struct.Config.html) from global args
/// and subcommand args.
fn config_from_args(args: &ArgMatches, subcommand: &str, sub_args: &ArgMatches) -> Result<Config> {
    let mut config = Config::new();
    let command = try!(Command::from_str(subcommand));
    config.set_command(command);
    if let Some(ref strategy) = sub_args.value_of("strategy") {
        config.set_update_strategy(UpdateStrategy::from_str(strategy));
    }
    if let Some(ref archive) = sub_args.value_of("archive") {
        config.set_archive(archive.to_string());
    }
    if let Some(ref package) = sub_args.value_of("package") {
        let ident = try!(PackageIdent::from_str(package));
        config.set_package(ident);
    }
    if let Some(key) = sub_args.value_of("key") {
        config.set_key(key.to_string());
    }
    if let Some(email) = sub_args.value_of("email") {
        config.set_email(email.to_string());
    }
    if let Some(user) = sub_args.value_of("user") {
        config.set_user_key(user.to_string());
    }
    if let Some(service) = sub_args.value_of("service") {
        config.set_service_key(service.to_string());
    }
    if let Some(infile) = sub_args.value_of("infile") {
        config.set_infile(infile.to_string());
    }
    if let Some(outfile) = sub_args.value_of("outfile") {
        config.set_outfile(outfile.to_string());
    }
    if let Some(topology) = sub_args.value_of("topology") {
        match topology.as_ref() {
            "standalone" => {
                config.set_topology(Topology::Standalone);
            }
            "leader" => {
                config.set_topology(Topology::Leader);
            }
            "initializer" => {
                config.set_topology(Topology::Initializer);
            }
            t => return Err(sup_error!(Error::UnknownTopology(String::from(t)))),
        }
    }
    if sub_args.value_of("expire-days").is_some() {
        let ed = value_t!(sub_args.value_of("expire-days"), u16).unwrap_or_else(|e| e.exit());
        config.set_expire_days(ed);
    }
    let env_or_default = henv::var(DEPOT_URL_ENVVAR).unwrap_or(DEFAULT_DEPOT_URL.to_string());
    let url = sub_args.value_of("url").unwrap_or(&env_or_default);
    config.set_url(url.to_string());
    config.set_group(sub_args.value_of("group").unwrap_or(DEFAULT_GROUP).to_string());
    let bindings = match sub_args.values_of("bind") {
        Some(bind) => bind.map(|s| s.to_string()).collect(),
        None => vec![],
    };
    config.set_bind(bindings);
    config.set_path(sub_args.value_of("path")
        .unwrap_or(fs::svc_path(sup::PROGRAM_NAME.as_str())
            .join("data")
            .to_string_lossy()
            .as_ref())
        .to_string());

    let mut env_path = String::new();
    for path in try!(busybox_paths()) {
        if env_path.len() > 0 {
            env_path.push(':');
        }
        env_path.push_str(path.to_string_lossy().as_ref());
    }
    let default_gossip_ip = try!(ip(Some(&env_path)));
    let (gossip_ip, gossip_port) = try!(parse_ip_port_with_defaults(
                                        sub_args.value_of("listen-peer"),
                                        &default_gossip_ip,
                                        DEFAULT_GOSSIP_LISTEN_PORT));

    debug!("Gossip IP = {}", &gossip_ip);
    debug!("Gossip port = {}", &gossip_port);
    config.set_gossip_listen_ip(gossip_ip);
    config.set_gossip_listen_port(gossip_port);

    let (sidecar_ip, sidecar_port) = try!(parse_ip_port_with_defaults(
                                            sub_args.value_of("listen-http"),
                                            DEFAULT_HTTP_LISTEN_IP,
                                            DEFAULT_HTTP_LISTEN_PORT));

    debug!("HTTP IP = {}", &sidecar_ip);
    debug!("HTTP port = {}", &sidecar_port);

    config.set_http_listen_ip(sidecar_ip);
    config.set_http_listen_port(sidecar_port);

    let gossip_peers = match sub_args.values_of("peer") {
        Some(gp) => gp.map(|s| s.to_string()).collect(),
        None => vec![],
    };
    config.set_gossip_peer(gossip_peers);
    if sub_args.value_of("permanent-peer").is_some() {
        config.set_gossip_permanent(true);
    }
    if let Some(sg) = sub_args.value_of("service-group") {
        config.set_service_group(sg.to_string());
    }
    if let Some(fp) = sub_args.value_of("file-path") {
        config.set_file_path(fp.to_string());
    }
    config.set_version_number(value_t!(sub_args, "version-number", u64).unwrap_or(0));
    let ring = match sub_args.value_of("ring") {
        Some(val) => Some(try!(SymKey::get_latest_pair_for(&val, &default_cache_key_path(None)))),
        None => {
            match henv::var(RING_KEY_ENVVAR) {
                Ok(val) => {
                    let (key, _) = try!(SymKey::write_file_from_str(&val,
                                                                    &default_cache_key_path(None)));
                    Some(key)
                }
                Err(_) => {
                    match henv::var(RING_ENVVAR) {
                        Ok(val) => {
                            Some(try!(SymKey::get_latest_pair_for(&val,
                                                                  &default_cache_key_path(None))))
                        }
                        Err(_) => None,
                    }
                }
            }
        }
    };
    if let Some(ring) = ring {
        config.set_ring(ring.name_with_rev());
    }
    if args.value_of("verbose").is_some() {
        sup::output::set_verbose(true);
    }
    if args.value_of("no-color").is_some() {
        sup::output::set_no_color(true);
    }

    if let Some(org) = sub_args.value_of("organization") {
        config.set_organization(org.to_string());
    }
    debug!("Config:\n{:?}", config);
    Ok(config)
}

type Handler = fn(&Config) -> result::Result<(), sup::error::SupError>;

/// The entrypoint for the Supervisor.
///
/// * Set up the logger
/// * Pull in the arguments from the Command Line, push through clap
/// * Dispatch to a function that handles that action called
/// * Exit cleanly, or if we return an `Error`, call `exit_with(E, 1)`
#[allow(dead_code)]
fn main() {
    env_logger::init().unwrap();
    crypto_init();

    let arg_url = || {
        Arg::with_name("url")
            .short("u")
            .long("url")
            .takes_value(true)
            .help("Use the specified package depot url")
    };
    let arg_group = || {
        Arg::with_name("group")
            .long("group")
            .takes_value(true)
            .help("The service group; shared config and topology [default: default].")
    };

    let arg_org = || {
        Arg::with_name("organization")
            .long("org")
            .takes_value(true)
            .help("The organization that a service is part of")
    };

    let arg_strategy = || {
        Arg::with_name("strategy")
            .long("strategy")
            .short("s")
            .takes_value(true)
            .possible_values(&["none", "at-once"])
            .help("The update strategy; [default: none].")
    };

    let sub_start = SubCommand::with_name("start")
        .about("Start a Habitat-supervised service from a package")
        .aliases(&["st", "sta", "star"])
        .arg(Arg::with_name("package")
            .index(1)
            .required(true)
            .help("Name of package to start"))
        .arg(arg_url())
        .arg(arg_group())
        .arg(arg_org())
        .arg(arg_strategy())
        .arg(Arg::with_name("topology")
            .short("t")
            .long("topology")
            .value_name("topology")
            .help("Service topology"))
        .arg(Arg::with_name("bind")
            .long("bind")
            .value_name("bind")
            .multiple(true)
            .help("One or more service groups to bind to a configuration"))
        .arg(Arg::with_name("ring")
            .short("r")
            .long("ring")
            .value_name("ring")
            .help("Ring key name"))
        .arg(Arg::with_name("peer")
            .long("peer")
            .value_name("ip:port")
            .multiple(true)
            .help("The listen address of an initial peer"))
        .arg(Arg::with_name("listen-peer")
            .long("listen-peer")
            .value_name("ip:port")
            .help("The listen address [default: ip_with_default_route:9634]"))
        .arg(Arg::with_name("listen-http")
            .long("listen-http")
            .value_name("ip:port")
            .help("The HTTP API listen address [default: 0.0.0.0:9631]"))
        .arg(Arg::with_name("permanent-peer")
            .short("I")
            .long("permanent-peer")
            .help("If this service is a permanent peer"));
    let sub_bash = SubCommand::with_name("bash")
        .about("Start an interactive shell (bash)")
        .aliases(&["b", "ba", "bas"]);
    let sub_sh = SubCommand::with_name("sh").about("Start an interactive shell (sh)");
    let sub_config = SubCommand::with_name("config")
        .about("Print the default.toml for a given package")
        .aliases(&["c", "co", "con", "conf", "confi"])
        .arg(Arg::with_name("package")
            .index(1)
            .required(true)
            .help("Name of package"));
    let args = App::new(sup::PROGRAM_NAME.as_str())
        .version(VERSION)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .arg(Arg::with_name("verbose")
            .short("v")
            .global(true)
            .help("Verbose output; shows line numbers"))
        .arg(Arg::with_name("no-color")
            .long("no-color")
            .global(true)
            .help("Turn ANSI color off :("))
        .subcommand(sub_start)
        .subcommand(sub_bash)
        .subcommand(sub_sh)
        .subcommand(sub_config);
    let matches = args.get_matches();

    debug!("clap matches {:?}", matches);

    let subcommand_name = matches.subcommand_name().unwrap();
    let subcommand_matches = matches.subcommand_matches(subcommand_name).unwrap();

    let config = match config_from_args(&matches, subcommand_name, &subcommand_matches) {
        Ok(config) => config,
        Err(e) => return exit_with(e, 1),
    };

    let result = match config.command() {
        Command::ShellBash => shell_bash(&config),
        Command::ShellSh => shell_sh(&config),
        Command::Config => configure(&config),
        Command::Start => start(&config),
    };

    match result {
        Ok(_) => std::process::exit(0),
        Err(e) => exit_with(e, 1),
    }
}

/// Exit with an error message and the right status code
#[allow(dead_code)]
fn exit_with(e: SupError, code: i32) {
    println!("{}", e.to_string());
    process::exit(code)
}

/// Start a sh shell
#[allow(dead_code)]
fn shell_sh(_config: &Config) -> Result<()> {
    shell::sh()
}

/// Start a bash shell
#[allow(dead_code)]
fn shell_bash(_config: &Config) -> Result<()> {
    shell::bash()
}

/// Show the configuration options for a service
#[allow(dead_code)]
fn configure(config: &Config) -> Result<()> {
    try!(configure::display(config));
    Ok(())
}

/// Start a service
#[allow(dead_code)]
fn start(config: &Config) -> Result<()> {
    outputln!("Starting {}",
              Yellow.bold().paint(config.package().to_string()));
    try!(start::package(config));
    outputln!("Finished with {}",
              Yellow.bold().paint(config.package().to_string()));
    Ok(())
}
<commit_msg>Auto merge of #996 - habitat-sh:dp_fix_args_with_params, r=smith<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate habitat_sup as sup;
extern crate habitat_core as hcore;
extern crate rustc_serialize;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate ansi_term;
extern crate libc;
#[macro_use]
extern crate clap;

use std::process;
use std::result;
use std::str::FromStr;

use ansi_term::Colour::Yellow;
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
use hcore::env as henv;
use hcore::fs;
use hcore::crypto::{default_cache_key_path, SymKey};
use hcore::crypto::init as crypto_init;
use hcore::package::PackageIdent;
use hcore::url::{DEFAULT_DEPOT_URL, DEPOT_URL_ENVVAR};

use sup::config::{Command, Config, UpdateStrategy};
use sup::error::{Error, Result, SupError};
use sup::command::*;
use sup::topology::Topology;
use sup::util::parse_ip_port_with_defaults;
use sup::util::path::busybox_paths;
use sup::util::sys::ip;

/// Our output key
static LOGKEY: &'static str = "MN";

/// The version number
const VERSION: &'static str = include_str!(concat!(env!("OUT_DIR"), "/VERSION"));

/// CLI defaults
static DEFAULT_GROUP: &'static str = "default";

static DEFAULT_HTTP_LISTEN_IP: &'static str = "0.0.0.0";
static DEFAULT_HTTP_LISTEN_PORT: u16 = 9631;

const DEFAULT_GOSSIP_LISTEN_PORT: u16 = 9634;

static RING_ENVVAR: &'static str = "HAB_RING";
static RING_KEY_ENVVAR: &'static str = "HAB_RING_KEY";

/// Creates a [Config](config/struct.Config.html) from global args
/// and subcommand args.
fn config_from_args(subcommand: &str, sub_args: &ArgMatches) -> Result<Config> {
    let mut config = Config::new();
    let command = try!(Command::from_str(subcommand));
    config.set_command(command);
    if let Some(ref strategy) = sub_args.value_of("strategy") {
        config.set_update_strategy(UpdateStrategy::from_str(strategy));
    }
    if let Some(ref archive) = sub_args.value_of("archive") {
        config.set_archive(archive.to_string());
    }
    if let Some(ref package) = sub_args.value_of("package") {
        let ident = try!(PackageIdent::from_str(package));
        config.set_package(ident);
    }
    if let Some(key) = sub_args.value_of("key") {
        config.set_key(key.to_string());
    }
    if let Some(email) = sub_args.value_of("email") {
        config.set_email(email.to_string());
    }
    if let Some(user) = sub_args.value_of("user") {
        config.set_user_key(user.to_string());
    }
    if let Some(service) = sub_args.value_of("service") {
        config.set_service_key(service.to_string());
    }
    if let Some(infile) = sub_args.value_of("infile") {
        config.set_infile(infile.to_string());
    }
    if let Some(outfile) = sub_args.value_of("outfile") {
        config.set_outfile(outfile.to_string());
    }
    if let Some(topology) = sub_args.value_of("topology") {
        match topology.as_ref() {
            "standalone" => {
                config.set_topology(Topology::Standalone);
            }
            "leader" => {
                config.set_topology(Topology::Leader);
            }
            "initializer" => {
                config.set_topology(Topology::Initializer);
            }
            t => return Err(sup_error!(Error::UnknownTopology(String::from(t)))),
        }
    }
    if sub_args.value_of("expire-days").is_some() {
        let ed = value_t!(sub_args.value_of("expire-days"), u16).unwrap_or_else(|e| e.exit());
        config.set_expire_days(ed);
    }
    let env_or_default = henv::var(DEPOT_URL_ENVVAR).unwrap_or(DEFAULT_DEPOT_URL.to_string());
    let url = sub_args.value_of("url").unwrap_or(&env_or_default);
    config.set_url(url.to_string());
    config.set_group(sub_args.value_of("group").unwrap_or(DEFAULT_GROUP).to_string());
    let bindings = match sub_args.values_of("bind") {
        Some(bind) => bind.map(|s| s.to_string()).collect(),
        None => vec![],
    };
    config.set_bind(bindings);
    config.set_path(sub_args.value_of("path")
        .unwrap_or(fs::svc_path(sup::PROGRAM_NAME.as_str())
            .join("data")
            .to_string_lossy()
            .as_ref())
        .to_string());

    let mut env_path = String::new();
    for path in try!(busybox_paths()) {
        if env_path.len() > 0 {
            env_path.push(':');
        }
        env_path.push_str(path.to_string_lossy().as_ref());
    }
    let default_gossip_ip = try!(ip(Some(&env_path)));
    let (gossip_ip, gossip_port) = try!(parse_ip_port_with_defaults(
                                        sub_args.value_of("listen-peer"),
                                        &default_gossip_ip,
                                        DEFAULT_GOSSIP_LISTEN_PORT));

    debug!("Gossip IP = {}", &gossip_ip);
    debug!("Gossip port = {}", &gossip_port);
    config.set_gossip_listen_ip(gossip_ip);
    config.set_gossip_listen_port(gossip_port);

    let (sidecar_ip, sidecar_port) = try!(parse_ip_port_with_defaults(
                                            sub_args.value_of("listen-http"),
                                            DEFAULT_HTTP_LISTEN_IP,
                                            DEFAULT_HTTP_LISTEN_PORT));

    debug!("HTTP IP = {}", &sidecar_ip);
    debug!("HTTP port = {}", &sidecar_port);

    config.set_http_listen_ip(sidecar_ip);
    config.set_http_listen_port(sidecar_port);

    let gossip_peers = match sub_args.values_of("peer") {
        Some(gp) => gp.map(|s| s.to_string()).collect(),
        None => vec![],
    };
    config.set_gossip_peer(gossip_peers);
    if sub_args.is_present("permanent-peer") {
        config.set_gossip_permanent(true);
    }
    if let Some(sg) = sub_args.value_of("service-group") {
        config.set_service_group(sg.to_string());
    }
    if let Some(fp) = sub_args.value_of("file-path") {
        config.set_file_path(fp.to_string());
    }
    config.set_version_number(value_t!(sub_args, "version-number", u64).unwrap_or(0));
    let ring = match sub_args.value_of("ring") {
        Some(val) => Some(try!(SymKey::get_latest_pair_for(&val, &default_cache_key_path(None)))),
        None => {
            match henv::var(RING_KEY_ENVVAR) {
                Ok(val) => {
                    let (key, _) = try!(SymKey::write_file_from_str(&val,
                                                                    &default_cache_key_path(None)));
                    Some(key)
                }
                Err(_) => {
                    match henv::var(RING_ENVVAR) {
                        Ok(val) => {
                            Some(try!(SymKey::get_latest_pair_for(&val,
                                                                  &default_cache_key_path(None))))
                        }
                        Err(_) => None,
                    }
                }
            }
        }
    };
    if let Some(ring) = ring {
        config.set_ring(ring.name_with_rev());
    }
    if sub_args.is_present("verbose") {
        sup::output::set_verbose(true);
    }
    if sub_args.is_present("no-color") {
        sup::output::set_no_color(true);
    }
    if let Some(org) = sub_args.value_of("organization") {
        config.set_organization(org.to_string());
    }
    debug!("Config:\n{:?}", config);
    Ok(config)
}

type Handler = fn(&Config) -> result::Result<(), sup::error::SupError>;

/// The entrypoint for the Supervisor.
///
/// * Set up the logger
/// * Pull in the arguments from the Command Line, push through clap
/// * Dispatch to a function that handles that action called
/// * Exit cleanly, or if we return an `Error`, call `exit_with(E, 1)`
#[allow(dead_code)]
fn main() {
    env_logger::init().unwrap();
    crypto_init();

    let arg_url = || {
        Arg::with_name("url")
            .short("u")
            .long("url")
            .takes_value(true)
            .help("Use the specified package depot url")
    };
    let arg_group = || {
        Arg::with_name("group")
            .long("group")
            .takes_value(true)
            .help("The service group; shared config and topology [default: default].")
    };

    let arg_org = || {
        Arg::with_name("organization")
            .long("org")
            .takes_value(true)
            .help("The organization that a service is part of")
    };

    let arg_strategy = || {
        Arg::with_name("strategy")
            .long("strategy")
            .short("s")
            .takes_value(true)
            .possible_values(&["none", "at-once"])
            .help("The update strategy; [default: none].")
    };

    let sub_start = SubCommand::with_name("start")
        .about("Start a Habitat-supervised service from a package")
        .aliases(&["st", "sta", "star"])
        .arg(Arg::with_name("package")
            .index(1)
            .required(true)
            .help("Name of package to start"))
        .arg(arg_url())
        .arg(arg_group())
        .arg(arg_org())
        .arg(arg_strategy())
        .arg(Arg::with_name("topology")
            .short("t")
            .long("topology")
            .value_name("topology")
            .help("Service topology"))
        .arg(Arg::with_name("bind")
            .long("bind")
            .value_name("bind")
            .multiple(true)
            .help("One or more service groups to bind to a configuration"))
        .arg(Arg::with_name("ring")
            .short("r")
            .long("ring")
            .value_name("ring")
            .help("Ring key name"))
        .arg(Arg::with_name("peer")
            .long("peer")
            .value_name("ip:port")
            .multiple(true)
            .help("The listen address of an initial peer"))
        .arg(Arg::with_name("listen-peer")
            .long("listen-peer")
            .value_name("ip:port")
            .help("The listen address [default: ip_with_default_route:9634]"))
        .arg(Arg::with_name("listen-http")
            .long("listen-http")
            .value_name("ip:port")
            .help("The HTTP API listen address [default: 0.0.0.0:9631]"))
        .arg(Arg::with_name("permanent-peer")
            .short("I")
            .long("permanent-peer")
            .help("If this service is a permanent peer"));
    let sub_bash = SubCommand::with_name("bash")
        .about("Start an interactive shell (bash)")
        .aliases(&["b", "ba", "bas"]);
    let sub_sh = SubCommand::with_name("sh").about("Start an interactive shell (sh)");
    let sub_config = SubCommand::with_name("config")
        .about("Print the default.toml for a given package")
        .aliases(&["c", "co", "con", "conf", "confi"])
        .arg(Arg::with_name("package")
            .index(1)
            .required(true)
            .help("Name of package"));
    let args = App::new(sup::PROGRAM_NAME.as_str())
        .version(VERSION)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .arg(Arg::with_name("verbose")
            .short("v")
            .global(true)
            .help("Verbose output; shows line numbers"))
        .arg(Arg::with_name("no-color")
            .long("no-color")
            .global(true)
            .help("Turn ANSI color off :("))
        .subcommand(sub_start)
        .subcommand(sub_bash)
        .subcommand(sub_sh)
        .subcommand(sub_config);
    let matches = args.get_matches();

    debug!("clap matches {:?}", matches);
    let subcommand_name = matches.subcommand_name().unwrap();
    let subcommand_matches = matches.subcommand_matches(subcommand_name).unwrap();
    debug!("subcommand name {:?}", &subcommand_name);
    debug!("Subcommand matches {:?}", &subcommand_matches);

    let config = match config_from_args(subcommand_name, &subcommand_matches) {
        Ok(config) => config,
        Err(e) => return exit_with(e, 1),
    };

    let result = match config.command() {
        Command::ShellBash => shell_bash(&config),
        Command::ShellSh => shell_sh(&config),
        Command::Config => configure(&config),
        Command::Start => start(&config),
    };

    match result {
        Ok(_) => std::process::exit(0),
        Err(e) => exit_with(e, 1),
    }
}

/// Exit with an error message and the right status code
#[allow(dead_code)]
fn exit_with(e: SupError, code: i32) {
    println!("{}", e.to_string());
    process::exit(code)
}

/// Start a sh shell
#[allow(dead_code)]
fn shell_sh(_config: &Config) -> Result<()> {
    shell::sh()
}

/// Start a bash shell
#[allow(dead_code)]
fn shell_bash(_config: &Config) -> Result<()> {
    shell::bash()
}

/// Show the configuration options for a service
#[allow(dead_code)]
fn configure(config: &Config) -> Result<()> {
    try!(configure::display(config));
    Ok(())
}

/// Start a service
#[allow(dead_code)]
fn start(config: &Config) -> Result<()> {
    outputln!("Starting {}",
              Yellow.bold().paint(config.package().to_string()));
    try!(start::package(config));
    outputln!("Finished with {}",
              Yellow.bold().paint(config.package().to_string()));
    Ok(())
}
<|endoftext|>


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

use js::jsapi::{JSVal, JSBool, JSContext};
use js::jsapi::{JS_ValueToInt64, JS_ValueToECMAInt32, JS_ValueToECMAUint32};
use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean};
use js::{JSVAL_FALSE, JSVAL_TRUE};
use js::glue::{RUST_UINT_TO_JSVAL, RUST_DOUBLE_TO_JSVAL};

pub trait JSValConvertible {
    fn to_jsval(&self) -> JSVal;
    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<Self>;
}

unsafe fn convert_from_jsval<T: Default>(
    cx: *JSContext, value: JSVal,
    convert_fn: extern "C" unsafe fn(*JSContext, JSVal, *T) -> JSBool) -> Option<T> {
    let mut ret = Default::default();
    if convert_fn(cx, value, &mut ret as *mut T as *T) == 0 {
        None
    } else {
        Some(ret)
    }
}

impl JSValConvertible for i64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i64> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) }
    }
}

impl JSValConvertible for u32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u32> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) }
    }
}

impl JSValConvertible for i32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i32> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }
    }
}

impl JSValConvertible for u16 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u16> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) }
    }
}

impl JSValConvertible for bool {
    fn to_jsval(&self) -> JSVal {
        if *self {
            JSVAL_TRUE
        } else {
            JSVAL_FALSE
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<bool> {
        let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) };
        result.map(|b| b != 0)
    }
}

impl JSValConvertible for f32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f32> {
        let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) };
        result.map(|f| f as f32)
    }
}

impl JSValConvertible for f64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f64> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }
    }
}
<commit_msg>Reorder implementations in conversions.rs.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use js::jsapi::{JSVal, JSBool, JSContext};
use js::jsapi::{JS_ValueToInt64, JS_ValueToECMAInt32, JS_ValueToECMAUint32};
use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean};
use js::{JSVAL_FALSE, JSVAL_TRUE};
use js::glue::{RUST_UINT_TO_JSVAL, RUST_DOUBLE_TO_JSVAL};

pub trait JSValConvertible {
    fn to_jsval(&self) -> JSVal;
    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<Self>;
}

unsafe fn convert_from_jsval<T: Default>(
    cx: *JSContext, value: JSVal,
    convert_fn: extern "C" unsafe fn(*JSContext, JSVal, *T) -> JSBool) -> Option<T> {
    let mut ret = Default::default();
    if convert_fn(cx, value, &mut ret as *mut T as *T) == 0 {
        None
    } else {
        Some(ret)
    }
}

impl JSValConvertible for bool {
    fn to_jsval(&self) -> JSVal {
        if *self {
            JSVAL_TRUE
        } else {
            JSVAL_FALSE
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<bool> {
        let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) };
        result.map(|b| b != 0)
    }
}

impl JSValConvertible for u16 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u16> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) }
    }
}

impl JSValConvertible for i32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self as u32)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i32> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }
    }
}

impl JSValConvertible for u32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_UINT_TO_JSVAL(*self)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u32> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) }
    }
}

impl JSValConvertible for i64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i64> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) }
    }
}

impl JSValConvertible for f32 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f32> {
        let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) };
        result.map(|f| f as f32)
    }
}

impl JSValConvertible for f64 {
    fn to_jsval(&self) -> JSVal {
        unsafe {
            RUST_DOUBLE_TO_JSVAL(*self as f64)
        }
    }

    fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f64> {
        unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
//
// 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 crate::{
    attrs::{Attrs, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING},
    dummies,
    utils::Sp,
};

use proc_macro2::{Span, TokenStream};
use proc_macro_error::{abort, abort_call_site};
use quote::quote;
use syn::{
    punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, Data, DataEnum, DeriveInput,
    Fields, Ident, Variant,
};

pub fn derive_value_enum(input: &DeriveInput) -> TokenStream {
    let ident = &input.ident;

    dummies::value_enum(ident);

    match input.data {
        Data::Enum(ref e) => gen_for_enum(ident, &input.attrs, e),
        _ => abort_call_site!("`#[derive(ValueEnum)]` only supports enums"),
    }
}

pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStream {
    let attrs = Attrs::from_struct(
        Span::call_site(),
        attrs,
        Name::Derived(name.clone()),
        Sp::call_site(DEFAULT_CASING),
        Sp::call_site(DEFAULT_ENV_CASING),
    );

    let lits = lits(&e.variants, &attrs);
    let value_variants = gen_value_variants(&lits);
    let to_possible_value = gen_to_possible_value(&lits);

    quote! {
        #[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
        #[allow(
            clippy::style,
            clippy::complexity,
            clippy::pedantic,
            clippy::restriction,
            clippy::perf,
            clippy::deprecated,
            clippy::nursery,
            clippy::cargo,
            clippy::suspicious_else_formatting,
        )]
        #[deny(clippy::correctness)]
        impl clap::ValueEnum for #name {
            #value_variants
            #to_possible_value
        }
    }
}

fn lits(
    variants: &Punctuated<Variant, Comma>,
    parent_attribute: &Attrs,
) -> Vec<(TokenStream, Ident)> {
    variants
        .iter()
        .filter_map(|variant| {
            let attrs = Attrs::from_value_enum_variant(
                variant,
                parent_attribute.casing(),
                parent_attribute.env_casing(),
            );
            if let Kind::Skip(_) = &*attrs.kind() {
                None
            } else {
                if !matches!(variant.fields, Fields::Unit) {
                    abort!(variant.span(), "`#[derive(ValueEnum)]` only supports non-unit variants, unless they are skipped");
                }
                let fields = attrs.field_methods(false);
                let name = attrs.cased_name();
                Some((
                    quote! {
                        clap::PossibleValue::new(#name)
                        #fields
                    },
                    variant.ident.clone(),
                ))
            }
        })
        .collect::<Vec<_>>()
}

fn gen_value_variants(lits: &[(TokenStream, Ident)]) -> TokenStream {
    let lit = lits.iter().map(|l| &l.1).collect::<Vec<_>>();

    quote! {
        fn value_variants<'a>() -> &'a [Self]{
            &[#(Self::#lit),*]
        }
    }
}

fn gen_to_possible_value(lits: &[(TokenStream, Ident)]) -> TokenStream {
    let (lit, variant): (Vec<TokenStream>, Vec<Ident>) = lits.iter().cloned().unzip();

    quote! {
        fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::PossibleValue<'a>> {
            match self {
                #(Self::#variant => Some(#lit),)*
                _ => None
            }
        }
    }
}
<commit_msg>fix(derive): Set the span for code generation<commit_after>// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
//
// 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 crate::{
    attrs::{Attrs, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING},
    dummies,
    utils::Sp,
};

use proc_macro2::{Span, TokenStream};
use proc_macro_error::{abort, abort_call_site};
use quote::quote;
use quote::quote_spanned;
use syn::{
    punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, Data, DataEnum, DeriveInput,
    Fields, Ident, Variant,
};

pub fn derive_value_enum(input: &DeriveInput) -> TokenStream {
    let ident = &input.ident;

    dummies::value_enum(ident);

    match input.data {
        Data::Enum(ref e) => gen_for_enum(ident, &input.attrs, e),
        _ => abort_call_site!("`#[derive(ValueEnum)]` only supports enums"),
    }
}

pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStream {
    let attrs = Attrs::from_struct(
        Span::call_site(),
        attrs,
        Name::Derived(name.clone()),
        Sp::call_site(DEFAULT_CASING),
        Sp::call_site(DEFAULT_ENV_CASING),
    );

    let lits = lits(&e.variants, &attrs);
    let value_variants = gen_value_variants(&lits);
    let to_possible_value = gen_to_possible_value(&lits);

    quote! {
        #[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
        #[allow(
            clippy::style,
            clippy::complexity,
            clippy::pedantic,
            clippy::restriction,
            clippy::perf,
            clippy::deprecated,
            clippy::nursery,
            clippy::cargo,
            clippy::suspicious_else_formatting,
        )]
        #[deny(clippy::correctness)]
        impl clap::ValueEnum for #name {
            #value_variants
            #to_possible_value
        }
    }
}

fn lits(
    variants: &Punctuated<Variant, Comma>,
    parent_attribute: &Attrs,
) -> Vec<(TokenStream, Ident)> {
    variants
        .iter()
        .filter_map(|variant| {
            let attrs = Attrs::from_value_enum_variant(
                variant,
                parent_attribute.casing(),
                parent_attribute.env_casing(),
            );
            if let Kind::Skip(_) = &*attrs.kind() {
                None
            } else {
                if !matches!(variant.fields, Fields::Unit) {
                    abort!(variant.span(), "`#[derive(ValueEnum)]` only supports non-unit variants, unless they are skipped");
                }
                let fields = attrs.field_methods(false);
                let name = attrs.cased_name();
                Some((
                    quote_spanned! { variant.span()=>
                        clap::PossibleValue::new(#name)
                        #fields
                    },
                    variant.ident.clone(),
                ))
            }
        })
        .collect::<Vec<_>>()
}

fn gen_value_variants(lits: &[(TokenStream, Ident)]) -> TokenStream {
    let lit = lits.iter().map(|l| &l.1).collect::<Vec<_>>();

    quote! {
        fn value_variants<'a>() -> &'a [Self]{
            &[#(Self::#lit),*]
        }
    }
}

fn gen_to_possible_value(lits: &[(TokenStream, Ident)]) -> TokenStream {
    let (lit, variant): (Vec<TokenStream>, Vec<Ident>) = lits.iter().cloned().unzip();

    quote! {
        fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::PossibleValue<'a>> {
            match self {
                #(Self::#variant => Some(#lit),)*
                _ => None
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Read;

pub fn render_playpen(s: &str, path: &Path) -> String {
    // When replacing one thing in a string by something with a different length, the indices
    // after that will not correspond, we therefore have to store the difference to correct this
    let mut previous_end_index = 0;
    let mut replaced = String::new();

    for playpen in find_playpens(s, path) {

        if playpen.escaped {
            replaced.push_str(&s[previous_end_index..playpen.start_index - 1]);
            replaced.push_str(&s[playpen.start_index..playpen.end_index]);
            previous_end_index = playpen.end_index;
            continue;
        }

        // Check if the file exists
        if !playpen.rust_file.exists() || !playpen.rust_file.is_file() {
            warn!("[-] No file exists for {{{{#playpen }}}}\n    {}", playpen.rust_file.to_str().unwrap());
            continue;
        }

        // Open file & read file
        let mut file = if let Ok(f) = File::open(&playpen.rust_file) {
            f
        } else {
            continue;
        };
        let mut file_content = String::new();
        if file.read_to_string(&mut file_content).is_err() {
            continue;
        };

        let replacement = String::new() + "
" + &file_content +
                          "
";

        replaced.push_str(&s[previous_end_index..playpen.start_index]);
        replaced.push_str(&replacement);
        previous_end_index = playpen.end_index;
        // println!("Playpen{{ {}, {}, {:?}, {} }}", playpen.start_index, playpen.end_index, playpen.rust_file,
        // playpen.editable);
    }

    replaced.push_str(&s[previous_end_index..]);

    replaced
}

#[derive(PartialOrd, PartialEq, Debug)]
struct Playpen {
    start_index: usize,
    end_index: usize,
    rust_file: PathBuf,
    editable: bool,
    escaped: bool,
}

fn find_playpens(s: &str, base_path: &Path) -> Vec<Playpen> {
    let mut playpens = vec![];
    for (i, _) in s.match_indices("{{#playpen") {
        debug!("[*]: find_playpen");

        let mut escaped = false;

        if i > 0 {
            if let Some(c) = s[i - 1..].chars().nth(0) {
                if c == '\\' {
                    escaped = true
                }
            }
        }
        // DON'T forget the "+ i" else you have an index out of bounds error !!
        let end_i = if let Some(n) = s[i..].find("}}") {
            n
        } else {
            continue;
        } + i + 2;

        debug!("s[{}..{}] = {}", i, end_i, s[i..end_i].to_string());

        // If there is nothing between "{{#playpen" and "}}" skip
        if end_i - 2 - (i + 10) < 1 {
            continue;
        }
        if s[i + 10..end_i - 2].trim().is_empty() {
            continue;
        }

        debug!("{}", s[i + 10..end_i - 2].to_string());

        // Split on whitespaces
        let params: Vec<&str> = s[i + 10..end_i - 2].split_whitespace().collect();
        let editable = params
            .get(1)
            .map(|p| p.find("editable").is_some())
            .unwrap_or(false);

        playpens.push(Playpen {
            start_index: i,
            end_index: end_i,
            rust_file: base_path.join(PathBuf::from(params[0])),
            editable: editable,
            escaped: escaped,
        })
    }

    playpens
}

// ---------------------------------------------------------------------------------
//      Tests
//

#[test]
fn test_find_playpens_no_playpen() {
    let s = "Some random text without playpen...";
    assert!(find_playpens(s, Path::new("")) == vec![]);
}

#[test]
fn test_find_playpens_partial_playpen() {
    let s = "Some random text with {{#playpen...";
    assert!(find_playpens(s, Path::new("")) == vec![]);
}

#[test]
fn test_find_playpens_empty_playpen() {
    let s = "Some random text with {{#playpen}} and {{#playpen   }}...";
    assert!(find_playpens(s, Path::new("")) == vec![]);
}

#[test]
fn test_find_playpens_simple_playpen() {
    let s = "Some random text with {{#playpen file.rs}} and {{#playpen test.rs }}...";

    println!("\nOUTPUT: {:?}\n", find_playpens(s, Path::new("")));

    assert!(find_playpens(s, Path::new("")) ==
            vec![Playpen {
                     start_index: 22,
                     end_index: 42,
                     rust_file: PathBuf::from("file.rs"),
                     editable: false,
                     escaped: false,
                 },
                 Playpen {
                     start_index: 47,
                     end_index: 68,
                     rust_file: PathBuf::from("test.rs"),
                     editable: false,
                     escaped: false,
                 }]);
}

#[test]
fn test_find_playpens_complex_playpen() {
    let s = "Some random text with {{#playpen file.rs editable}} and {{#playpen test.rs editable }}...";

    println!("\nOUTPUT: {:?}\n", find_playpens(s, Path::new("dir")));

    assert!(find_playpens(s, Path::new("dir")) ==
            vec![Playpen {
                     start_index: 22,
                     end_index: 51,
                     rust_file: PathBuf::from("dir/file.rs"),
                     editable: true,
                     escaped: false,
                 },
                 Playpen {
                     start_index: 56,
                     end_index: 86,
                     rust_file: PathBuf::from("dir/test.rs"),
                     editable: true,
                     escaped: false,
                 }]);
}

#[test]
fn test_find_playpens_escaped_playpen() {
    let s = "Some random text with escaped playpen \\{{#playpen file.rs editable}} ...";

    println!("\nOUTPUT: {:?}\n", find_playpens(s, Path::new("")));

    assert!(find_playpens(s, Path::new("")) ==
            vec![
        Playpen{start_index: 39, end_index: 68, rust_file: PathBuf::from("file.rs"), editable: true, escaped: true},
    ]);
}
<commit_msg>Remove the extra run button on runnable rust files<commit_after>use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Read;

pub fn render_playpen(s: &str, path: &Path) -> String {
    // When replacing one thing in a string by something with a different length, the indices
    // after that will not correspond, we therefore have to store the difference to correct this
    let mut previous_end_index = 0;
    let mut replaced = String::new();

    for playpen in find_playpens(s, path) {

        if playpen.escaped {
            replaced.push_str(&s[previous_end_index..playpen.start_index - 1]);
            replaced.push_str(&s[playpen.start_index..playpen.end_index]);
            previous_end_index = playpen.end_index;
            continue;
        }

        // Check if the file exists
        if !playpen.rust_file.exists() || !playpen.rust_file.is_file() {
            warn!("[-] No file exists for {{{{#playpen }}}}\n    {}", playpen.rust_file.to_str().unwrap());
            continue;
        }

        // Open file & read file
        let mut file = if let Ok(f) = File::open(&playpen.rust_file) {
            f
        } else {
            continue;
        };
        let mut file_content = String::new();
        if file.read_to_string(&mut file_content).is_err() {
            continue;
        };

        let replacement = String::new() + "
" + &file_content +
                          "
";

        replaced.push_str(&s[previous_end_index..playpen.start_index]);
        replaced.push_str(&replacement);
        previous_end_index = playpen.end_index;
        // println!("Playpen{{ {}, {}, {:?}, {} }}", playpen.start_index, playpen.end_index, playpen.rust_file,
        // playpen.editable);
    }

    replaced.push_str(&s[previous_end_index..]);

    replaced
}

#[derive(PartialOrd, PartialEq, Debug)]
struct Playpen {
    start_index: usize,
    end_index: usize,
    rust_file: PathBuf,
    editable: bool,
    escaped: bool,
}

fn find_playpens(s: &str, base_path: &Path) -> Vec<Playpen> {
    let mut playpens = vec![];
    for (i, _) in s.match_indices("{{#playpen") {
        debug!("[*]: find_playpen");

        let mut escaped = false;

        if i > 0 {
            if let Some(c) = s[i - 1..].chars().nth(0) {
                if c == '\\' {
                    escaped = true
                }
            }
        }
        // DON'T forget the "+ i" else you have an index out of bounds error !!
        let end_i = if let Some(n) = s[i..].find("}}") {
            n
        } else {
            continue;
        } + i + 2;

        debug!("s[{}..{}] = {}", i, end_i, s[i..end_i].to_string());

        // If there is nothing between "{{#playpen" and "}}" skip
        if end_i - 2 - (i + 10) < 1 {
            continue;
        }
        if s[i + 10..end_i - 2].trim().is_empty() {
            continue;
        }

        debug!("{}", s[i + 10..end_i - 2].to_string());

        // Split on whitespaces
        let params: Vec<&str> = s[i + 10..end_i - 2].split_whitespace().collect();
        let editable = params
            .get(1)
            .map(|p| p.find("editable").is_some())
            .unwrap_or(false);

        playpens.push(Playpen {
            start_index: i,
            end_index: end_i,
            rust_file: base_path.join(PathBuf::from(params[0])),
            editable: editable,
            escaped: escaped,
        })
    }

    playpens
}

// ---------------------------------------------------------------------------------
//      Tests
//

#[test]
fn test_find_playpens_no_playpen() {
    let s = "Some random text without playpen...";
    assert!(find_playpens(s, Path::new("")) == vec![]);
}

#[test]
fn test_find_playpens_partial_playpen() {
    let s = "Some random text with {{#playpen...";
    assert!(find_playpens(s, Path::new("")) == vec![]);
}

#[test]
fn test_find_playpens_empty_playpen() {
    let s = "Some random text with {{#playpen}} and {{#playpen   }}...";
    assert!(find_playpens(s, Path::new("")) == vec![]);
}

#[test]
fn test_find_playpens_simple_playpen() {
    let s = "Some random text with {{#playpen file.rs}} and {{#playpen test.rs }}...";

    println!("\nOUTPUT: {:?}\n", find_playpens(s, Path::new("")));

    assert!(find_playpens(s, Path::new("")) ==
            vec![Playpen {
                     start_index: 22,
                     end_index: 42,
                     rust_file: PathBuf::from("file.rs"),
                     editable: false,
                     escaped: false,
                 },
                 Playpen {
                     start_index: 47,
                     end_index: 68,
                     rust_file: PathBuf::from("test.rs"),
                     editable: false,
                     escaped: false,
                 }]);
}

#[test]
fn test_find_playpens_complex_playpen() {
    let s = "Some random text with {{#playpen file.rs editable}} and {{#playpen test.rs editable }}...";

    println!("\nOUTPUT: {:?}\n", find_playpens(s, Path::new("dir")));

    assert!(find_playpens(s, Path::new("dir")) ==
            vec![Playpen {
                     start_index: 22,
                     end_index: 51,
                     rust_file: PathBuf::from("dir/file.rs"),
                     editable: true,
                     escaped: false,
                 },
                 Playpen {
                     start_index: 56,
                     end_index: 86,
                     rust_file: PathBuf::from("dir/test.rs"),
                     editable: true,
                     escaped: false,
                 }]);
}

#[test]
fn test_find_playpens_escaped_playpen() {
    let s = "Some random text with escaped playpen \\{{#playpen file.rs editable}} ...";

    println!("\nOUTPUT: {:?}\n", find_playpens(s, Path::new("")));

    assert!(find_playpens(s, Path::new("")) ==
            vec![
        Playpen{start_index: 39, end_index: 68, rust_file: PathBuf::from("file.rs"), editable: true, escaped: true},
    ]);
}
<|endoftext|>


<commit_before>//! Support for nested invocations of proc-macro-hack expression macros.
//!
//! By default, macros defined through proc-macro-hack do not support nested
//! invocations, i.e. the code emitted by a proc-macro-hack macro invocation
//! cannot contain recursive calls to the same proc-macro-hack macro nor calls
//! to any other proc-macro-hack macros.
//!
//! This crate provides opt-in support for such nested invocations.
//!
//! To make a macro callable recursively, add a dependency on this crate from
//! your declaration crate and update the `#[proc_macro_hack]` re-export as
//! follows.
//!
//! ```rust
//! // Before
//! # const IGNORE: &str = stringify! {
//! #[proc_macro_hack]
//! pub use demo_hack_impl::add_one;
//! # }
//! ```
//!
//! ```rust
//! // After
//! # const IGNORE: &str = stringify! {
//! extern crate proc_macro_nested;
//!
//! #[proc_macro_hack(support_nested)]
//! pub use demo_hack_impl::add_one;
//! # }
//! ```
//!
//! No change is required within your definition crate, only in the declaration
//! crate.

#![no_std]

include!(concat!(env!("OUT_DIR"), "/count.rs"));

#[doc(hidden)]
#[macro_export]
macro_rules! dispatch {
    (() $($bang:tt)*) => {
        $crate::count!($($bang)*)
    };
    ((($($first:tt)*) $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($first)* $($rest)*) $($bang)*)
    };
    (([$($first:tt)*] $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($first)* $($rest)*) $($bang)*)
    };
    (({$($first:tt)*} $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($first)* $($rest)*) $($bang)*)
    };
    ((! $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($rest)*) $($bang)* !)
    };
    (($first:tt $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($rest)*) $($bang)*)
    };
}
<commit_msg>Clarify what declaration crate means<commit_after>//! Support for nested invocations of proc-macro-hack expression macros.
//!
//! By default, macros defined through proc-macro-hack do not support nested
//! invocations, i.e. the code emitted by a proc-macro-hack macro invocation
//! cannot contain recursive calls to the same proc-macro-hack macro nor calls
//! to any other proc-macro-hack macros.
//!
//! This crate provides opt-in support for such nested invocations.
//!
//! To make a macro callable recursively, add a dependency on this crate from
//! your declaration crate and update the `#[proc_macro_hack]` re-export as
//! follows.
//!
//! ```rust
//! // Before
//! # const IGNORE: &str = stringify! {
//! #[proc_macro_hack]
//! pub use demo_hack_impl::add_one;
//! # }
//! ```
//!
//! ```rust
//! // After
//! # const IGNORE: &str = stringify! {
//! extern crate proc_macro_nested;
//!
//! #[proc_macro_hack(support_nested)]
//! pub use demo_hack_impl::add_one;
//! # }
//! ```
//!
//! No change is required within your definition crate, only to the re-export in
//! the declaration crate.

#![no_std]

include!(concat!(env!("OUT_DIR"), "/count.rs"));

#[doc(hidden)]
#[macro_export]
macro_rules! dispatch {
    (() $($bang:tt)*) => {
        $crate::count!($($bang)*)
    };
    ((($($first:tt)*) $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($first)* $($rest)*) $($bang)*)
    };
    (([$($first:tt)*] $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($first)* $($rest)*) $($bang)*)
    };
    (({$($first:tt)*} $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($first)* $($rest)*) $($bang)*)
    };
    ((! $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($rest)*) $($bang)* !)
    };
    (($first:tt $($rest:tt)*) $($bang:tt)*) => {
        $crate::dispatch!(($($rest)*) $($bang)*)
    };
}
<|endoftext|>