<commit_before>#![feature(const_fn)]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate serde;
extern crate serde_json;

use serde::Deserialize;
use std::fmt;
use std::io::{self, Read};
use std::convert;
use std::collections::HashMap;
use std::net::{
    TcpListener,
    TcpStream,
    SocketAddr,
};
use std::sync::{
    self,
    Mutex,
    Arc,
};
use std::sync::mpsc::{
    channel,
    Sender,
    TryRecvError,
};
use std::thread::{
    self,
    JoinHandle,
};

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Sender,
    Unimplemented,
}

impl convert::From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        match err {
            serde_json::Error::IoError(err) => Error::Io(err),
            err => Error::Json(err),
        }
    }
}

impl convert::From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl<T> convert::From<sync::mpsc::SendError<T>> for Error {
    fn from(_: sync::mpsc::SendError<T>) -> Error {
        Error::Sender
    }
}

pub type Result<T> = std::result::Result<T, Error>;

pub fn handle_conn<F, Request, Reply>(stream: TcpStream, f: F) -> Result<()>
    where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>
{
    let read_stream = try!(stream.try_clone());
    let mut de = serde_json::Deserializer::new(read_stream.bytes());
    let stream = Arc::new(Mutex::new(stream));
    loop {
        let request_packet: Packet<Request> = try!(Packet::deserialize(&mut de));
        match request_packet {
            Packet::Shutdown => {
                let stream = stream.clone();
                let mut my_stream = stream.lock().unwrap();
                try!(serde_json::to_writer(&mut *my_stream, &request_packet));
                break;
            },
            Packet::Message(id, message) => {
                let f = f.clone();
                let arc_stream = stream.clone();
                thread::spawn(move || {
                    let reply = f.serve(&message).unwrap();
                    let reply_packet = Packet::Message(id, reply);
                    let mut my_stream = arc_stream.lock().unwrap();
                    serde_json::to_writer(&mut *my_stream, &reply_packet).unwrap();
                });
            },
        }
    }
    Ok(())
}

pub struct Shutdown {
    tx: Sender<()>,
    join_handle: JoinHandle<()>,
    addr: SocketAddr,
}

impl Shutdown {
    pub fn wait(self) {
        self.join_handle.join().unwrap();
    }

    pub fn shutdown(self) {
        self.tx.send(()).expect(&line!().to_string());
        TcpStream::connect(&self.addr).unwrap();
        self.join_handle.join().expect(&line!().to_string());
    }
}

pub fn serve_async<F, Request, Reply>(addr: &SocketAddr, f: F) -> io::Result<Shutdown>
    where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>,
{
    let listener = try!(TcpListener::bind(addr));
    let (die_tx, die_rx) = channel();
    let join_handle = thread::spawn(move || {
        for conn in listener.incoming() {
            match die_rx.try_recv() {
                Ok(_) => break,
                Err(TryRecvError::Disconnected) => {
                    println!("serve: sender disconnected ");
                    break;
                },
                _ => (),
            }
            let conn = match conn {
                Err(err) => {
                    println!("I couldn't unwrap the connection :( {:?}", err);
                    return;
                },
                Ok(c) => c,
            };
            let f = f.clone();
            thread::spawn(move || {
                if let Err(err) = handle_conn(conn, f) {
                    println!("error handling connection: {:?}", err);
                }
            });
        }
    });
    Ok(Shutdown{
        tx: die_tx,
        join_handle: join_handle,
        addr: addr.clone(),
    })
}

pub trait Serve<Request, Reply>: Send + Sync {
    fn serve(&self, request: &Request) -> io::Result<Reply>;
}

impl<Request, Reply, S> Serve<Request, Reply> for Arc<S>
    where S: Serve<Request, Reply>
{
    fn serve(&self, request: &Request) -> io::Result<Reply> {
        S::serve(self, request)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum Packet<T> {
    Message(u64, T),
    Shutdown,
}

fn reader<Reply>(
    stream: TcpStream,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>)
    where Reply: serde::Deserialize
{
    let mut de = serde_json::Deserializer::new(stream.bytes());
    loop {
        match Packet::deserialize(&mut de) {
            Ok(Packet::Message(id, reply)) => {
                let mut requests = requests.lock().unwrap();
                let reply_tx = requests.remove(&id).unwrap();
                reply_tx.send(reply).unwrap();
            },
            Ok(Packet::Shutdown) => {
                break;
            }
            // TODO: This shutdown logic is janky.. What's the right way to do this?
            Err(err) => panic!("unexpected error while parsing!: {:?}", err),
        }
    }
}

fn increment(cur_id: &mut u64) -> u64 {
    let id = *cur_id;
    *cur_id += 1;
    id
}

struct SyncedClientState {
    next_id: u64,
    stream: TcpStream,
}

pub struct Client<Reply> {
    synced_state: Mutex<SyncedClientState>,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>,
    reader_guard: thread::JoinHandle<()>,
}

impl<Reply> Client<Reply>
    where Reply: serde::de::Deserialize + Send + 'static
{
    pub fn new(stream: TcpStream) -> Result<Self> {
        let requests = Arc::new(Mutex::new(HashMap::new()));
        let reader_stream = try!(stream.try_clone());
        let reader_requests = requests.clone();
        let reader_guard =
            thread::spawn(move || reader(reader_stream, reader_requests));
        Ok(Client{
            synced_state: Mutex::new(SyncedClientState{
                next_id: 0,
                stream: stream,
            }),
            requests: requests,
            reader_guard: reader_guard,
        })
    }

    pub fn rpc<Request>(&self, request: &Request) -> Result<Reply>
        where Request: serde::ser::Serialize + Clone + Send + 'static
    {
        let (tx, rx) = channel();
        let mut state = self.synced_state.lock().unwrap();
        let id = increment(&mut state.next_id);
        {
            let mut requests = self.requests.lock().unwrap();
            requests.insert(id, tx);
        }
        let packet = Packet::Message(id, request.clone());
        try!(serde_json::to_writer(&mut state.stream, &packet));
        drop(state);
        Ok(rx.recv().unwrap())
    }

    pub fn disconnect<Request: serde::Serialize>(self) -> Result<()> {
        {
            let mut state = self.synced_state.lock().unwrap();
            let packet: Packet<Request> = Packet::Shutdown;
            try!(serde_json::to_writer(&mut state.stream, &packet));
        }
        self.reader_guard.join().unwrap();
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use serde;
    use super::*;
    use std::fmt;
    use std::io;
    use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
    use std::sync::{Arc, Mutex, Barrier};
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    const PORT: AtomicUsize = AtomicUsize::new(10000);

    fn next_addr() -> SocketAddr {
        let addr = format!("127.0.0.1:{}", PORT.fetch_add(1, Ordering::SeqCst));
        addr.to_socket_addrs().unwrap().next().unwrap()
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
    enum Request {
        Increment
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Reply {
        Increment(u64)
    }

    struct Server {
        counter: Mutex<u64>,
    }

    impl Serve<Request, Reply> for Server {
        fn serve(&self, _: &Request) -> io::Result<Reply> {
            let mut counter = self.counter.lock().unwrap();
            let reply = Reply::Increment(*counter);
            *counter += 1;
            Ok(reply)
        }
    }

    impl Server {
        fn new() -> Server {
            Server{counter: Mutex::new(0)}
        }

        fn count(&self) -> u64 {
            *self.counter.lock().unwrap()
        }
    }

    fn wtf<F, Request, Reply>(server: F) -> (SocketAddr, Shutdown)
        where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
              Reply: 'static + fmt::Debug + Send + serde::ser::Serialize,
              F: 'static + Clone + Serve<Request, Reply>
    {
        let mut addr;
        let mut shutdown;
        while let &Err(_) = {shutdown = serve_async({addr = next_addr(); &addr}, server.clone()); &shutdown} { }
        (addr, shutdown.unwrap())
    }

    #[test]
    fn test_handle() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Client<Reply> = Client::new(client_stream).expect(&line!().to_string());
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }

    #[test]
    fn test() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client = Client::new(client_stream).unwrap();
        assert_eq!(Reply::Increment(0), client.rpc(&Request::Increment).unwrap());
        assert_eq!(1, server.count());
        assert_eq!(Reply::Increment(1), client.rpc(&Request::Increment).unwrap());
        assert_eq!(2, server.count());
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }

    struct BarrierServer {
        barrier: Barrier,
        inner: Server,
    }

    impl Serve<Request, Reply> for BarrierServer {
        fn serve(&self, request: &Request) -> io::Result<Reply> {
            self.barrier.wait();
            let reply = try!(self.inner.serve(request));
            Ok(reply)
        }
    }

    impl BarrierServer {
        fn new(n: usize) -> BarrierServer {
            BarrierServer{barrier: Barrier::new(n), inner: Server::new()}
        }

        fn count(&self) -> u64 {
            self.inner.count()
        }
    }

    #[test]
    fn test_concurrent() {
        let server = Arc::new(BarrierServer::new(10));
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Arc<Client<Reply>> = Arc::new(Client::new(client_stream).unwrap());
        let mut join_handles = vec![];
        for _ in 0..10 {
            let my_client = client.clone();
            join_handles.push(thread::spawn(move || my_client.rpc(&Request::Increment).unwrap()));
        }
        for handle in join_handles.into_iter() {
            handle.join().unwrap();
        }
        assert_eq!(10, server.count());
        let client = match Arc::try_unwrap(client) {
            Err(_) => panic!("couldn't unwrap arc"),
            Ok(c) => c,
        };
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }
}
<commit_msg>Make handle_conn be private<commit_after>#![feature(const_fn)]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate serde;
extern crate serde_json;

use serde::Deserialize;
use std::fmt;
use std::io::{self, Read};
use std::convert;
use std::collections::HashMap;
use std::net::{
    TcpListener,
    TcpStream,
    SocketAddr,
};
use std::sync::{
    self,
    Mutex,
    Arc,
};
use std::sync::mpsc::{
    channel,
    Sender,
    TryRecvError,
};
use std::thread::{
    self,
    JoinHandle,
};

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Sender,
    Unimplemented,
}

impl convert::From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Error {
        match err {
            serde_json::Error::IoError(err) => Error::Io(err),
            err => Error::Json(err),
        }
    }
}

impl convert::From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl<T> convert::From<sync::mpsc::SendError<T>> for Error {
    fn from(_: sync::mpsc::SendError<T>) -> Error {
        Error::Sender
    }
}

pub type Result<T> = std::result::Result<T, Error>;

fn handle_conn<F, Request, Reply>(stream: TcpStream, f: F) -> Result<()>
    where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>
{
    let read_stream = try!(stream.try_clone());
    let mut de = serde_json::Deserializer::new(read_stream.bytes());
    let stream = Arc::new(Mutex::new(stream));
    loop {
        let request_packet: Packet<Request> = try!(Packet::deserialize(&mut de));
        match request_packet {
            Packet::Shutdown => {
                let stream = stream.clone();
                let mut my_stream = stream.lock().unwrap();
                try!(serde_json::to_writer(&mut *my_stream, &request_packet));
                break;
            },
            Packet::Message(id, message) => {
                let f = f.clone();
                let arc_stream = stream.clone();
                thread::spawn(move || {
                    let reply = f.serve(&message).unwrap();
                    let reply_packet = Packet::Message(id, reply);
                    let mut my_stream = arc_stream.lock().unwrap();
                    serde_json::to_writer(&mut *my_stream, &reply_packet).unwrap();
                });
            },
        }
    }
    Ok(())
}

pub struct Shutdown {
    tx: Sender<()>,
    join_handle: JoinHandle<()>,
    addr: SocketAddr,
}

impl Shutdown {
    pub fn wait(self) {
        self.join_handle.join().unwrap();
    }

    pub fn shutdown(self) {
        self.tx.send(()).expect(&line!().to_string());
        TcpStream::connect(&self.addr).unwrap();
        self.join_handle.join().expect(&line!().to_string());
    }
}

pub fn serve_async<F, Request, Reply>(addr: &SocketAddr, f: F) -> io::Result<Shutdown>
    where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
          Reply: 'static + fmt::Debug + serde::ser::Serialize,
          F: 'static + Clone + Serve<Request, Reply>,
{
    let listener = try!(TcpListener::bind(addr));
    let (die_tx, die_rx) = channel();
    let join_handle = thread::spawn(move || {
        for conn in listener.incoming() {
            match die_rx.try_recv() {
                Ok(_) => break,
                Err(TryRecvError::Disconnected) => {
                    println!("serve: sender disconnected ");
                    break;
                },
                _ => (),
            }
            let conn = match conn {
                Err(err) => {
                    println!("I couldn't unwrap the connection :( {:?}", err);
                    return;
                },
                Ok(c) => c,
            };
            let f = f.clone();
            thread::spawn(move || {
                if let Err(err) = handle_conn(conn, f) {
                    println!("error handling connection: {:?}", err);
                }
            });
        }
    });
    Ok(Shutdown{
        tx: die_tx,
        join_handle: join_handle,
        addr: addr.clone(),
    })
}

pub trait Serve<Request, Reply>: Send + Sync {
    fn serve(&self, request: &Request) -> io::Result<Reply>;
}

impl<Request, Reply, S> Serve<Request, Reply> for Arc<S>
    where S: Serve<Request, Reply>
{
    fn serve(&self, request: &Request) -> io::Result<Reply> {
        S::serve(self, request)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum Packet<T> {
    Message(u64, T),
    Shutdown,
}

fn reader<Reply>(
    stream: TcpStream,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>)
    where Reply: serde::Deserialize
{
    let mut de = serde_json::Deserializer::new(stream.bytes());
    loop {
        match Packet::deserialize(&mut de) {
            Ok(Packet::Message(id, reply)) => {
                let mut requests = requests.lock().unwrap();
                let reply_tx = requests.remove(&id).unwrap();
                reply_tx.send(reply).unwrap();
            },
            Ok(Packet::Shutdown) => {
                break;
            }
            // TODO: This shutdown logic is janky.. What's the right way to do this?
            Err(err) => panic!("unexpected error while parsing!: {:?}", err),
        }
    }
}

fn increment(cur_id: &mut u64) -> u64 {
    let id = *cur_id;
    *cur_id += 1;
    id
}

struct SyncedClientState {
    next_id: u64,
    stream: TcpStream,
}

pub struct Client<Reply> {
    synced_state: Mutex<SyncedClientState>,
    requests: Arc<Mutex<HashMap<u64, Sender<Reply>>>>,
    reader_guard: thread::JoinHandle<()>,
}

impl<Reply> Client<Reply>
    where Reply: serde::de::Deserialize + Send + 'static
{
    pub fn new(stream: TcpStream) -> Result<Self> {
        let requests = Arc::new(Mutex::new(HashMap::new()));
        let reader_stream = try!(stream.try_clone());
        let reader_requests = requests.clone();
        let reader_guard =
            thread::spawn(move || reader(reader_stream, reader_requests));
        Ok(Client{
            synced_state: Mutex::new(SyncedClientState{
                next_id: 0,
                stream: stream,
            }),
            requests: requests,
            reader_guard: reader_guard,
        })
    }

    pub fn rpc<Request>(&self, request: &Request) -> Result<Reply>
        where Request: serde::ser::Serialize + Clone + Send + 'static
    {
        let (tx, rx) = channel();
        let mut state = self.synced_state.lock().unwrap();
        let id = increment(&mut state.next_id);
        {
            let mut requests = self.requests.lock().unwrap();
            requests.insert(id, tx);
        }
        let packet = Packet::Message(id, request.clone());
        try!(serde_json::to_writer(&mut state.stream, &packet));
        drop(state);
        Ok(rx.recv().unwrap())
    }

    pub fn disconnect<Request: serde::Serialize>(self) -> Result<()> {
        {
            let mut state = self.synced_state.lock().unwrap();
            let packet: Packet<Request> = Packet::Shutdown;
            try!(serde_json::to_writer(&mut state.stream, &packet));
        }
        self.reader_guard.join().unwrap();
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use serde;
    use super::*;
    use std::fmt;
    use std::io;
    use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
    use std::sync::{Arc, Mutex, Barrier};
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    const PORT: AtomicUsize = AtomicUsize::new(10000);

    fn next_addr() -> SocketAddr {
        let addr = format!("127.0.0.1:{}", PORT.fetch_add(1, Ordering::SeqCst));
        addr.to_socket_addrs().unwrap().next().unwrap()
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
    enum Request {
        Increment
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Reply {
        Increment(u64)
    }

    struct Server {
        counter: Mutex<u64>,
    }

    impl Serve<Request, Reply> for Server {
        fn serve(&self, _: &Request) -> io::Result<Reply> {
            let mut counter = self.counter.lock().unwrap();
            let reply = Reply::Increment(*counter);
            *counter += 1;
            Ok(reply)
        }
    }

    impl Server {
        fn new() -> Server {
            Server{counter: Mutex::new(0)}
        }

        fn count(&self) -> u64 {
            *self.counter.lock().unwrap()
        }
    }

    fn wtf<F, Request, Reply>(server: F) -> (SocketAddr, Shutdown)
        where Request: 'static + fmt::Debug + Send + serde::de::Deserialize + fmt::Debug + serde::ser::Serialize,
              Reply: 'static + fmt::Debug + Send + serde::ser::Serialize,
              F: 'static + Clone + Serve<Request, Reply>
    {
        let mut addr;
        let mut shutdown;
        while let &Err(_) = {shutdown = serve_async({addr = next_addr(); &addr}, server.clone()); &shutdown} { }
        (addr, shutdown.unwrap())
    }

    #[test]
    fn test_handle() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Client<Reply> = Client::new(client_stream).expect(&line!().to_string());
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }

    #[test]
    fn test() {
        let server = Arc::new(Server::new());
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client = Client::new(client_stream).unwrap();
        assert_eq!(Reply::Increment(0), client.rpc(&Request::Increment).unwrap());
        assert_eq!(1, server.count());
        assert_eq!(Reply::Increment(1), client.rpc(&Request::Increment).unwrap());
        assert_eq!(2, server.count());
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }

    struct BarrierServer {
        barrier: Barrier,
        inner: Server,
    }

    impl Serve<Request, Reply> for BarrierServer {
        fn serve(&self, request: &Request) -> io::Result<Reply> {
            self.barrier.wait();
            let reply = try!(self.inner.serve(request));
            Ok(reply)
        }
    }

    impl BarrierServer {
        fn new(n: usize) -> BarrierServer {
            BarrierServer{barrier: Barrier::new(n), inner: Server::new()}
        }

        fn count(&self) -> u64 {
            self.inner.count()
        }
    }

    #[test]
    fn test_concurrent() {
        let server = Arc::new(BarrierServer::new(10));
        let (addr, shutdown) = wtf(server.clone());
        let client_stream = TcpStream::connect(&addr).unwrap();
        let client: Arc<Client<Reply>> = Arc::new(Client::new(client_stream).unwrap());
        let mut join_handles = vec![];
        for _ in 0..10 {
            let my_client = client.clone();
            join_handles.push(thread::spawn(move || my_client.rpc(&Request::Increment).unwrap()));
        }
        for handle in join_handles.into_iter() {
            handle.join().unwrap();
        }
        assert_eq!(10, server.count());
        let client = match Arc::try_unwrap(client) {
            Err(_) => panic!("couldn't unwrap arc"),
            Ok(c) => c,
        };
        client.disconnect::<Request>().unwrap();
        shutdown.shutdown();
    }
}
<|endoftext|>


<commit_before>//! Winit allows you to build a window on as many platforms as possible.
//!
//! # Building a window
//!
//! Before you can build a window, you first need to build an `EventsLoop`. This is done with the
//! `EventsLoop::new()` function. Example:
//!
//! ```no_run
//! use winit::EventsLoop;
//! let events_loop = EventsLoop::new();
//! ```
//!
//! Once this is done there are two ways to create a window:
//!
//!  - Calling `Window::new(&events_loop)`.
//!  - Calling `let builder = WindowBuilder::new()` then `builder.build(&events_loop)`.
//!
//! The first way is the simpliest way and will give you default values for everything.
//!
//! The second way allows you to customize the way your window will look and behave by modifying
//! the fields of the `WindowBuilder` object before you create the window.
//!
//! # Events handling
//!
//! Once a window has been created, it will *generate events*. For example whenever the user moves
//! the window, resizes the window, moves the mouse, etc. an event is generated.
//!
//! The events generated by a window can be retreived from the `EventsLoop` the window was created
//! with.
//!
//! There are two ways to do so. The first is to call `events_loop.poll_events(...)`, which will
//! retreive all the events pending on the windows and immediately return after no new event is
//! available. You usually want to use this method in application that render continuously on the
//! screen, such as video games.
//!
//! ```no_run
//! use winit::{Event, WindowEvent};
//! # use winit::EventsLoop;
//! # let mut events_loop = EventsLoop::new();
//!
//! loop {
//!     events_loop.poll_events(|event| {
//!         match event {
//!             Event::WindowEvent { event: WindowEvent::Resized(w, h), .. } => {
//!                 println!("The window was resized to {}x{}", w, h);
//!             },
//!             _ => ()
//!         }
//!     });
//! }
//! ```
//!
//! The second way is to call `events_loop.run_forever(...)`. As its name tells, it will run
//! forever unless it is stopped by returning `ControlFlow::Break`.
//!
//! ```no_run
//! use winit::{ControlFlow, Event, WindowEvent};
//! # use winit::EventsLoop;
//! # let mut events_loop = EventsLoop::new();
//!
//! events_loop.run_forever(|event| {
//!     match event {
//!         Event::WindowEvent { event: WindowEvent::Closed, .. } => {
//!             println!("The window was closed ; stopping");
//!             ControlFlow::Break
//!         },
//!         _ => ControlFlow::Continue,
//!     }
//! });
//! ```
//!
//! If you use multiple windows, the `WindowEvent` event has a member named `window_id`. You can
//! compare it with the value returned by the `id()` method of `Window` in order to know which
//! window has received the event.
//!
//! # Drawing on the window
//!
//! Winit doesn't provide any function that allows drawing on a window. However it allows you to
//! retreive the raw handle of the window (see the `os` module for that), which in turn allows you
//! to create an OpenGL/Vulkan/DirectX/Metal/etc. context that will draw on the window.
//!

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate shared_library;

extern crate libc;

#[cfg(target_os = "windows")]
extern crate winapi;
#[cfg(target_os = "windows")]
extern crate kernel32;
#[cfg(target_os = "windows")]
extern crate shell32;
#[cfg(target_os = "windows")]
extern crate gdi32;
#[cfg(target_os = "windows")]
extern crate user32;
#[cfg(target_os = "windows")]
extern crate dwmapi;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[macro_use]
extern crate objc;
#[cfg(target_os = "macos")]
extern crate cocoa;
#[cfg(target_os = "macos")]
extern crate core_foundation;
#[cfg(target_os = "macos")]
extern crate core_graphics;
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
extern crate x11_dl;
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
#[macro_use]
extern crate wayland_client;

pub use events::*;
pub use window::{AvailableMonitorsIter, MonitorId, get_available_monitors, get_primary_monitor};
pub use native_monitor::NativeMonitorId;

#[macro_use]
mod api_transition;

mod platform;
mod events;
mod window;

pub mod os;

/// Represents a window.
///
/// # Example
///
/// ```no_run
/// use winit::{Event, EventsLoop, Window, WindowEvent, ControlFlow};
///
/// let mut events_loop = EventsLoop::new();
/// let window = Window::new(&events_loop).unwrap();
///
/// events_loop.run_forever(|event| {
///     match event {
///         Event::WindowEvent { event: WindowEvent::Closed, .. } => {
///             ControlFlow::Break
///         },
///         _ => ControlFlow::Continue,
///     }
/// });
/// ```
pub struct Window {
    window: platform::Window2,
}

/// Identifier of a window. Unique for each window.
///
/// Can be obtained with `window.id()`.
///
/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
/// can then compare to the ids of your windows.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowId(platform::WindowId);

/// Identifier of an input device.
///
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceId(platform::DeviceId);

/// Provides a way to retreive events from the windows that were registered to it.
///
/// To wake up an `EventsLoop` from a another thread, see the `EventsLoopProxy` docs.
///
/// Usage will result in display backend initialisation, this can be controlled on linux
/// using an environment variable `WINIT_UNIX_BACKEND`.
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
/// > and if it fails will fallback on x11.
/// >
/// > If this variable is set with any other value, winit will panic.
pub struct EventsLoop {
    events_loop: platform::EventsLoop,
}

/// Returned by the user callback given to the `EventsLoop::run_forever` method.
///
/// Indicates whether the `run_forever` method should continue or complete.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ControlFlow {
    /// Continue looping and waiting for events.
    Continue,
    /// Break from the event loop.
    Break,
}

impl EventsLoop {
    /// Builds a new events loop.
    pub fn new() -> EventsLoop {
        EventsLoop {
            events_loop: platform::EventsLoop::new(),
        }
    }

    /// Fetches all the events that are pending, calls the callback function for each of them,
    /// and returns.
    #[inline]
    pub fn poll_events<F>(&mut self, callback: F)
        where F: FnMut(Event)
    {
        self.events_loop.poll_events(callback)
    }

    /// Runs forever until `interrupt()` is called. Whenever an event happens, calls the callback.
    #[inline]
    pub fn run_forever<F>(&mut self, callback: F)
        where F: FnMut(Event) -> ControlFlow
    {
        self.events_loop.run_forever(callback)
    }

    /// Creates an `EventsLoopProxy` that can be used to wake up the `EventsLoop` from another
    /// thread.
    pub fn create_proxy(&self) -> EventsLoopProxy {
        EventsLoopProxy {
            events_loop_proxy: self.events_loop.create_proxy(),
        }
    }
}

/// Used to wake up the `EventsLoop` from another thread.
pub struct EventsLoopProxy {
    events_loop_proxy: platform::EventsLoopProxy,
}

impl EventsLoopProxy {
    /// Wake up the `EventsLoop` from which this proxy was created.
    ///
    /// This causes the `EventsLoop` to emit an `Awakened` event.
    ///
    /// Returns an `Err` if the associated `EventsLoop` no longer exists.
    pub fn wakeup(&self) -> Result<(), EventsLoopClosed> {
        self.events_loop_proxy.wakeup()
    }
}

/// The error that is returned when an `EventsLoopProxy` attempts to wake up an `EventsLoop` that
/// no longer exists.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct EventsLoopClosed;

impl std::fmt::Display for EventsLoopClosed {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", std::error::Error::description(self))
    }
}

impl std::error::Error for EventsLoopClosed {
    fn description(&self) -> &str {
        "Tried to wake up a closed `EventsLoop`"
    }
}

/// Object that allows you to build windows.
#[derive(Clone)]
pub struct WindowBuilder {
    /// The attributes to use to create the window.
    pub window: WindowAttributes,

    // Platform-specific configuration. Private.
    platform_specific: platform::PlatformSpecificWindowBuilderAttributes,
}

/// Error that can happen while creating a window or a headless renderer.
#[derive(Debug)]
pub enum CreationError {
    OsError(String),
    /// TODO: remove this error
    NotSupported,
}

impl CreationError {
    fn to_string(&self) -> &str {
        match *self {
            CreationError::OsError(ref text) => &text,
            CreationError::NotSupported => "Some of the requested attributes are not supported",
        }
    }
}

impl std::fmt::Display for CreationError {
    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        formatter.write_str(self.to_string())
    }
}

impl std::error::Error for CreationError {
    fn description(&self) -> &str {
        self.to_string()
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum MouseCursor {
    /// The platform-dependent default cursor.
    Default,
    /// A simple crosshair.
    Crosshair,
    /// A hand (often used to indicate links in web browsers).
    Hand,
    /// Self explanatory.
    Arrow,
    /// Indicates something is to be moved.
    Move,
    /// Indicates text that may be selected or edited.
    Text,
    /// Program busy indicator.
    Wait,
    /// Help indicator (often rendered as a "?")
    Help,
    /// Progress indicator. Shows that processing is being done. But in contrast
    /// with "Wait" the user may still interact with the program. Often rendered
    /// as a spinning beach ball, or an arrow with a watch or hourglass.
    Progress,

    /// Cursor showing that something cannot be done.
    NotAllowed,
    ContextMenu,
    NoneCursor,
    Cell,
    VerticalText,
    Alias,
    Copy,
    NoDrop,
    Grab,
    Grabbing,
    AllScroll,
    ZoomIn,
    ZoomOut,

    /// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
    /// is used when the movement starts from the south-east corner of the box.
    EResize,
    NResize,
    NeResize,
    NwResize,
    SResize,
    SeResize,
    SwResize,
    WResize,
    EwResize,
    NsResize,
    NeswResize,
    NwseResize,
    ColResize,
    RowResize,
}

/// Describes how winit handles the cursor.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum CursorState {
    /// Normal cursor behavior.
    Normal,

    /// The cursor will be invisible when over the window.
    Hide,

    /// Grabs the mouse cursor. The cursor's motion will be confined to this
    /// window and the window has exclusive access to further events regarding
    /// the cursor.
    ///
    /// This is useful for first-person cameras for example.
    Grab,
}

/// Attributes to use when creating a window.
#[derive(Clone)]
pub struct WindowAttributes {
    /// The dimensions of the window. If this is `None`, some platform-specific dimensions will be
    /// used.
    ///
    /// The default is `None`.
    pub dimensions: Option<(u32, u32)>,

    /// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
    ///
    /// The default is `None`.
    pub min_dimensions: Option<(u32, u32)>,

    /// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
    ///
    /// The default is `None`.
    pub max_dimensions: Option<(u32, u32)>,

    /// If `Some`, the window will be in fullscreen mode with the given monitor.
    ///
    /// The default is `None`.
    pub monitor: Option<platform::MonitorId>,

    /// The title of the window in the title bar.
    ///
    /// The default is `"winit window"`.
    pub title: String,

    /// Whether the window should be immediately visible upon creation.
    ///
    /// The default is `true`.
    pub visible: bool,

    /// Whether the the window should be transparent. If this is true, writing colors
    /// with alpha values different than `1.0` will produce a transparent window.
    ///
    /// The default is `false`.
    pub transparent: bool,

    /// Whether the window should have borders and bars.
    ///
    /// The default is `true`.
    pub decorations: bool,

    /// [iOS only] Enable multitouch, see [UIView#multipleTouchEnabled]
    /// (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instp/UIView/multipleTouchEnabled)
    pub multitouch: bool,
}

impl Default for WindowAttributes {
    #[inline]
    fn default() -> WindowAttributes {
        WindowAttributes {
            dimensions: None,
            min_dimensions: None,
            max_dimensions: None,
            monitor: None,
            title: "winit window".to_owned(),
            visible: true,
            transparent: false,
            decorations: true,
            multitouch: false,
        }
    }
}

mod native_monitor {
    /// Native platform identifier for a monitor. Different platforms use fundamentally different types
    /// to represent a monitor ID.
    #[derive(Clone, PartialEq, Eq)]
    pub enum NativeMonitorId {
        /// Cocoa and X11 use a numeric identifier to represent a monitor.
        Numeric(u32),

        /// Win32 uses a Unicode string to represent a monitor.
        Name(String),

        /// Other platforms (Android) don't support monitor identification.
        Unavailable
    }
}
<commit_msg>Derive Clone for CreationError<commit_after>//! Winit allows you to build a window on as many platforms as possible.
//!
//! # Building a window
//!
//! Before you can build a window, you first need to build an `EventsLoop`. This is done with the
//! `EventsLoop::new()` function. Example:
//!
//! ```no_run
//! use winit::EventsLoop;
//! let events_loop = EventsLoop::new();
//! ```
//!
//! Once this is done there are two ways to create a window:
//!
//!  - Calling `Window::new(&events_loop)`.
//!  - Calling `let builder = WindowBuilder::new()` then `builder.build(&events_loop)`.
//!
//! The first way is the simpliest way and will give you default values for everything.
//!
//! The second way allows you to customize the way your window will look and behave by modifying
//! the fields of the `WindowBuilder` object before you create the window.
//!
//! # Events handling
//!
//! Once a window has been created, it will *generate events*. For example whenever the user moves
//! the window, resizes the window, moves the mouse, etc. an event is generated.
//!
//! The events generated by a window can be retreived from the `EventsLoop` the window was created
//! with.
//!
//! There are two ways to do so. The first is to call `events_loop.poll_events(...)`, which will
//! retreive all the events pending on the windows and immediately return after no new event is
//! available. You usually want to use this method in application that render continuously on the
//! screen, such as video games.
//!
//! ```no_run
//! use winit::{Event, WindowEvent};
//! # use winit::EventsLoop;
//! # let mut events_loop = EventsLoop::new();
//!
//! loop {
//!     events_loop.poll_events(|event| {
//!         match event {
//!             Event::WindowEvent { event: WindowEvent::Resized(w, h), .. } => {
//!                 println!("The window was resized to {}x{}", w, h);
//!             },
//!             _ => ()
//!         }
//!     });
//! }
//! ```
//!
//! The second way is to call `events_loop.run_forever(...)`. As its name tells, it will run
//! forever unless it is stopped by returning `ControlFlow::Break`.
//!
//! ```no_run
//! use winit::{ControlFlow, Event, WindowEvent};
//! # use winit::EventsLoop;
//! # let mut events_loop = EventsLoop::new();
//!
//! events_loop.run_forever(|event| {
//!     match event {
//!         Event::WindowEvent { event: WindowEvent::Closed, .. } => {
//!             println!("The window was closed ; stopping");
//!             ControlFlow::Break
//!         },
//!         _ => ControlFlow::Continue,
//!     }
//! });
//! ```
//!
//! If you use multiple windows, the `WindowEvent` event has a member named `window_id`. You can
//! compare it with the value returned by the `id()` method of `Window` in order to know which
//! window has received the event.
//!
//! # Drawing on the window
//!
//! Winit doesn't provide any function that allows drawing on a window. However it allows you to
//! retreive the raw handle of the window (see the `os` module for that), which in turn allows you
//! to create an OpenGL/Vulkan/DirectX/Metal/etc. context that will draw on the window.
//!

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate shared_library;

extern crate libc;

#[cfg(target_os = "windows")]
extern crate winapi;
#[cfg(target_os = "windows")]
extern crate kernel32;
#[cfg(target_os = "windows")]
extern crate shell32;
#[cfg(target_os = "windows")]
extern crate gdi32;
#[cfg(target_os = "windows")]
extern crate user32;
#[cfg(target_os = "windows")]
extern crate dwmapi;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[macro_use]
extern crate objc;
#[cfg(target_os = "macos")]
extern crate cocoa;
#[cfg(target_os = "macos")]
extern crate core_foundation;
#[cfg(target_os = "macos")]
extern crate core_graphics;
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
extern crate x11_dl;
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
#[macro_use]
extern crate wayland_client;

pub use events::*;
pub use window::{AvailableMonitorsIter, MonitorId, get_available_monitors, get_primary_monitor};
pub use native_monitor::NativeMonitorId;

#[macro_use]
mod api_transition;

mod platform;
mod events;
mod window;

pub mod os;

/// Represents a window.
///
/// # Example
///
/// ```no_run
/// use winit::{Event, EventsLoop, Window, WindowEvent, ControlFlow};
///
/// let mut events_loop = EventsLoop::new();
/// let window = Window::new(&events_loop).unwrap();
///
/// events_loop.run_forever(|event| {
///     match event {
///         Event::WindowEvent { event: WindowEvent::Closed, .. } => {
///             ControlFlow::Break
///         },
///         _ => ControlFlow::Continue,
///     }
/// });
/// ```
pub struct Window {
    window: platform::Window2,
}

/// Identifier of a window. Unique for each window.
///
/// Can be obtained with `window.id()`.
///
/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
/// can then compare to the ids of your windows.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowId(platform::WindowId);

/// Identifier of an input device.
///
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceId(platform::DeviceId);

/// Provides a way to retreive events from the windows that were registered to it.
///
/// To wake up an `EventsLoop` from a another thread, see the `EventsLoopProxy` docs.
///
/// Usage will result in display backend initialisation, this can be controlled on linux
/// using an environment variable `WINIT_UNIX_BACKEND`.
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
/// > and if it fails will fallback on x11.
/// >
/// > If this variable is set with any other value, winit will panic.
pub struct EventsLoop {
    events_loop: platform::EventsLoop,
}

/// Returned by the user callback given to the `EventsLoop::run_forever` method.
///
/// Indicates whether the `run_forever` method should continue or complete.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ControlFlow {
    /// Continue looping and waiting for events.
    Continue,
    /// Break from the event loop.
    Break,
}

impl EventsLoop {
    /// Builds a new events loop.
    pub fn new() -> EventsLoop {
        EventsLoop {
            events_loop: platform::EventsLoop::new(),
        }
    }

    /// Fetches all the events that are pending, calls the callback function for each of them,
    /// and returns.
    #[inline]
    pub fn poll_events<F>(&mut self, callback: F)
        where F: FnMut(Event)
    {
        self.events_loop.poll_events(callback)
    }

    /// Runs forever until `interrupt()` is called. Whenever an event happens, calls the callback.
    #[inline]
    pub fn run_forever<F>(&mut self, callback: F)
        where F: FnMut(Event) -> ControlFlow
    {
        self.events_loop.run_forever(callback)
    }

    /// Creates an `EventsLoopProxy` that can be used to wake up the `EventsLoop` from another
    /// thread.
    pub fn create_proxy(&self) -> EventsLoopProxy {
        EventsLoopProxy {
            events_loop_proxy: self.events_loop.create_proxy(),
        }
    }
}

/// Used to wake up the `EventsLoop` from another thread.
pub struct EventsLoopProxy {
    events_loop_proxy: platform::EventsLoopProxy,
}

impl EventsLoopProxy {
    /// Wake up the `EventsLoop` from which this proxy was created.
    ///
    /// This causes the `EventsLoop` to emit an `Awakened` event.
    ///
    /// Returns an `Err` if the associated `EventsLoop` no longer exists.
    pub fn wakeup(&self) -> Result<(), EventsLoopClosed> {
        self.events_loop_proxy.wakeup()
    }
}

/// The error that is returned when an `EventsLoopProxy` attempts to wake up an `EventsLoop` that
/// no longer exists.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct EventsLoopClosed;

impl std::fmt::Display for EventsLoopClosed {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", std::error::Error::description(self))
    }
}

impl std::error::Error for EventsLoopClosed {
    fn description(&self) -> &str {
        "Tried to wake up a closed `EventsLoop`"
    }
}

/// Object that allows you to build windows.
#[derive(Clone)]
pub struct WindowBuilder {
    /// The attributes to use to create the window.
    pub window: WindowAttributes,

    // Platform-specific configuration. Private.
    platform_specific: platform::PlatformSpecificWindowBuilderAttributes,
}

/// Error that can happen while creating a window or a headless renderer.
#[derive(Debug, Clone)]
pub enum CreationError {
    OsError(String),
    /// TODO: remove this error
    NotSupported,
}

impl CreationError {
    fn to_string(&self) -> &str {
        match *self {
            CreationError::OsError(ref text) => &text,
            CreationError::NotSupported => "Some of the requested attributes are not supported",
        }
    }
}

impl std::fmt::Display for CreationError {
    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        formatter.write_str(self.to_string())
    }
}

impl std::error::Error for CreationError {
    fn description(&self) -> &str {
        self.to_string()
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum MouseCursor {
    /// The platform-dependent default cursor.
    Default,
    /// A simple crosshair.
    Crosshair,
    /// A hand (often used to indicate links in web browsers).
    Hand,
    /// Self explanatory.
    Arrow,
    /// Indicates something is to be moved.
    Move,
    /// Indicates text that may be selected or edited.
    Text,
    /// Program busy indicator.
    Wait,
    /// Help indicator (often rendered as a "?")
    Help,
    /// Progress indicator. Shows that processing is being done. But in contrast
    /// with "Wait" the user may still interact with the program. Often rendered
    /// as a spinning beach ball, or an arrow with a watch or hourglass.
    Progress,

    /// Cursor showing that something cannot be done.
    NotAllowed,
    ContextMenu,
    NoneCursor,
    Cell,
    VerticalText,
    Alias,
    Copy,
    NoDrop,
    Grab,
    Grabbing,
    AllScroll,
    ZoomIn,
    ZoomOut,

    /// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
    /// is used when the movement starts from the south-east corner of the box.
    EResize,
    NResize,
    NeResize,
    NwResize,
    SResize,
    SeResize,
    SwResize,
    WResize,
    EwResize,
    NsResize,
    NeswResize,
    NwseResize,
    ColResize,
    RowResize,
}

/// Describes how winit handles the cursor.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum CursorState {
    /// Normal cursor behavior.
    Normal,

    /// The cursor will be invisible when over the window.
    Hide,

    /// Grabs the mouse cursor. The cursor's motion will be confined to this
    /// window and the window has exclusive access to further events regarding
    /// the cursor.
    ///
    /// This is useful for first-person cameras for example.
    Grab,
}

/// Attributes to use when creating a window.
#[derive(Clone)]
pub struct WindowAttributes {
    /// The dimensions of the window. If this is `None`, some platform-specific dimensions will be
    /// used.
    ///
    /// The default is `None`.
    pub dimensions: Option<(u32, u32)>,

    /// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
    ///
    /// The default is `None`.
    pub min_dimensions: Option<(u32, u32)>,

    /// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
    ///
    /// The default is `None`.
    pub max_dimensions: Option<(u32, u32)>,

    /// If `Some`, the window will be in fullscreen mode with the given monitor.
    ///
    /// The default is `None`.
    pub monitor: Option<platform::MonitorId>,

    /// The title of the window in the title bar.
    ///
    /// The default is `"winit window"`.
    pub title: String,

    /// Whether the window should be immediately visible upon creation.
    ///
    /// The default is `true`.
    pub visible: bool,

    /// Whether the the window should be transparent. If this is true, writing colors
    /// with alpha values different than `1.0` will produce a transparent window.
    ///
    /// The default is `false`.
    pub transparent: bool,

    /// Whether the window should have borders and bars.
    ///
    /// The default is `true`.
    pub decorations: bool,

    /// [iOS only] Enable multitouch, see [UIView#multipleTouchEnabled]
    /// (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instp/UIView/multipleTouchEnabled)
    pub multitouch: bool,
}

impl Default for WindowAttributes {
    #[inline]
    fn default() -> WindowAttributes {
        WindowAttributes {
            dimensions: None,
            min_dimensions: None,
            max_dimensions: None,
            monitor: None,
            title: "winit window".to_owned(),
            visible: true,
            transparent: false,
            decorations: true,
            multitouch: false,
        }
    }
}

mod native_monitor {
    /// Native platform identifier for a monitor. Different platforms use fundamentally different types
    /// to represent a monitor ID.
    #[derive(Clone, PartialEq, Eq)]
    pub enum NativeMonitorId {
        /// Cocoa and X11 use a numeric identifier to represent a monitor.
        Numeric(u32),

        /// Win32 uses a Unicode string to represent a monitor.
        Name(String),

        /// Other platforms (Android) don't support monitor identification.
        Unavailable
    }
}
<|endoftext|>


<commit_before>//! The FFI bindings.
//!
//! See the [C API docs](http://emcrisostomo.github.io/fswatch/doc/1.9.3/libfswatch.html/libfswatch_8h.html).

#![allow(non_camel_case_types)]

extern crate libc;

use libc::{c_int, c_uint, c_void, c_double, c_char, time_t};

#[link(name = "fswatch")]
extern "C" {
  pub fn fsw_init_library() -> FSW_STATUS;

  pub fn fsw_init_session(monitor_type: FswMonitorType) -> FSW_HANDLE;

  pub fn fsw_add_path(handle: FSW_HANDLE, path: *const c_char) -> FSW_STATUS;

  pub fn fsw_add_property(handle: FSW_HANDLE, name: *const c_char, value: *const c_char) -> FSW_STATUS;

  pub fn fsw_set_allow_overflow(handle: FSW_HANDLE, allow_overflow: bool) -> FSW_STATUS;

  pub fn fsw_set_callback(handle: FSW_HANDLE, callback: FSW_CEVENT_CALLBACK, data: *const c_void) -> FSW_STATUS;

  pub fn fsw_set_latency(handle: FSW_HANDLE, latency: c_double) -> FSW_STATUS;

  pub fn fsw_set_recursive(handle: FSW_HANDLE, recursive: bool) -> FSW_STATUS;

  pub fn fsw_set_directory_only(handle: FSW_HANDLE, directory_only: bool) -> FSW_STATUS;

  pub fn fsw_set_follow_symlinks(handle: FSW_HANDLE, follow_symlinks: bool) -> FSW_STATUS;

  pub fn fsw_add_event_type_filter(handle: FSW_HANDLE, event_type: fsw_event_type_filter) -> FSW_STATUS;

  pub fn fsw_add_filter(handle: FSW_HANDLE, filter: fsw_cmonitor_filter) -> FSW_STATUS;

  pub fn fsw_start_monitor(handle: FSW_HANDLE) -> FSW_STATUS;

  pub fn fsw_destroy_session(handle: FSW_HANDLE) -> FSW_STATUS;

  pub fn fsw_last_error() -> FSW_STATUS;

  pub fn fsw_is_verbose() -> bool;

  pub fn fsw_set_verbose(verbose: bool);
}

pub type FSW_STATUS = c_int;
// type FSW_HANDLE = c_uint;
// Fun story here. FSW_HANDLE is defined as an unsigned int, but it can return a signed int,
// FSW_INVALID_HANDLE, which is -1. So, we're calling FSW_HANDLE c_int, not c_uint.
pub type FSW_HANDLE = c_int;
pub type FSW_CEVENT_CALLBACK = extern fn(events: *const fsw_cevent, event_num: c_uint, data: *mut c_void);

pub const FSW_INVALID_HANDLE: FSW_HANDLE = -1;

pub const FSW_OK: FSW_STATUS = 0;
pub const FSW_ERR_UNKNOWN_ERROR: FSW_STATUS = 1;
pub const FSW_ERR_SESSION_UNKNOWN: FSW_STATUS = (1 << 1);
pub const FSW_ERR_MONITOR_ALREADY_EXISTS: FSW_STATUS = (1 << 2);
pub const FSW_ERR_MEMORY: FSW_STATUS = (1 << 3);
pub const FSW_ERR_UNKNOWN_MONITOR_TYPE: FSW_STATUS = (1 << 4);
pub const FSW_ERR_CALLBACK_NOT_SET: FSW_STATUS = (1 << 5);
pub const FSW_ERR_PATHS_NOT_SET: FSW_STATUS = (1 << 6);
pub const FSW_ERR_MISSING_CONTEXT: FSW_STATUS = (1 << 7);
pub const FSW_ERR_INVALID_PATH: FSW_STATUS = (1 << 8);
pub const FSW_ERR_INVALID_CALLBACK: FSW_STATUS = (1 << 9);
pub const FSW_ERR_INVALID_LATENCY: FSW_STATUS = (1 << 10);
pub const FSW_ERR_INVALID_REGEX: FSW_STATUS = (1 << 11);
pub const FSW_ERR_MONITOR_ALREADY_RUNNING: FSW_STATUS = (1 << 12);
pub const FSW_ERR_UNKNOWN_VALUE: FSW_STATUS = (1 << 13);
pub const FSW_ERR_INVALID_PROPERTY: FSW_STATUS = (1 << 14);

#[repr(C)]
pub struct fsw_event_type_filter {
  pub flag: FswEventFlag
}

#[repr(C)]
pub struct fsw_cmonitor_filter {
  pub text: *const c_char,
  pub filter_type: FswFilterType,
  pub case_sensitive: bool,
  pub extended: bool
}

#[repr(C)]
pub struct fsw_cevent {
  pub path: *const c_char,
  pub evt_time: time_t,
  pub flags: *const FswEventFlag,
  pub flags_num: c_uint
}

#[repr(u32)]
pub enum fsw_event_flag {
  NoOp = 0,
  PlatformSpecific = 1,
  Created = (1 << 1),
  Updated = (1 << 2),
  Removed = (1 << 3),
  Renamed = (1 << 4),
  OwnerModified = (1 << 5),
  AttributeModified = (1 << 6),
  MovedFrom = (1 << 7),
  MovedTo = (1 << 8),
  IsFile = (1 << 9),
  IsDir = (1 << 10),
  IsSymLink = (1 << 11),
  Link = (1 << 12),
  Overflow = (1 << 13)
}

#[repr(C)]
pub enum fsw_filter_type {
  filter_include,
  filter_exclude
}

#[repr(C)]
pub enum fsw_monitor_type {
  system_default_monitor_type,
  fsevents_monitor_type,
  kqueue_monitor_type,
  inotify_monitor_type,
  windows_monitor_type,
  poll_monitor_type,
  fen_monitor_type
}
<commit_msg>fix: use refactored names<commit_after>//! The FFI bindings.
//!
//! See the [C API docs](http://emcrisostomo.github.io/fswatch/doc/1.9.3/libfswatch.html/libfswatch_8h.html).

#![allow(non_camel_case_types)]

extern crate libc;

use libc::{c_int, c_uint, c_void, c_double, c_char, time_t};

#[link(name = "fswatch")]
extern "C" {
  pub fn fsw_init_library() -> FSW_STATUS;

  pub fn fsw_init_session(monitor_type: fsw_monitor_type) -> FSW_HANDLE;

  pub fn fsw_add_path(handle: FSW_HANDLE, path: *const c_char) -> FSW_STATUS;

  pub fn fsw_add_property(handle: FSW_HANDLE, name: *const c_char, value: *const c_char) -> FSW_STATUS;

  pub fn fsw_set_allow_overflow(handle: FSW_HANDLE, allow_overflow: bool) -> FSW_STATUS;

  pub fn fsw_set_callback(handle: FSW_HANDLE, callback: FSW_CEVENT_CALLBACK, data: *const c_void) -> FSW_STATUS;

  pub fn fsw_set_latency(handle: FSW_HANDLE, latency: c_double) -> FSW_STATUS;

  pub fn fsw_set_recursive(handle: FSW_HANDLE, recursive: bool) -> FSW_STATUS;

  pub fn fsw_set_directory_only(handle: FSW_HANDLE, directory_only: bool) -> FSW_STATUS;

  pub fn fsw_set_follow_symlinks(handle: FSW_HANDLE, follow_symlinks: bool) -> FSW_STATUS;

  pub fn fsw_add_event_type_filter(handle: FSW_HANDLE, event_type: fsw_event_type_filter) -> FSW_STATUS;

  pub fn fsw_add_filter(handle: FSW_HANDLE, filter: fsw_cmonitor_filter) -> FSW_STATUS;

  pub fn fsw_start_monitor(handle: FSW_HANDLE) -> FSW_STATUS;

  pub fn fsw_destroy_session(handle: FSW_HANDLE) -> FSW_STATUS;

  pub fn fsw_last_error() -> FSW_STATUS;

  pub fn fsw_is_verbose() -> bool;

  pub fn fsw_set_verbose(verbose: bool);
}

pub type FSW_STATUS = c_int;
// type FSW_HANDLE = c_uint;
// Fun story here. FSW_HANDLE is defined as an unsigned int, but it can return a signed int,
// FSW_INVALID_HANDLE, which is -1. So, we're calling FSW_HANDLE c_int, not c_uint.
pub type FSW_HANDLE = c_int;
pub type FSW_CEVENT_CALLBACK = extern fn(events: *const fsw_cevent, event_num: c_uint, data: *mut c_void);

pub const FSW_INVALID_HANDLE: FSW_HANDLE = -1;

pub const FSW_OK: FSW_STATUS = 0;
pub const FSW_ERR_UNKNOWN_ERROR: FSW_STATUS = 1;
pub const FSW_ERR_SESSION_UNKNOWN: FSW_STATUS = (1 << 1);
pub const FSW_ERR_MONITOR_ALREADY_EXISTS: FSW_STATUS = (1 << 2);
pub const FSW_ERR_MEMORY: FSW_STATUS = (1 << 3);
pub const FSW_ERR_UNKNOWN_MONITOR_TYPE: FSW_STATUS = (1 << 4);
pub const FSW_ERR_CALLBACK_NOT_SET: FSW_STATUS = (1 << 5);
pub const FSW_ERR_PATHS_NOT_SET: FSW_STATUS = (1 << 6);
pub const FSW_ERR_MISSING_CONTEXT: FSW_STATUS = (1 << 7);
pub const FSW_ERR_INVALID_PATH: FSW_STATUS = (1 << 8);
pub const FSW_ERR_INVALID_CALLBACK: FSW_STATUS = (1 << 9);
pub const FSW_ERR_INVALID_LATENCY: FSW_STATUS = (1 << 10);
pub const FSW_ERR_INVALID_REGEX: FSW_STATUS = (1 << 11);
pub const FSW_ERR_MONITOR_ALREADY_RUNNING: FSW_STATUS = (1 << 12);
pub const FSW_ERR_UNKNOWN_VALUE: FSW_STATUS = (1 << 13);
pub const FSW_ERR_INVALID_PROPERTY: FSW_STATUS = (1 << 14);

#[repr(C)]
pub struct fsw_event_type_filter {
  pub flag: fsw_event_flag
}

#[repr(C)]
pub struct fsw_cmonitor_filter {
  pub text: *const c_char,
  pub filter_type: fsw_filter_type,
  pub case_sensitive: bool,
  pub extended: bool
}

#[repr(C)]
pub struct fsw_cevent {
  pub path: *const c_char,
  pub evt_time: time_t,
  pub flags: *const fsw_event_flag,
  pub flags_num: c_uint
}

#[repr(u32)]
pub enum fsw_event_flag {
  NoOp = 0,
  PlatformSpecific = 1,
  Created = (1 << 1),
  Updated = (1 << 2),
  Removed = (1 << 3),
  Renamed = (1 << 4),
  OwnerModified = (1 << 5),
  AttributeModified = (1 << 6),
  MovedFrom = (1 << 7),
  MovedTo = (1 << 8),
  IsFile = (1 << 9),
  IsDir = (1 << 10),
  IsSymLink = (1 << 11),
  Link = (1 << 12),
  Overflow = (1 << 13)
}

#[repr(C)]
pub enum fsw_filter_type {
  filter_include,
  filter_exclude
}

#[repr(C)]
pub enum fsw_monitor_type {
  system_default_monitor_type,
  fsevents_monitor_type,
  kqueue_monitor_type,
  inotify_monitor_type,
  windows_monitor_type,
  poll_monitor_type,
  fen_monitor_type
}
<|endoftext|>


<commit_before>/// Calculate the crc64 checksum of the given data, starting with the given crc.
///
/// Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
///
/// Specification of this CRC64 variant follows:
///
/// ```text
/// Name: crc-64-jones
/// Width: 64 bites
/// Poly: 0xad93d23594c935a9
/// Reflected In: True
/// Xor_In: 0xffffffffffffffff
/// Reflected_Out: True
/// Xor_Out: 0x0
/// Check("123456789"): 0xe9c6d914c4b8d9ca
/// ```
///
/// Example:
///
/// ```rust
/// crc64::crc64(0, "123456789".as_bytes());
/// ```

use std::mem;
use crc_table::CRC64_TAB;
mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1usize;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i+=1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly : u64 = 0xad93d23594c935a9;

    let mut bit : bool;

    let mut offset = 0usize;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i & 0xff != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset+=1;
    }
    crc = crc & 0xffffffffffffffff;

    return crc_reflect(crc, 64) ^ 0x0000000000000000;
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc : u64;

    let mut table : Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in (0..8) {
        table.push(Vec::with_capacity(256));
    };

    for n in (0usize..256) {
        table[0].push(crc64_trivial(0, &vec![n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in (0usize..256) {
        crc = table[0][n];
        for k in (1usize..8) {
            let idx  = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    };

    table
}

// transmute slice of 8 u8 values to one u64 (drop the length)
macro_rules! slice_to_long {
    ($curVec:expr) => {
        {
            unsafe {
                let (tmp, _) : (*const u64, usize) = mem::transmute(&$curVec);
                *tmp
            }
        }
    }
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= slice_to_long!(data[offset..(offset+8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize] ^
              CRC64_TAB[6][((crc >> 8) & 0xff) as usize] ^
              CRC64_TAB[5][((crc >> 16) & 0xff) as usize] ^
              CRC64_TAB[4][((crc >> 24) & 0xff) as usize] ^
              CRC64_TAB[3][((crc >> 32) & 0xff) as usize] ^
              CRC64_TAB[2][((crc >> 40) & 0xff) as usize] ^
              CRC64_TAB[1][((crc >> 48) & 0xff) as usize] ^
              CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}
<commit_msg>Auto merge of #4 - seppo0010:master, r=badboy<commit_after>/// Calculate the crc64 checksum of the given data, starting with the given crc.
///
/// Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
///
/// Specification of this CRC64 variant follows:
///
/// ```text
/// Name: crc-64-jones
/// Width: 64 bites
/// Poly: 0xad93d23594c935a9
/// Reflected In: True
/// Xor_In: 0xffffffffffffffff
/// Reflected_Out: True
/// Xor_Out: 0x0
/// Check("123456789"): 0xe9c6d914c4b8d9ca
/// ```
///
/// Example:
///
/// ```rust
/// crc64::crc64(0, "123456789".as_bytes());
/// ```

use std::io;
use std::io::Write;
use std::mem;
use crc_table::CRC64_TAB;
mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1usize;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i+=1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly : u64 = 0xad93d23594c935a9;

    let mut bit : bool;

    let mut offset = 0usize;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i & 0xff != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset+=1;
    }
    crc = crc & 0xffffffffffffffff;

    return crc_reflect(crc, 64) ^ 0x0000000000000000;
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc : u64;

    let mut table : Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in (0..8) {
        table.push(Vec::with_capacity(256));
    };

    for n in (0usize..256) {
        table[0].push(crc64_trivial(0, &vec![n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in (0usize..256) {
        crc = table[0][n];
        for k in (1usize..8) {
            let idx  = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    };

    table
}

// transmute slice of 8 u8 values to one u64 (drop the length)
macro_rules! slice_to_long {
    ($curVec:expr) => {
        {
            unsafe {
                let (tmp, _) : (*const u64, usize) = mem::transmute(&$curVec);
                *tmp
            }
        }
    }
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= slice_to_long!(data[offset..(offset+8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize] ^
              CRC64_TAB[6][((crc >> 8) & 0xff) as usize] ^
              CRC64_TAB[5][((crc >> 16) & 0xff) as usize] ^
              CRC64_TAB[4][((crc >> 24) & 0xff) as usize] ^
              CRC64_TAB[3][((crc >> 32) & 0xff) as usize] ^
              CRC64_TAB[2][((crc >> 40) & 0xff) as usize] ^
              CRC64_TAB[1][((crc >> 48) & 0xff) as usize] ^
              CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, &step1));
    assert_eq!(value2, crc64(value1, &step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(&step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(&step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<|endoftext|>


<commit_before>//! Various extension methods to ast Nodes, which are hard to code-generate.
//! Extensions for various expressions live in a sibling `expr_extensions` module.

use std::fmt;

use itertools::Itertools;
use ra_parser::SyntaxKind;

use crate::{
    ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode},
    SmolStr, SyntaxElement, SyntaxToken, T,
};

impl ast::Name {
    pub fn text(&self) -> &SmolStr {
        text_of_first_token(self.syntax())
    }
}

impl ast::NameRef {
    pub fn text(&self) -> &SmolStr {
        text_of_first_token(self.syntax())
    }

    pub fn as_tuple_field(&self) -> Option<usize> {
        self.text().parse().ok()
    }
}

fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
    node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AttrKind {
    Inner,
    Outer,
}

impl ast::Attr {
    pub fn as_simple_atom(&self) -> Option<SmolStr> {
        match self.input() {
            None => self.simple_name(),
            Some(_) => None,
        }
    }

    pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
        match self.input() {
            Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
            _ => None,
        }
    }

    pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
        match self.input() {
            Some(AttrInput::Literal(lit)) => {
                let key = self.simple_name()?;
                // FIXME: escape? raw string?
                let value = lit.syntax().first_token()?.text().trim_matches('"').into();
                Some((key, value))
            }
            _ => None,
        }
    }

    pub fn simple_name(&self) -> Option<SmolStr> {
        let path = self.path()?;
        match (path.segment(), path.qualifier()) {
            (Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
            _ => None,
        }
    }

    pub fn kind(&self) -> AttrKind {
        let first_token = self.syntax().first_token();
        let first_token_kind = first_token.as_ref().map(SyntaxToken::kind);
        let second_token_kind =
            first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind);

        match (first_token_kind, second_token_kind) {
            (Some(SyntaxKind::POUND), Some(T![!])) => AttrKind::Inner,
            _ => AttrKind::Outer,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PathSegmentKind {
    Name(ast::NameRef),
    Type { type_ref: Option<ast::TypeRef>, trait_ref: Option<ast::PathType> },
    SelfKw,
    SuperKw,
    CrateKw,
}

impl ast::PathSegment {
    pub fn parent_path(&self) -> ast::Path {
        self.syntax()
            .parent()
            .and_then(ast::Path::cast)
            .expect("segments are always nested in paths")
    }

    pub fn kind(&self) -> Option<PathSegmentKind> {
        let res = if let Some(name_ref) = self.name_ref() {
            PathSegmentKind::Name(name_ref)
        } else {
            match self.syntax().first_child_or_token()?.kind() {
                T![self] => PathSegmentKind::SelfKw,
                T![super] => PathSegmentKind::SuperKw,
                T![crate] => PathSegmentKind::CrateKw,
                T![<] => {
                    // <T> or <T as Trait>
                    // T is any TypeRef, Trait has to be a PathType
                    let mut type_refs =
                        self.syntax().children().filter(|node| ast::TypeRef::can_cast(node.kind()));
                    let type_ref = type_refs.next().and_then(ast::TypeRef::cast);
                    let trait_ref = type_refs.next().and_then(ast::PathType::cast);
                    PathSegmentKind::Type { type_ref, trait_ref }
                }
                _ => return None,
            }
        };
        Some(res)
    }
}

impl ast::Path {
    pub fn parent_path(&self) -> Option<ast::Path> {
        self.syntax().parent().and_then(ast::Path::cast)
    }
}

impl ast::UseTreeList {
    pub fn parent_use_tree(&self) -> ast::UseTree {
        self.syntax()
            .parent()
            .and_then(ast::UseTree::cast)
            .expect("UseTreeLists are always nested in UseTrees")
    }
}

impl ast::ImplDef {
    pub fn target_type(&self) -> Option<ast::TypeRef> {
        match self.target() {
            (Some(t), None) | (_, Some(t)) => Some(t),
            _ => None,
        }
    }

    pub fn target_trait(&self) -> Option<ast::TypeRef> {
        match self.target() {
            (Some(t), Some(_)) => Some(t),
            _ => None,
        }
    }

    fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) {
        let mut types = support::children(self.syntax());
        let first = types.next();
        let second = types.next();
        (first, second)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StructKind {
    Record(ast::RecordFieldDefList),
    Tuple(ast::TupleFieldDefList),
    Unit,
}

impl StructKind {
    fn from_node<N: AstNode>(node: &N) -> StructKind {
        if let Some(nfdl) = support::child::<ast::RecordFieldDefList>(node.syntax()) {
            StructKind::Record(nfdl)
        } else if let Some(pfl) = support::child::<ast::TupleFieldDefList>(node.syntax()) {
            StructKind::Tuple(pfl)
        } else {
            StructKind::Unit
        }
    }
}

impl ast::StructDef {
    pub fn kind(&self) -> StructKind {
        StructKind::from_node(self)
    }
}

impl ast::RecordField {
    pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordField> {
        let candidate =
            field_name.syntax().parent().and_then(ast::RecordField::cast).or_else(|| {
                field_name.syntax().ancestors().nth(4).and_then(ast::RecordField::cast)
            })?;
        if candidate.field_name().as_ref() == Some(field_name) {
            Some(candidate)
        } else {
            None
        }
    }

    /// Deals with field init shorthand
    pub fn field_name(&self) -> Option<ast::NameRef> {
        if let Some(name_ref) = self.name_ref() {
            return Some(name_ref);
        }
        if let Some(ast::Expr::PathExpr(expr)) = self.expr() {
            let path = expr.path()?;
            let segment = path.segment()?;
            let name_ref = segment.name_ref()?;
            if path.qualifier().is_none() {
                return Some(name_ref);
            }
        }
        None
    }
}

pub enum NameOrNameRef {
    Name(ast::Name),
    NameRef(ast::NameRef),
}

impl fmt::Display for NameOrNameRef {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            NameOrNameRef::Name(it) => fmt::Display::fmt(it, f),
            NameOrNameRef::NameRef(it) => fmt::Display::fmt(it, f),
        }
    }
}

impl ast::RecordFieldPat {
    /// Deals with field init shorthand
    pub fn field_name(&self) -> Option<NameOrNameRef> {
        if let Some(name_ref) = self.name_ref() {
            return Some(NameOrNameRef::NameRef(name_ref));
        }
        if let Some(ast::Pat::BindPat(pat)) = self.pat() {
            let name = pat.name()?;
            return Some(NameOrNameRef::Name(name));
        }
        None
    }
}

impl ast::EnumVariant {
    pub fn parent_enum(&self) -> ast::EnumDef {
        self.syntax()
            .parent()
            .and_then(|it| it.parent())
            .and_then(ast::EnumDef::cast)
            .expect("EnumVariants are always nested in Enums")
    }
    pub fn kind(&self) -> StructKind {
        StructKind::from_node(self)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FieldKind {
    Name(ast::NameRef),
    Index(SyntaxToken),
}

impl ast::FieldExpr {
    pub fn index_token(&self) -> Option<SyntaxToken> {
        self.syntax
            .children_with_tokens()
            // FIXME: Accepting floats here to reject them in validation later
            .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER)
            .as_ref()
            .and_then(SyntaxElement::as_token)
            .cloned()
    }

    pub fn field_access(&self) -> Option<FieldKind> {
        if let Some(nr) = self.name_ref() {
            Some(FieldKind::Name(nr))
        } else if let Some(tok) = self.index_token() {
            Some(FieldKind::Index(tok))
        } else {
            None
        }
    }
}

pub struct SlicePatComponents {
    pub prefix: Vec<ast::Pat>,
    pub slice: Option<ast::Pat>,
    pub suffix: Vec<ast::Pat>,
}

impl ast::SlicePat {
    pub fn components(&self) -> SlicePatComponents {
        let mut args = self.args().peekable();
        let prefix = args
            .peeking_take_while(|p| match p {
                ast::Pat::DotDotPat(_) => false,
                ast::Pat::BindPat(bp) => match bp.pat() {
                    Some(ast::Pat::DotDotPat(_)) => false,
                    _ => true,
                },
                ast::Pat::RefPat(rp) => match rp.pat() {
                    Some(ast::Pat::DotDotPat(_)) => false,
                    Some(ast::Pat::BindPat(bp)) => match bp.pat() {
                        Some(ast::Pat::DotDotPat(_)) => false,
                        _ => true,
                    },
                    _ => true,
                },
                _ => true,
            })
            .collect();
        let slice = args.next();
        let suffix = args.collect();

        SlicePatComponents { prefix, slice, suffix }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum SelfParamKind {
    /// self
    Owned,
    /// &self
    Ref,
    /// &mut self
    MutRef,
}

impl ast::SelfParam {
    pub fn kind(&self) -> SelfParamKind {
        if self.amp_token().is_some() {
            if self.mut_token().is_some() {
                SelfParamKind::MutRef
            } else {
                SelfParamKind::Ref
            }
        } else {
            SelfParamKind::Owned
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum TypeBoundKind {
    /// Trait
    PathType(ast::PathType),
    /// for<'a> ...
    ForType(ast::ForType),
    /// 'a
    Lifetime(SyntaxToken),
}

impl ast::TypeBound {
    pub fn kind(&self) -> TypeBoundKind {
        if let Some(path_type) = support::children(self.syntax()).next() {
            TypeBoundKind::PathType(path_type)
        } else if let Some(for_type) = support::children(self.syntax()).next() {
            TypeBoundKind::ForType(for_type)
        } else if let Some(lifetime) = self.lifetime_token() {
            TypeBoundKind::Lifetime(lifetime)
        } else {
            unreachable!()
        }
    }

    pub fn const_question_token(&self) -> Option<SyntaxToken> {
        self.syntax()
            .children_with_tokens()
            .filter_map(|it| it.into_token())
            .take_while(|it| it.kind() != T![const])
            .find(|it| it.kind() == T![?])
    }

    pub fn question_token(&self) -> Option<SyntaxToken> {
        if self.const_token().is_some() {
            self.syntax()
                .children_with_tokens()
                .filter_map(|it| it.into_token())
                .skip_while(|it| it.kind() != T![const])
                .find(|it| it.kind() == T![?])
        } else {
            support::token(&self.syntax, T![?])
        }
    }
}

pub enum VisibilityKind {
    In(ast::Path),
    PubCrate,
    PubSuper,
    PubSelf,
    Pub,
}

impl ast::Visibility {
    pub fn kind(&self) -> VisibilityKind {
        if let Some(path) = support::children(self.syntax()).next() {
            VisibilityKind::In(path)
        } else if self.crate_token().is_some() {
            VisibilityKind::PubCrate
        } else if self.super_token().is_some() {
            VisibilityKind::PubSuper
        } else if self.self_token().is_some() {
            VisibilityKind::PubSuper
        } else {
            VisibilityKind::Pub
        }
    }
}

impl ast::MacroCall {
    pub fn is_macro_rules(&self) -> Option<ast::Name> {
        let name_ref = self.path()?.segment()?.name_ref()?;
        if name_ref.text() == "macro_rules" {
            self.name()
        } else {
            None
        }
    }
}

impl ast::LifetimeParam {
    pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
        self.syntax()
            .children_with_tokens()
            .filter_map(|it| it.into_token())
            .skip_while(|x| x.kind() != T![:])
            .filter(|it| it.kind() == T![lifetime])
    }
}

impl ast::RangePat {
    pub fn start(&self) -> Option<ast::Pat> {
        self.syntax()
            .children_with_tokens()
            .take_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
            .filter_map(|it| it.into_node())
            .find_map(ast::Pat::cast)
    }

    pub fn end(&self) -> Option<ast::Pat> {
        self.syntax()
            .children_with_tokens()
            .skip_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
            .filter_map(|it| it.into_node())
            .find_map(ast::Pat::cast)
    }
}

impl ast::TokenTree {
    pub fn left_delimiter_token(&self) -> Option<SyntaxToken> {
        self.syntax().first_child_or_token()?.into_token().filter(|it| match it.kind() {
            T!['{'] | T!['('] | T!['['] => true,
            _ => false,
        })
    }

    pub fn right_delimiter_token(&self) -> Option<SyntaxToken> {
        self.syntax().last_child_or_token()?.into_token().filter(|it| match it.kind() {
            T!['{'] | T!['('] | T!['['] => true,
            _ => false,
        })
    }
}
<commit_msg>Fix pub(self) visibility?<commit_after>//! Various extension methods to ast Nodes, which are hard to code-generate.
//! Extensions for various expressions live in a sibling `expr_extensions` module.

use std::fmt;

use itertools::Itertools;
use ra_parser::SyntaxKind;

use crate::{
    ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode},
    SmolStr, SyntaxElement, SyntaxToken, T,
};

impl ast::Name {
    pub fn text(&self) -> &SmolStr {
        text_of_first_token(self.syntax())
    }
}

impl ast::NameRef {
    pub fn text(&self) -> &SmolStr {
        text_of_first_token(self.syntax())
    }

    pub fn as_tuple_field(&self) -> Option<usize> {
        self.text().parse().ok()
    }
}

fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
    node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AttrKind {
    Inner,
    Outer,
}

impl ast::Attr {
    pub fn as_simple_atom(&self) -> Option<SmolStr> {
        match self.input() {
            None => self.simple_name(),
            Some(_) => None,
        }
    }

    pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
        match self.input() {
            Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
            _ => None,
        }
    }

    pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
        match self.input() {
            Some(AttrInput::Literal(lit)) => {
                let key = self.simple_name()?;
                // FIXME: escape? raw string?
                let value = lit.syntax().first_token()?.text().trim_matches('"').into();
                Some((key, value))
            }
            _ => None,
        }
    }

    pub fn simple_name(&self) -> Option<SmolStr> {
        let path = self.path()?;
        match (path.segment(), path.qualifier()) {
            (Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
            _ => None,
        }
    }

    pub fn kind(&self) -> AttrKind {
        let first_token = self.syntax().first_token();
        let first_token_kind = first_token.as_ref().map(SyntaxToken::kind);
        let second_token_kind =
            first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind);

        match (first_token_kind, second_token_kind) {
            (Some(SyntaxKind::POUND), Some(T![!])) => AttrKind::Inner,
            _ => AttrKind::Outer,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PathSegmentKind {
    Name(ast::NameRef),
    Type { type_ref: Option<ast::TypeRef>, trait_ref: Option<ast::PathType> },
    SelfKw,
    SuperKw,
    CrateKw,
}

impl ast::PathSegment {
    pub fn parent_path(&self) -> ast::Path {
        self.syntax()
            .parent()
            .and_then(ast::Path::cast)
            .expect("segments are always nested in paths")
    }

    pub fn kind(&self) -> Option<PathSegmentKind> {
        let res = if let Some(name_ref) = self.name_ref() {
            PathSegmentKind::Name(name_ref)
        } else {
            match self.syntax().first_child_or_token()?.kind() {
                T![self] => PathSegmentKind::SelfKw,
                T![super] => PathSegmentKind::SuperKw,
                T![crate] => PathSegmentKind::CrateKw,
                T![<] => {
                    // <T> or <T as Trait>
                    // T is any TypeRef, Trait has to be a PathType
                    let mut type_refs =
                        self.syntax().children().filter(|node| ast::TypeRef::can_cast(node.kind()));
                    let type_ref = type_refs.next().and_then(ast::TypeRef::cast);
                    let trait_ref = type_refs.next().and_then(ast::PathType::cast);
                    PathSegmentKind::Type { type_ref, trait_ref }
                }
                _ => return None,
            }
        };
        Some(res)
    }
}

impl ast::Path {
    pub fn parent_path(&self) -> Option<ast::Path> {
        self.syntax().parent().and_then(ast::Path::cast)
    }
}

impl ast::UseTreeList {
    pub fn parent_use_tree(&self) -> ast::UseTree {
        self.syntax()
            .parent()
            .and_then(ast::UseTree::cast)
            .expect("UseTreeLists are always nested in UseTrees")
    }
}

impl ast::ImplDef {
    pub fn target_type(&self) -> Option<ast::TypeRef> {
        match self.target() {
            (Some(t), None) | (_, Some(t)) => Some(t),
            _ => None,
        }
    }

    pub fn target_trait(&self) -> Option<ast::TypeRef> {
        match self.target() {
            (Some(t), Some(_)) => Some(t),
            _ => None,
        }
    }

    fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) {
        let mut types = support::children(self.syntax());
        let first = types.next();
        let second = types.next();
        (first, second)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StructKind {
    Record(ast::RecordFieldDefList),
    Tuple(ast::TupleFieldDefList),
    Unit,
}

impl StructKind {
    fn from_node<N: AstNode>(node: &N) -> StructKind {
        if let Some(nfdl) = support::child::<ast::RecordFieldDefList>(node.syntax()) {
            StructKind::Record(nfdl)
        } else if let Some(pfl) = support::child::<ast::TupleFieldDefList>(node.syntax()) {
            StructKind::Tuple(pfl)
        } else {
            StructKind::Unit
        }
    }
}

impl ast::StructDef {
    pub fn kind(&self) -> StructKind {
        StructKind::from_node(self)
    }
}

impl ast::RecordField {
    pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordField> {
        let candidate =
            field_name.syntax().parent().and_then(ast::RecordField::cast).or_else(|| {
                field_name.syntax().ancestors().nth(4).and_then(ast::RecordField::cast)
            })?;
        if candidate.field_name().as_ref() == Some(field_name) {
            Some(candidate)
        } else {
            None
        }
    }

    /// Deals with field init shorthand
    pub fn field_name(&self) -> Option<ast::NameRef> {
        if let Some(name_ref) = self.name_ref() {
            return Some(name_ref);
        }
        if let Some(ast::Expr::PathExpr(expr)) = self.expr() {
            let path = expr.path()?;
            let segment = path.segment()?;
            let name_ref = segment.name_ref()?;
            if path.qualifier().is_none() {
                return Some(name_ref);
            }
        }
        None
    }
}

pub enum NameOrNameRef {
    Name(ast::Name),
    NameRef(ast::NameRef),
}

impl fmt::Display for NameOrNameRef {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            NameOrNameRef::Name(it) => fmt::Display::fmt(it, f),
            NameOrNameRef::NameRef(it) => fmt::Display::fmt(it, f),
        }
    }
}

impl ast::RecordFieldPat {
    /// Deals with field init shorthand
    pub fn field_name(&self) -> Option<NameOrNameRef> {
        if let Some(name_ref) = self.name_ref() {
            return Some(NameOrNameRef::NameRef(name_ref));
        }
        if let Some(ast::Pat::BindPat(pat)) = self.pat() {
            let name = pat.name()?;
            return Some(NameOrNameRef::Name(name));
        }
        None
    }
}

impl ast::EnumVariant {
    pub fn parent_enum(&self) -> ast::EnumDef {
        self.syntax()
            .parent()
            .and_then(|it| it.parent())
            .and_then(ast::EnumDef::cast)
            .expect("EnumVariants are always nested in Enums")
    }
    pub fn kind(&self) -> StructKind {
        StructKind::from_node(self)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FieldKind {
    Name(ast::NameRef),
    Index(SyntaxToken),
}

impl ast::FieldExpr {
    pub fn index_token(&self) -> Option<SyntaxToken> {
        self.syntax
            .children_with_tokens()
            // FIXME: Accepting floats here to reject them in validation later
            .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER)
            .as_ref()
            .and_then(SyntaxElement::as_token)
            .cloned()
    }

    pub fn field_access(&self) -> Option<FieldKind> {
        if let Some(nr) = self.name_ref() {
            Some(FieldKind::Name(nr))
        } else if let Some(tok) = self.index_token() {
            Some(FieldKind::Index(tok))
        } else {
            None
        }
    }
}

pub struct SlicePatComponents {
    pub prefix: Vec<ast::Pat>,
    pub slice: Option<ast::Pat>,
    pub suffix: Vec<ast::Pat>,
}

impl ast::SlicePat {
    pub fn components(&self) -> SlicePatComponents {
        let mut args = self.args().peekable();
        let prefix = args
            .peeking_take_while(|p| match p {
                ast::Pat::DotDotPat(_) => false,
                ast::Pat::BindPat(bp) => match bp.pat() {
                    Some(ast::Pat::DotDotPat(_)) => false,
                    _ => true,
                },
                ast::Pat::RefPat(rp) => match rp.pat() {
                    Some(ast::Pat::DotDotPat(_)) => false,
                    Some(ast::Pat::BindPat(bp)) => match bp.pat() {
                        Some(ast::Pat::DotDotPat(_)) => false,
                        _ => true,
                    },
                    _ => true,
                },
                _ => true,
            })
            .collect();
        let slice = args.next();
        let suffix = args.collect();

        SlicePatComponents { prefix, slice, suffix }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum SelfParamKind {
    /// self
    Owned,
    /// &self
    Ref,
    /// &mut self
    MutRef,
}

impl ast::SelfParam {
    pub fn kind(&self) -> SelfParamKind {
        if self.amp_token().is_some() {
            if self.mut_token().is_some() {
                SelfParamKind::MutRef
            } else {
                SelfParamKind::Ref
            }
        } else {
            SelfParamKind::Owned
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum TypeBoundKind {
    /// Trait
    PathType(ast::PathType),
    /// for<'a> ...
    ForType(ast::ForType),
    /// 'a
    Lifetime(SyntaxToken),
}

impl ast::TypeBound {
    pub fn kind(&self) -> TypeBoundKind {
        if let Some(path_type) = support::children(self.syntax()).next() {
            TypeBoundKind::PathType(path_type)
        } else if let Some(for_type) = support::children(self.syntax()).next() {
            TypeBoundKind::ForType(for_type)
        } else if let Some(lifetime) = self.lifetime_token() {
            TypeBoundKind::Lifetime(lifetime)
        } else {
            unreachable!()
        }
    }

    pub fn const_question_token(&self) -> Option<SyntaxToken> {
        self.syntax()
            .children_with_tokens()
            .filter_map(|it| it.into_token())
            .take_while(|it| it.kind() != T![const])
            .find(|it| it.kind() == T![?])
    }

    pub fn question_token(&self) -> Option<SyntaxToken> {
        if self.const_token().is_some() {
            self.syntax()
                .children_with_tokens()
                .filter_map(|it| it.into_token())
                .skip_while(|it| it.kind() != T![const])
                .find(|it| it.kind() == T![?])
        } else {
            support::token(&self.syntax, T![?])
        }
    }
}

pub enum VisibilityKind {
    In(ast::Path),
    PubCrate,
    PubSuper,
    PubSelf,
    Pub,
}

impl ast::Visibility {
    pub fn kind(&self) -> VisibilityKind {
        if let Some(path) = support::children(self.syntax()).next() {
            VisibilityKind::In(path)
        } else if self.crate_token().is_some() {
            VisibilityKind::PubCrate
        } else if self.super_token().is_some() {
            VisibilityKind::PubSuper
        } else if self.self_token().is_some() {
            VisibilityKind::PubSelf
        } else {
            VisibilityKind::Pub
        }
    }
}

impl ast::MacroCall {
    pub fn is_macro_rules(&self) -> Option<ast::Name> {
        let name_ref = self.path()?.segment()?.name_ref()?;
        if name_ref.text() == "macro_rules" {
            self.name()
        } else {
            None
        }
    }
}

impl ast::LifetimeParam {
    pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
        self.syntax()
            .children_with_tokens()
            .filter_map(|it| it.into_token())
            .skip_while(|x| x.kind() != T![:])
            .filter(|it| it.kind() == T![lifetime])
    }
}

impl ast::RangePat {
    pub fn start(&self) -> Option<ast::Pat> {
        self.syntax()
            .children_with_tokens()
            .take_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
            .filter_map(|it| it.into_node())
            .find_map(ast::Pat::cast)
    }

    pub fn end(&self) -> Option<ast::Pat> {
        self.syntax()
            .children_with_tokens()
            .skip_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
            .filter_map(|it| it.into_node())
            .find_map(ast::Pat::cast)
    }
}

impl ast::TokenTree {
    pub fn left_delimiter_token(&self) -> Option<SyntaxToken> {
        self.syntax().first_child_or_token()?.into_token().filter(|it| match it.kind() {
            T!['{'] | T!['('] | T!['['] => true,
            _ => false,
        })
    }

    pub fn right_delimiter_token(&self) -> Option<SyntaxToken> {
        self.syntax().last_child_or_token()?.into_token().filter(|it| match it.kind() {
            T!['{'] | T!['('] | T!['['] => true,
            _ => false,
        })
    }
}
<|endoftext|>