<commit_before>use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
    braced,
    parse::{Parse, ParseStream, Result},
    Field, FieldValue, Ident, Meta, Token,
};

mod metadata;
mod request;
mod response;

use self::{metadata::Metadata, request::Request, response::Response};

pub fn strip_serde_attrs(field: &Field) -> Field {
    let mut field = field.clone();

    field.attrs = field
        .attrs
        .into_iter()
        .filter(|attr| {
            let meta = attr
                .interpret_meta()
                .expect("ruma_api! could not parse field attributes");

            let meta_list = match meta {
                Meta::List(meta_list) => meta_list,
                _ => return true,
            };

            if &meta_list.ident.to_string() == "serde" {
                return false;
            }

            true
        })
        .collect();

    field
}

pub struct Api {
    metadata: Metadata,
    request: Request,
    response: Response,
}

impl From<RawApi> for Api {
    fn from(raw_api: RawApi) -> Self {
        Api {
            metadata: raw_api.metadata.into(),
            request: raw_api.request.into(),
            response: raw_api.response.into(),
        }
    }
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let description = &self.metadata.description;
        let method = Ident::new(self.metadata.method.as_ref(), Span::call_site());
        let name = &self.metadata.name;
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request = &self.request;
        let request_types = quote! { #request };
        let response = &self.response;
        let response_types = quote! { #response };

        let extract_request_path = if self.request.has_path_fields() {
            quote! {
                let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
            }
        } else {
            TokenStream::new()
        };

        let (set_request_path, parse_request_path) = if self.request.has_path_fields() {
            let path_str = path.as_str();

            assert!(path_str.starts_with('/'), "path needs to start with '/'");
            assert!(
                path_str.chars().filter(|c| *c == ':').count() == self.request.path_field_count(),
                "number of declared path parameters needs to match amount of placeholders in path"
            );

            let request_path_init_fields = self.request.request_path_init_fields();

            let path_segments = path_str[1..].split('/').into_iter();
            let path_segment_push = path_segments.clone().map(|segment| {
                let arg = if segment.starts_with(':') {
                    let path_var = &segment[1..];
                    let path_var_ident = Ident::new(path_var, Span::call_site());
                    quote!(&request_path.#path_var_ident.to_string())
                } else {
                    quote!(#segment)
                };

                quote! {
                    path_segments.push(#arg);
                }
            });

            let set_tokens = quote! {
                let request_path = RequestPath {
                    #request_path_init_fields
                };

                // This `unwrap()` can only fail when the url is a
                // cannot-be-base url like `mailto:` or `data:`, which is not
                // the case for our placeholder url.
                let mut path_segments = url.path_segments_mut().unwrap();
                #(#path_segment_push)*
            };

            let path_fields = path_segments
                .enumerate()
                .filter(|(_, s)| s.starts_with(':'))
                .map(|(i, segment)| {
                    let path_var = &segment[1..];
                    let path_var_ident = Ident::new(path_var, Span::call_site());
                    let path_field = self
                        .request
                        .path_field(path_var)
                        .expect("expected request to have path field");
                    let ty = &path_field.ty;

                    quote! {
                        #path_var_ident: {
                            let segment = path_segments.get(#i).unwrap().as_bytes();
                            let decoded =
                                ::url::percent_encoding::percent_decode(segment)
                                .decode_utf8_lossy();
                            #ty::deserialize(decoded.into_deserializer())
                                .map_err(|e: ::serde_json::error::Error| e)?
                        }
                    }
                });

            let parse_tokens = quote! {
                #(#path_fields,)*
            };

            (set_tokens, parse_tokens)
        } else {
            let set_tokens = quote! {
                url.set_path(metadata.path);
            };
            let parse_tokens = TokenStream::new();
            (set_tokens, parse_tokens)
        };

        let set_request_query = if self.request.has_query_fields() {
            let request_query_init_fields = self.request.request_query_init_fields();

            quote! {
                let request_query = RequestQuery {
                    #request_query_init_fields
                };

                url.set_query(Some(&::serde_urlencoded::to_string(request_query)?));
            }
        } else {
            TokenStream::new()
        };

        let extract_request_query = if self.request.has_query_fields() {
            quote! {
                let request_query: RequestQuery =
                    ::serde_urlencoded::from_str(&request.uri().query().unwrap_or(""))?;
            }
        } else {
            TokenStream::new()
        };

        let parse_request_query = if self.request.has_query_fields() {
            self.request.request_init_query_fields()
        } else {
            TokenStream::new()
        };

        let add_headers_to_request = if self.request.has_header_fields() {
            let add_headers = self.request.add_headers_to_request();
            quote! {
                let headers = http_request.headers_mut();
                #add_headers
            }
        } else {
            TokenStream::new()
        };

        let extract_request_headers = if self.request.has_header_fields() {
            quote! {
                let headers = request.headers();
            }
        } else {
            TokenStream::new()
        };

        let parse_request_headers = if self.request.has_header_fields() {
            self.request.parse_headers_from_request()
        } else {
            TokenStream::new()
        };

        let create_http_request = if let Some(field) = self.request.newtype_body_field() {
            let field_name = field
                .ident
                .as_ref()
                .expect("expected field to have an identifier");

            quote! {
                let request_body = RequestBody(request.#field_name);

                let mut http_request = ::http::Request::new(::serde_json::to_vec(&request_body)?.into());
            }
        } else if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                let mut http_request = ::http::Request::new(::serde_json::to_vec(&request_body)?.into());
            }
        } else {
            quote! {
                let mut http_request = ::http::Request::new(::hyper::Body::empty());
            }
        };

        let extract_request_body = if let Some(field) = self.request.newtype_body_field() {
            let ty = &field.ty;
            quote! {
                let request_body: #ty =
                    ::serde_json::from_slice(request.body().as_slice())?;
            }
        } else if self.request.has_body_fields() {
            quote! {
                let request_body: RequestBody =
                    ::serde_json::from_slice(request.body().as_slice())?;
            }
        } else {
            TokenStream::new()
        };

        let parse_request_body = if let Some(field) = self.request.newtype_body_field() {
            let field_name = field
                .ident
                .as_ref()
                .expect("expected field to have an identifier");

            quote! {
                #field_name: request_body,
            }
        } else if self.request.has_body_fields() {
            self.request.request_init_body_fields()
        } else {
            TokenStream::new()
        };

        let deserialize_response_body = if let Some(field) = self.response.newtype_body_field() {
            let field_type = &field.ty;

            quote! {
                let future_response = http_response.into_body()
                    .fold(Vec::new(), |mut vec, chunk| {
                        vec.extend(chunk.iter());
                        ::futures::future::ok::<_, ::hyper::Error>(vec)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|data|
                              ::serde_json::from_slice::<#field_type>(data.as_slice())
                              .map_err(::ruma_api::Error::from)
                              .into_future()
                    )
            }
        } else if self.response.has_body_fields() {
            quote! {
                let future_response = http_response.into_body()
                    .fold(Vec::new(), |mut vec, chunk| {
                        vec.extend(chunk.iter());
                        ::futures::future::ok::<_, ::hyper::Error>(vec)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|data|
                              ::serde_json::from_slice::<ResponseBody>(data.as_slice())
                              .map_err(::ruma_api::Error::from)
                              .into_future()
                    )
            }
        } else {
            quote! {
                let future_response = ::futures::future::ok(())
            }
        };

        let extract_response_headers = if self.response.has_header_fields() {
            quote! {
                let mut headers = http_response.headers().clone();
            }
        } else {
            TokenStream::new()
        };

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            TokenStream::new()
        };

        let serialize_response_headers = self.response.apply_header_fields();

        let serialize_response_body = if self.response.has_body() {
            let body = self.response.to_body();
            quote! {
                .body(::hyper::Body::from(::serde_json::to_vec(&#body)?))
            }
        } else {
            quote! {
                .body(::hyper::Body::from("{}".as_bytes().to_vec()))
            }
        };

        tokens.append_all(quote! {
            #[allow(unused_imports)]
            use ::futures::{Future as _Future, IntoFuture as _IntoFuture, Stream as _Stream};
            use ::ruma_api::Endpoint as _RumaApiEndpoint;
            use ::serde::Deserialize;
            use ::serde::de::{Error as _SerdeError, IntoDeserializer};

            use ::std::convert::{TryInto as _TryInto};

            /// The API endpoint.
            #[derive(Debug)]
            pub struct Endpoint;

            #request_types

            impl ::std::convert::TryFrom<::http::Request<Vec<u8>>> for Request {
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn try_from(request: ::http::Request<Vec<u8>>) -> Result<Self, Self::Error> {
                    #extract_request_path
                    #extract_request_query
                    #extract_request_headers
                    #extract_request_body

                    Ok(Request {
                        #parse_request_path
                        #parse_request_query
                        #parse_request_headers
                        #parse_request_body
                    })
                }
            }

            impl ::futures::future::FutureFrom<::http::Request<::hyper::Body>> for Request {
                type Future = Box<_Future<Item = Self, Error = Self::Error> + Send>;
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn future_from(request: ::http::Request<::hyper::Body>) -> Self::Future {
                    let (parts, body) = request.into_parts();
                    let future = body.from_err().fold(Vec::new(), |mut vec, chunk| {
                        vec.extend(chunk.iter());
                        ::futures::future::ok::<_, Self::Error>(vec)
                    }).and_then(|body| {
                        ::http::Request::from_parts(parts, body)
                            .try_into()
                            .into_future()
                            .from_err()
                    });
                    Box::new(future)
                }
            }

            impl ::std::convert::TryFrom<Request> for ::http::Request<::hyper::Body> {
                type Error = ::ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Endpoint::METADATA;

                    // Use dummy homeserver url which has to be overwritten in
                    // the calling code. Previously (with http::Uri) this was
                    // not required, but Url::parse only accepts absolute urls.
                    let mut url = ::url::Url::parse("http://invalid-host-please-change/").unwrap();

                    { #set_request_path }
                    { #set_request_query }

                    #create_http_request

                    *http_request.method_mut() = ::http::Method::#method;
                    *http_request.uri_mut() = url.into_string().parse().unwrap();

                    { #add_headers_to_request }

                    Ok(http_request)
                }
            }

            #response_types

            impl ::std::convert::TryFrom<Response> for ::http::Response<::hyper::Body> {
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn try_from(response: Response) -> Result<Self, Self::Error> {
                    let response = ::http::Response::builder()
                        .header(::http::header::CONTENT_TYPE, "application/json")
                        #serialize_response_headers
                        #serialize_response_body
                        .unwrap();
                    Ok(response)
                }
            }

            impl ::futures::future::FutureFrom<::http::Response<::hyper::Body>> for Response {
                type Future = Box<_Future<Item = Self, Error = Self::Error> + Send>;
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn future_from(http_response: ::http::Response<::hyper::Body>) -> Self::Future {
                    if http_response.status().is_success() {
                        #extract_response_headers

                        #deserialize_response_body
                        .and_then(move |response_body| {
                            let response = Response {
                                #response_init_fields
                            };

                            Ok(response)
                        });

                        Box::new(future_response)
                    } else {
                        Box::new(::futures::future::err(::ruma_api::Error::StatusCode(http_response.status().clone())))
                    }
                }
            }

            impl ::ruma_api::Endpoint for Endpoint {
                type Request = Request;
                type Response = Response;

                const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
                    description: #description,
                    method: ::http::Method::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        });
    }
}

mod kw {
    use syn::custom_keyword;

    custom_keyword!(metadata);
    custom_keyword!(request);
    custom_keyword!(response);
}

pub struct RawApi {
    pub metadata: Vec<FieldValue>,
    pub request: Vec<Field>,
    pub response: Vec<Field>,
}

impl Parse for RawApi {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        input.parse::<kw::metadata>()?;
        let metadata;
        braced!(metadata in input);

        input.parse::<kw::request>()?;
        let request;
        braced!(request in input);

        input.parse::<kw::response>()?;
        let response;
        braced!(response in input);

        Ok(RawApi {
            metadata: metadata
                .parse_terminated::<FieldValue, Token![,]>(FieldValue::parse)?
                .into_iter()
                .collect(),
            request: request
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
            response: response
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
        })
    }
}
<commit_msg>Fix trait imports in generated code without rename<commit_after>use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
    braced,
    parse::{Parse, ParseStream, Result},
    Field, FieldValue, Ident, Meta, Token,
};

mod metadata;
mod request;
mod response;

use self::{metadata::Metadata, request::Request, response::Response};

pub fn strip_serde_attrs(field: &Field) -> Field {
    let mut field = field.clone();

    field.attrs = field
        .attrs
        .into_iter()
        .filter(|attr| {
            let meta = attr
                .interpret_meta()
                .expect("ruma_api! could not parse field attributes");

            let meta_list = match meta {
                Meta::List(meta_list) => meta_list,
                _ => return true,
            };

            if &meta_list.ident.to_string() == "serde" {
                return false;
            }

            true
        })
        .collect();

    field
}

pub struct Api {
    metadata: Metadata,
    request: Request,
    response: Response,
}

impl From<RawApi> for Api {
    fn from(raw_api: RawApi) -> Self {
        Api {
            metadata: raw_api.metadata.into(),
            request: raw_api.request.into(),
            response: raw_api.response.into(),
        }
    }
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let description = &self.metadata.description;
        let method = Ident::new(self.metadata.method.as_ref(), Span::call_site());
        let name = &self.metadata.name;
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request = &self.request;
        let request_types = quote! { #request };
        let response = &self.response;
        let response_types = quote! { #response };

        let extract_request_path = if self.request.has_path_fields() {
            quote! {
                let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
            }
        } else {
            TokenStream::new()
        };

        let (set_request_path, parse_request_path) = if self.request.has_path_fields() {
            let path_str = path.as_str();

            assert!(path_str.starts_with('/'), "path needs to start with '/'");
            assert!(
                path_str.chars().filter(|c| *c == ':').count() == self.request.path_field_count(),
                "number of declared path parameters needs to match amount of placeholders in path"
            );

            let request_path_init_fields = self.request.request_path_init_fields();

            let path_segments = path_str[1..].split('/').into_iter();
            let path_segment_push = path_segments.clone().map(|segment| {
                let arg = if segment.starts_with(':') {
                    let path_var = &segment[1..];
                    let path_var_ident = Ident::new(path_var, Span::call_site());
                    quote!(&request_path.#path_var_ident.to_string())
                } else {
                    quote!(#segment)
                };

                quote! {
                    path_segments.push(#arg);
                }
            });

            let set_tokens = quote! {
                let request_path = RequestPath {
                    #request_path_init_fields
                };

                // This `unwrap()` can only fail when the url is a
                // cannot-be-base url like `mailto:` or `data:`, which is not
                // the case for our placeholder url.
                let mut path_segments = url.path_segments_mut().unwrap();
                #(#path_segment_push)*
            };

            let path_fields = path_segments
                .enumerate()
                .filter(|(_, s)| s.starts_with(':'))
                .map(|(i, segment)| {
                    let path_var = &segment[1..];
                    let path_var_ident = Ident::new(path_var, Span::call_site());
                    let path_field = self
                        .request
                        .path_field(path_var)
                        .expect("expected request to have path field");
                    let ty = &path_field.ty;

                    quote! {
                        #path_var_ident: {
                            let segment = path_segments.get(#i).unwrap().as_bytes();
                            let decoded =
                                ::url::percent_encoding::percent_decode(segment)
                                .decode_utf8_lossy();
                            #ty::deserialize(decoded.into_deserializer())
                                .map_err(|e: ::serde_json::error::Error| e)?
                        }
                    }
                });

            let parse_tokens = quote! {
                #(#path_fields,)*
            };

            (set_tokens, parse_tokens)
        } else {
            let set_tokens = quote! {
                url.set_path(metadata.path);
            };
            let parse_tokens = TokenStream::new();
            (set_tokens, parse_tokens)
        };

        let set_request_query = if self.request.has_query_fields() {
            let request_query_init_fields = self.request.request_query_init_fields();

            quote! {
                let request_query = RequestQuery {
                    #request_query_init_fields
                };

                url.set_query(Some(&::serde_urlencoded::to_string(request_query)?));
            }
        } else {
            TokenStream::new()
        };

        let extract_request_query = if self.request.has_query_fields() {
            quote! {
                let request_query: RequestQuery =
                    ::serde_urlencoded::from_str(&request.uri().query().unwrap_or(""))?;
            }
        } else {
            TokenStream::new()
        };

        let parse_request_query = if self.request.has_query_fields() {
            self.request.request_init_query_fields()
        } else {
            TokenStream::new()
        };

        let add_headers_to_request = if self.request.has_header_fields() {
            let add_headers = self.request.add_headers_to_request();
            quote! {
                let headers = http_request.headers_mut();
                #add_headers
            }
        } else {
            TokenStream::new()
        };

        let extract_request_headers = if self.request.has_header_fields() {
            quote! {
                let headers = request.headers();
            }
        } else {
            TokenStream::new()
        };

        let parse_request_headers = if self.request.has_header_fields() {
            self.request.parse_headers_from_request()
        } else {
            TokenStream::new()
        };

        let create_http_request = if let Some(field) = self.request.newtype_body_field() {
            let field_name = field
                .ident
                .as_ref()
                .expect("expected field to have an identifier");

            quote! {
                let request_body = RequestBody(request.#field_name);

                let mut http_request = ::http::Request::new(::serde_json::to_vec(&request_body)?.into());
            }
        } else if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                let mut http_request = ::http::Request::new(::serde_json::to_vec(&request_body)?.into());
            }
        } else {
            quote! {
                let mut http_request = ::http::Request::new(::hyper::Body::empty());
            }
        };

        let extract_request_body = if let Some(field) = self.request.newtype_body_field() {
            let ty = &field.ty;
            quote! {
                let request_body: #ty =
                    ::serde_json::from_slice(request.body().as_slice())?;
            }
        } else if self.request.has_body_fields() {
            quote! {
                let request_body: RequestBody =
                    ::serde_json::from_slice(request.body().as_slice())?;
            }
        } else {
            TokenStream::new()
        };

        let parse_request_body = if let Some(field) = self.request.newtype_body_field() {
            let field_name = field
                .ident
                .as_ref()
                .expect("expected field to have an identifier");

            quote! {
                #field_name: request_body,
            }
        } else if self.request.has_body_fields() {
            self.request.request_init_body_fields()
        } else {
            TokenStream::new()
        };

        let deserialize_response_body = if let Some(field) = self.response.newtype_body_field() {
            let field_type = &field.ty;

            quote! {
                let future_response = http_response.into_body()
                    .fold(Vec::new(), |mut vec, chunk| {
                        vec.extend(chunk.iter());
                        ::futures::future::ok::<_, ::hyper::Error>(vec)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|data|
                              ::serde_json::from_slice::<#field_type>(data.as_slice())
                              .map_err(::ruma_api::Error::from)
                              .into_future()
                    )
            }
        } else if self.response.has_body_fields() {
            quote! {
                let future_response = http_response.into_body()
                    .fold(Vec::new(), |mut vec, chunk| {
                        vec.extend(chunk.iter());
                        ::futures::future::ok::<_, ::hyper::Error>(vec)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|data|
                              ::serde_json::from_slice::<ResponseBody>(data.as_slice())
                              .map_err(::ruma_api::Error::from)
                              .into_future()
                    )
            }
        } else {
            quote! {
                let future_response = ::futures::future::ok(())
            }
        };

        let extract_response_headers = if self.response.has_header_fields() {
            quote! {
                let mut headers = http_response.headers().clone();
            }
        } else {
            TokenStream::new()
        };

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            TokenStream::new()
        };

        let serialize_response_headers = self.response.apply_header_fields();

        let serialize_response_body = if self.response.has_body() {
            let body = self.response.to_body();
            quote! {
                .body(::hyper::Body::from(::serde_json::to_vec(&#body)?))
            }
        } else {
            quote! {
                .body(::hyper::Body::from("{}".as_bytes().to_vec()))
            }
        };

        tokens.append_all(quote! {
            #[allow(unused_imports)]
            use ::futures::{Future as _Future, IntoFuture as _IntoFuture, Stream as _Stream};
            use ::ruma_api::Endpoint as _RumaApiEndpoint;
            use ::serde::Deserialize as _Deserialize;
            use ::serde::de::{Error as _SerdeError, IntoDeserializer as _IntoDeserializer};

            use ::std::convert::{TryInto as _TryInto};

            /// The API endpoint.
            #[derive(Debug)]
            pub struct Endpoint;

            #request_types

            impl ::std::convert::TryFrom<::http::Request<Vec<u8>>> for Request {
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn try_from(request: ::http::Request<Vec<u8>>) -> Result<Self, Self::Error> {
                    #extract_request_path
                    #extract_request_query
                    #extract_request_headers
                    #extract_request_body

                    Ok(Request {
                        #parse_request_path
                        #parse_request_query
                        #parse_request_headers
                        #parse_request_body
                    })
                }
            }

            impl ::futures::future::FutureFrom<::http::Request<::hyper::Body>> for Request {
                type Future = Box<_Future<Item = Self, Error = Self::Error> + Send>;
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn future_from(request: ::http::Request<::hyper::Body>) -> Self::Future {
                    let (parts, body) = request.into_parts();
                    let future = body.from_err().fold(Vec::new(), |mut vec, chunk| {
                        vec.extend(chunk.iter());
                        ::futures::future::ok::<_, Self::Error>(vec)
                    }).and_then(|body| {
                        ::http::Request::from_parts(parts, body)
                            .try_into()
                            .into_future()
                            .from_err()
                    });
                    Box::new(future)
                }
            }

            impl ::std::convert::TryFrom<Request> for ::http::Request<::hyper::Body> {
                type Error = ::ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Endpoint::METADATA;

                    // Use dummy homeserver url which has to be overwritten in
                    // the calling code. Previously (with http::Uri) this was
                    // not required, but Url::parse only accepts absolute urls.
                    let mut url = ::url::Url::parse("http://invalid-host-please-change/").unwrap();

                    { #set_request_path }
                    { #set_request_query }

                    #create_http_request

                    *http_request.method_mut() = ::http::Method::#method;
                    *http_request.uri_mut() = url.into_string().parse().unwrap();

                    { #add_headers_to_request }

                    Ok(http_request)
                }
            }

            #response_types

            impl ::std::convert::TryFrom<Response> for ::http::Response<::hyper::Body> {
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn try_from(response: Response) -> Result<Self, Self::Error> {
                    let response = ::http::Response::builder()
                        .header(::http::header::CONTENT_TYPE, "application/json")
                        #serialize_response_headers
                        #serialize_response_body
                        .unwrap();
                    Ok(response)
                }
            }

            impl ::futures::future::FutureFrom<::http::Response<::hyper::Body>> for Response {
                type Future = Box<_Future<Item = Self, Error = Self::Error> + Send>;
                type Error = ::ruma_api::Error;

                #[allow(unused_variables)]
                fn future_from(http_response: ::http::Response<::hyper::Body>) -> Self::Future {
                    if http_response.status().is_success() {
                        #extract_response_headers

                        #deserialize_response_body
                        .and_then(move |response_body| {
                            let response = Response {
                                #response_init_fields
                            };

                            Ok(response)
                        });

                        Box::new(future_response)
                    } else {
                        Box::new(::futures::future::err(::ruma_api::Error::StatusCode(http_response.status().clone())))
                    }
                }
            }

            impl ::ruma_api::Endpoint for Endpoint {
                type Request = Request;
                type Response = Response;

                const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
                    description: #description,
                    method: ::http::Method::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        });
    }
}

mod kw {
    use syn::custom_keyword;

    custom_keyword!(metadata);
    custom_keyword!(request);
    custom_keyword!(response);
}

pub struct RawApi {
    pub metadata: Vec<FieldValue>,
    pub request: Vec<Field>,
    pub response: Vec<Field>,
}

impl Parse for RawApi {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        input.parse::<kw::metadata>()?;
        let metadata;
        braced!(metadata in input);

        input.parse::<kw::request>()?;
        let request;
        braced!(request in input);

        input.parse::<kw::response>()?;
        let response;
        braced!(response in input);

        Ok(RawApi {
            metadata: metadata
                .parse_terminated::<FieldValue, Token![,]>(FieldValue::parse)?
                .into_iter()
                .collect(),
            request: request
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
            response: response
                .parse_terminated::<Field, Token![,]>(Field::parse_named)?
                .into_iter()
                .collect(),
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>Add deletes.<commit_after><|endoftext|>


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

//! Access to a single thread-local pointer.
//!
//! The runtime will use this for storing ~Task.
//!
//! XXX: Add runtime checks for usage of inconsistent pointer types.
//! and for overwriting an existing pointer.

use libc::c_void;
use cast;
use ptr;
use cell::Cell;
use option::{Option, Some, None};
use unstable::finally::Finally;
use tls = rt::thread_local_storage;

static mut RT_TLS_KEY: tls::Key = -1;

/// Initialize the TLS key. Other ops will fail if this isn't executed first.
#[fixed_stack_segment]
#[inline(never)]
pub fn init_tls_key() {
    unsafe {
        rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
        extern {
            fn rust_initialize_rt_tls_key(key: *mut tls::Key);
        }
    }
}

/// Give a pointer to thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
#[inline]
pub unsafe fn put<T>(sched: ~T) {
    let key = tls_key();
    let void_ptr: *mut c_void = cast::transmute(sched);
    tls::set(key, void_ptr);
}

/// Take ownership of a pointer from thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
#[inline]
pub unsafe fn take<T>() -> ~T {
    let key = tls_key();
    let void_ptr: *mut c_void = tls::get(key);
    if void_ptr.is_null() {
        rtabort!("thread-local pointer is null. bogus!");
    }
    let ptr: ~T = cast::transmute(void_ptr);
    tls::set(key, ptr::mut_null());
    return ptr;
}

/// Take ownership of a pointer from thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
/// Leaves the old pointer in TLS for speed.
#[inline]
pub unsafe fn unsafe_take<T>() -> ~T {
    let key = tls_key();
    let void_ptr: *mut c_void = tls::get(key);
    if void_ptr.is_null() {
        rtabort!("thread-local pointer is null. bogus!");
    }
    let ptr: ~T = cast::transmute(void_ptr);
    return ptr;
}

/// Check whether there is a thread-local pointer installed.
pub fn exists() -> bool {
    unsafe {
        match maybe_tls_key() {
            Some(key) => tls::get(key).is_not_null(),
            None => false
        }
    }
}

/// Borrow the thread-local value from thread-local storage.
/// While the value is borrowed it is not available in TLS.
///
/// # Safety note
///
/// Does not validate the pointer type.
pub unsafe fn borrow<T>(f: &fn(&mut T)) {
    let mut value = take();

    // XXX: Need a different abstraction from 'finally' here to avoid unsafety
    let unsafe_ptr = cast::transmute_mut_region(&mut *value);
    let value_cell = Cell::new(value);

    do (|| {
        f(unsafe_ptr);
    }).finally {
        put(value_cell.take());
    }
}

/// Borrow a mutable reference to the thread-local value
///
/// # Safety Note
///
/// Because this leaves the value in thread-local storage it is possible
/// For the Scheduler pointer to be aliased
pub unsafe fn unsafe_borrow<T>() -> *mut T {
    let key = tls_key();
    let mut void_ptr: *mut c_void = tls::get(key);
    if void_ptr.is_null() {
        rtabort!("thread-local pointer is null. bogus!");
    }
    let ptr: *mut *mut c_void = &mut void_ptr;
    let ptr: *mut ~T = ptr as *mut ~T;
    let ptr: *mut T = &mut **ptr;
    return ptr;
}

pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
    let key = tls_key();
    let mut void_ptr: *mut c_void = tls::get(key);
    if void_ptr.is_null() {
        return None;
    }
    {
        let ptr: *mut *mut c_void = &mut void_ptr;
        let ptr: *mut ~T = ptr as *mut ~T;
        let ptr: *mut T = &mut **ptr;
        return Some(ptr);
    }
}

#[inline]
fn tls_key() -> tls::Key {
    match maybe_tls_key() {
        Some(key) => key,
        None => rtabort!("runtime tls key not initialized")
    }
}

#[inline]
#[cfg(not(test))]
pub fn maybe_tls_key() -> Option<tls::Key> {
    unsafe {
        // NB: This is a little racy because, while the key is
        // initalized under a mutex and it's assumed to be initalized
        // in the Scheduler ctor by any thread that needs to use it,
        // we are not accessing the key under a mutex.  Threads that
        // are not using the new Scheduler but still *want to check*
        // whether they are running under a new Scheduler may see a 0
        // value here that is in the process of being initialized in
        // another thread. I think this is fine since the only action
        // they could take if it was initialized would be to check the
        // thread-local value and see that it's not set.
        if RT_TLS_KEY != -1 {
            return Some(RT_TLS_KEY);
        } else {
            return None;
        }
    }
}

// XXX: The boundary between the running runtime and the testing runtime
// seems to be fuzzy at the moment, and trying to use two different keys
// results in disaster. This should not be necessary.
#[inline]
#[cfg(test)]
pub fn maybe_tls_key() -> Option<tls::Key> {
    unsafe { ::cast::transmute(::realstd::rt::local_ptr::maybe_tls_key()) }
}
<commit_msg>rt: remove a series of unfortunate casts.<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Access to a single thread-local pointer.
//!
//! The runtime will use this for storing ~Task.
//!
//! XXX: Add runtime checks for usage of inconsistent pointer types.
//! and for overwriting an existing pointer.

use libc::c_void;
use cast;
use ptr;
use cell::Cell;
use option::{Option, Some, None};
use unstable::finally::Finally;
use tls = rt::thread_local_storage;

static mut RT_TLS_KEY: tls::Key = -1;

/// Initialize the TLS key. Other ops will fail if this isn't executed first.
#[fixed_stack_segment]
#[inline(never)]
pub fn init_tls_key() {
    unsafe {
        rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
        extern {
            fn rust_initialize_rt_tls_key(key: *mut tls::Key);
        }
    }
}

/// Give a pointer to thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
#[inline]
pub unsafe fn put<T>(sched: ~T) {
    let key = tls_key();
    let void_ptr: *mut c_void = cast::transmute(sched);
    tls::set(key, void_ptr);
}

/// Take ownership of a pointer from thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
#[inline]
pub unsafe fn take<T>() -> ~T {
    let key = tls_key();
    let void_ptr: *mut c_void = tls::get(key);
    if void_ptr.is_null() {
        rtabort!("thread-local pointer is null. bogus!");
    }
    let ptr: ~T = cast::transmute(void_ptr);
    tls::set(key, ptr::mut_null());
    return ptr;
}

/// Take ownership of a pointer from thread-local storage.
///
/// # Safety note
///
/// Does not validate the pointer type.
/// Leaves the old pointer in TLS for speed.
#[inline]
pub unsafe fn unsafe_take<T>() -> ~T {
    let key = tls_key();
    let void_ptr: *mut c_void = tls::get(key);
    if void_ptr.is_null() {
        rtabort!("thread-local pointer is null. bogus!");
    }
    let ptr: ~T = cast::transmute(void_ptr);
    return ptr;
}

/// Check whether there is a thread-local pointer installed.
pub fn exists() -> bool {
    unsafe {
        match maybe_tls_key() {
            Some(key) => tls::get(key).is_not_null(),
            None => false
        }
    }
}

/// Borrow the thread-local value from thread-local storage.
/// While the value is borrowed it is not available in TLS.
///
/// # Safety note
///
/// Does not validate the pointer type.
pub unsafe fn borrow<T>(f: &fn(&mut T)) {
    let mut value = take();

    // XXX: Need a different abstraction from 'finally' here to avoid unsafety
    let unsafe_ptr = cast::transmute_mut_region(&mut *value);
    let value_cell = Cell::new(value);

    do (|| {
        f(unsafe_ptr);
    }).finally {
        put(value_cell.take());
    }
}

/// Borrow a mutable reference to the thread-local value
///
/// # Safety Note
///
/// Because this leaves the value in thread-local storage it is possible
/// For the Scheduler pointer to be aliased
pub unsafe fn unsafe_borrow<T>() -> *mut T {
    let key = tls_key();
    let void_ptr = tls::get(key);
    if void_ptr.is_null() {
        rtabort!("thread-local pointer is null. bogus!");
    }
    void_ptr as *mut T
}

pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
    let key = tls_key();
    let void_ptr = tls::get(key);
    if void_ptr.is_null() {
        None
    } else {
        Some(void_ptr as *mut T)
    }
}

#[inline]
fn tls_key() -> tls::Key {
    match maybe_tls_key() {
        Some(key) => key,
        None => rtabort!("runtime tls key not initialized")
    }
}

#[inline]
#[cfg(not(test))]
pub fn maybe_tls_key() -> Option<tls::Key> {
    unsafe {
        // NB: This is a little racy because, while the key is
        // initalized under a mutex and it's assumed to be initalized
        // in the Scheduler ctor by any thread that needs to use it,
        // we are not accessing the key under a mutex.  Threads that
        // are not using the new Scheduler but still *want to check*
        // whether they are running under a new Scheduler may see a 0
        // value here that is in the process of being initialized in
        // another thread. I think this is fine since the only action
        // they could take if it was initialized would be to check the
        // thread-local value and see that it's not set.
        if RT_TLS_KEY != -1 {
            return Some(RT_TLS_KEY);
        } else {
            return None;
        }
    }
}

// XXX: The boundary between the running runtime and the testing runtime
// seems to be fuzzy at the moment, and trying to use two different keys
// results in disaster. This should not be necessary.
#[inline]
#[cfg(test)]
pub fn maybe_tls_key() -> Option<tls::Key> {
    unsafe { ::cast::transmute(::realstd::rt::local_ptr::maybe_tls_key()) }
}
<|endoftext|>


<commit_before><commit_msg>Add tests/complex.rs<commit_after>
extern crate num;
extern crate ndarray;

use ndarray::{arr1, arr2};
use num::Complex;

fn c<T: Clone + Num>(re: T, im: T) -> Complex<T> {
    Complex::new(re, im)
}

#[test]
fn complex_mat_mul()
{
    let a = arr2([[c::<f32>(1., 1.), c(2., 0.)], [c(0., -2.), c(3., 0.)]]);
    let e = ndarray::linalg::eye(2);
    let r = a.mat_mul(&e);
    println!("{}", a);
    assert_eq!(r, a);
    assert_eq!(a.mean(0), arr1([c(0.5, -0.5), c(2.5, 0.)]));
}
<|endoftext|>


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

//! An efficient, low-level, bindless graphics API for Rust. See [the
//! blog](http://gfx-rs.github.io/) for explanations and annotated examples.

#![feature(core, libc)]

#[macro_use]
extern crate log;
extern crate libc;

extern crate "gfx_device_gl" as device;

// public re-exports
pub use render::{DeviceHelper, ProgramError, Renderer, DrawError};
pub use render::batch;
pub use render::mesh::{Attribute, Mesh, VertexFormat};
pub use render::mesh::{Slice, ToSlice};
pub use render::mesh::SliceKind;
pub use render::state::{BlendPreset, DrawState};
pub use render::shade;
pub use render::target::{Frame, Plane};
pub use device::Device;
pub use device::{attrib, state, tex};
pub use device::as_byte_slice;
pub use device::{BufferHandle, BufferInfo, RawBufferHandle, ShaderHandle};
pub use device::{ProgramHandle, SurfaceHandle, TextureHandle};
pub use device::BufferUsage;
pub use device::{VertexCount, InstanceCount};
pub use device::PrimitiveType;
pub use device::draw::CommandBuffer;
pub use device::shade::UniformValue;
pub use device::shade::{ShaderSource, ProgramInfo};
pub use device::target::{ColorValue, ClearData, Mask, Layer, Level, Rect, Target};
pub use device::target::{COLOR, DEPTH, STENCIL};

// TODO: Remove this re-export once `gl_device` becomes a separate crate.
pub use device::gl_device::{GlDevice, GlCommandBuffer};

#[path = "../render/lib.rs"] pub mod render;

/// A convenient wrapper suitable for single-threaded operation.
pub struct Graphics<D: device::Device> {
    /// Graphics device.
    pub device: D,
    /// Renderer front-end.
    pub renderer: Renderer<<D as device::Device>::CommandBuffer>,
    /// Hidden batch context.
    context: batch::Context,
}

impl<D: device::Device> Graphics<D> {
    /// Create a new graphics wrapper.
    pub fn new(mut device: D) -> Graphics<D> {
        let rend = device.create_renderer();
        Graphics {
            device: device,
            renderer: rend,
            context: batch::Context::new(),
        }
    }

    /// Create a new ref batch.
    pub fn make_batch<T: shade::ShaderParam>(&mut self,
                      program: &ProgramHandle,
                      mesh: &Mesh,
                      slice: Slice,
                      state: &DrawState)
                      -> Result<batch::RefBatch<T>, batch::BatchError> {
        self.context.make_batch(program, mesh, slice, state)
    }

    /// Clear the `Frame` as the `ClearData` specifies.
    pub fn clear(&mut self, data: ClearData, mask: Mask, frame: &Frame) {
        self.renderer.clear(data, mask, frame)
    }

    /// Draw a ref batch.
    pub fn draw<'a, T: shade::ShaderParam>(&'a mut self,
                batch: &'a batch::RefBatch<T>, data: &'a T, frame: &Frame)
                -> Result<(), DrawError> {
        self.renderer.draw(&(batch, data, &self.context), frame)
    }

    /// Submit the internal command buffer and reset for the next frame.
    pub fn end_frame(&mut self) {
        self.device.submit(self.renderer.as_buffer());
        self.renderer.reset();
    }
}
<commit_msg>Re-export some missing types<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An efficient, low-level, bindless graphics API for Rust. See [the
//! blog](http://gfx-rs.github.io/) for explanations and annotated examples.

#![feature(core, libc)]

#[macro_use]
extern crate log;
extern crate libc;

extern crate "gfx_device_gl" as device;

// public re-exports
pub use render::{DeviceHelper, ProgramError, Renderer, DrawError};
pub use render::batch;
pub use render::mesh::{Attribute, Mesh, VertexFormat};
pub use render::mesh::{Slice, ToSlice};
pub use render::mesh::SliceKind;
pub use render::state::{BlendPreset, DrawState};
pub use render::shade;
pub use render::target::{Frame, Plane};
pub use device::Device;
pub use device::{attrib, state, tex};
pub use device::as_byte_slice;
pub use device::{BufferHandle, BufferInfo, RawBufferHandle, ShaderHandle};
pub use device::{ProgramHandle, SurfaceHandle, TextureHandle};
pub use device::BufferUsage;
pub use device::{VertexCount, InstanceCount};
pub use device::PrimitiveType;
pub use device::draw::CommandBuffer;
pub use device::shade::UniformValue;
pub use device::shade::{ShaderSource, ProgramInfo};
pub use device::target::*;

// TODO: Remove this re-export once `gl_device` becomes a separate crate.
pub use device::gl_device::{GlDevice, GlCommandBuffer};

#[path = "../render/lib.rs"] pub mod render;

/// A convenient wrapper suitable for single-threaded operation.
pub struct Graphics<D: device::Device> {
    /// Graphics device.
    pub device: D,
    /// Renderer front-end.
    pub renderer: Renderer<<D as device::Device>::CommandBuffer>,
    /// Hidden batch context.
    context: batch::Context,
}

impl<D: device::Device> Graphics<D> {
    /// Create a new graphics wrapper.
    pub fn new(mut device: D) -> Graphics<D> {
        let rend = device.create_renderer();
        Graphics {
            device: device,
            renderer: rend,
            context: batch::Context::new(),
        }
    }

    /// Create a new ref batch.
    pub fn make_batch<T: shade::ShaderParam>(&mut self,
                      program: &ProgramHandle,
                      mesh: &Mesh,
                      slice: Slice,
                      state: &DrawState)
                      -> Result<batch::RefBatch<T>, batch::BatchError> {
        self.context.make_batch(program, mesh, slice, state)
    }

    /// Clear the `Frame` as the `ClearData` specifies.
    pub fn clear(&mut self, data: ClearData, mask: Mask, frame: &Frame) {
        self.renderer.clear(data, mask, frame)
    }

    /// Draw a ref batch.
    pub fn draw<'a, T: shade::ShaderParam>(&'a mut self,
                batch: &'a batch::RefBatch<T>, data: &'a T, frame: &Frame)
                -> Result<(), DrawError> {
        self.renderer.draw(&(batch, data, &self.context), frame)
    }

    /// Submit the internal command buffer and reset for the next frame.
    pub fn end_frame(&mut self) {
        self.device.submit(self.renderer.as_buffer());
        self.renderer.reset();
    }
}
<|endoftext|>


<commit_before><commit_msg>test that 0 cannot be offset-inbounds by 0<commit_after>// error-pattern: outside bounds of allocation

fn main() {
    let x = 0 as *mut i32;
    let _x = x.wrapping_offset(8); // ok, this has no inbounds tag
    let _x = unsafe { x.offset(0) }; // UB despite offset 0, NULL is never inbounds
}
<|endoftext|>


<commit_before>use std::{cmp, fmt};
use std::cell::RefCell;
use std::os::unix::io::RawFd;
use std::collections::HashMap;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::Duration;

use libc::{self, time_t};

use {io, Ready, PollOpt, Token};
use event::{self, Event};
use sys::unix::cvt;
use sys::unix::io::set_cloexec;

/// Each Selector has a globally unique(ish) ID associated with it. This ID
/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
/// registered with the `Selector`. If a type that is previously associated with
/// a `Selector` attempts to register itself with a different `Selector`, the
/// operation will return with an error. This matches windows behavior.
static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

pub struct Selector {
    id: usize,
    kq: RawFd,
    changes: RefCell<KeventList>,
}

impl Selector {
    pub fn new() -> io::Result<Selector> {
        // offset by 1 to avoid choosing 0 as the id of a selector
        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
        let kq = unsafe { try!(cvt(libc::kqueue())) };
        drop(set_cloexec(kq));

        Ok(Selector {
            id: id,
            kq: kq,
            changes: RefCell::new(KeventList(Vec::new())),
        })
    }

    pub fn id(&self) -> usize {
        self.id
    }

    pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> {
        let timeout = timeout.map(|to| {
            libc::timespec {
                tv_sec: cmp::min(to.as_secs(), time_t::max_value() as u64) as time_t,
                tv_nsec: to.subsec_nanos() as libc::c_long,
            }
        });
        let timeout = timeout.as_ref().map(|s| s as *const _).unwrap_or(0 as *const _);

        unsafe {
            let cnt = try!(cvt(libc::kevent(self.kq,
                                            0 as *const _,
                                            0,
                                            evts.sys_events.0.as_mut_ptr(),
                                            evts.sys_events.0.capacity() as i32,
                                            timeout)));

            self.changes.borrow_mut().0.clear();
            evts.sys_events.0.set_len(cnt as usize);

            Ok(evts.coalesce(awakener))
        }
    }

    pub fn register(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        trace!("registering; token={:?}; interests={:?}", token, interests);

        self.ev_register(fd,
                         token.into(),
                         libc::EVFILT_READ,
                         interests.contains(Ready::readable()),
                         opts);
        self.ev_register(fd,
                         token.into(),
                         libc::EVFILT_WRITE,
                         interests.contains(Ready::writable()),
                         opts);

        self.flush_changes()
    }

    pub fn reregister(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        // Just need to call register here since EV_ADD is a mod if already
        // registered
        self.register(fd, token, interests, opts)
    }

    pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
        self.ev_push(fd, 0, libc::EVFILT_READ, libc::EV_DELETE);
        self.ev_push(fd, 0, libc::EVFILT_WRITE, libc::EV_DELETE);

        self.flush_changes()
    }

    fn ev_register(&self,
                   fd: RawFd,
                   token: usize,
                   filter: i16,
                   enable: bool,
                   opts: PollOpt) {
        let mut flags = libc::EV_ADD;

        if enable {
            flags = flags | libc::EV_ENABLE;
        } else {
            flags = flags | libc::EV_DISABLE;
        }

        if opts.contains(PollOpt::edge()) {
            flags = flags | libc::EV_CLEAR;
        }

        if opts.contains(PollOpt::oneshot()) {
            flags = flags | libc::EV_ONESHOT;
        }

        self.ev_push(fd, token, filter, flags);
    }

    fn ev_push(&self,
               fd: RawFd,
               token: usize,
               filter: i16,
               flags: u16) {
        self.changes.borrow_mut().0.push(libc::kevent {
            ident: fd as ::libc::uintptr_t,
            filter: filter,
            flags: flags,
            fflags: 0,
            data: 0,
            udata: token as *mut _,
        });
    }

    fn flush_changes(&self) -> io::Result<()> {
        unsafe {
            let mut changes = self.changes.borrow_mut();
            try!(cvt(libc::kevent(self.kq,
                                  changes.0.as_mut_ptr() as *const _,
                                  changes.0.len() as i32,
                                  0 as *mut _,
                                  0,
                                  0 as *const _)));
            changes.0.clear();
            Ok(())
        }
    }
}

impl fmt::Debug for Selector {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Selector")
            .field("id", &self.id)
            .field("kq", &self.kq)
            .field("changes", &self.changes.borrow().0.len())
            .finish()
    }
}

impl Drop for Selector {
    fn drop(&mut self) {
        unsafe {
            let _ = libc::close(self.kq);
        }
    }
}

pub struct Events {
    sys_events: KeventList,
    events: Vec<Event>,
    event_map: HashMap<Token, usize>,
}

struct KeventList(Vec<libc::kevent>);

unsafe impl Send for KeventList {}
unsafe impl Sync for KeventList {}

impl Events {
    pub fn with_capacity(cap: usize) -> Events {
        Events {
            sys_events: KeventList(Vec::with_capacity(cap)),
            events: Vec::with_capacity(cap),
            event_map: HashMap::with_capacity(cap)
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.events.len()
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.events.is_empty()
    }

    pub fn get(&self, idx: usize) -> Option<Event> {
        self.events.get(idx).map(|e| *e)
    }

    fn coalesce(&mut self, awakener: Token) -> bool {
        let mut ret = false;
        self.events.clear();
        self.event_map.clear();

        for e in self.sys_events.0.iter() {
            let token = Token(e.udata as usize);
            let len = self.events.len();

            if token == awakener {
                // TODO: Should this return an error if event is an error. It
                // is not critical as spurious wakeups are permitted.
                ret = true;
                continue;
            }

            let idx = *self.event_map.entry(token)
                .or_insert(len);

            if idx == len {
                // New entry, insert the default
                self.events.push(Event::new(Ready::none(), token));

            }

            if e.flags & libc::EV_ERROR != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::error());
            }

            if e.filter == libc::EVFILT_READ {
                event::kind_mut(&mut self.events[idx]).insert(Ready::readable());
            } else if e.filter == libc::EVFILT_WRITE {
                event::kind_mut(&mut self.events[idx]).insert(Ready::writable());
            }

            if e.flags & libc::EV_EOF != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::hup());

                // When the read end of the socket is closed, EV_EOF is set on
                // flags, and fflags contains the error if there is one.
                if e.fflags != 0 {
                    event::kind_mut(&mut self.events[idx]).insert(Ready::error());
                }
            }
        }

        ret
    }

    pub fn push_event(&mut self, event: Event) {
        self.events.push(event);
    }
}

impl fmt::Debug for Events {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "Events {{ len: {} }}", self.sys_events.0.len())
    }
}
<commit_msg>Do not kevent fds with EV_DISABLE when no interest<commit_after>use std::{cmp, fmt, ptr};
use std::cell::RefCell;
use std::os::raw::c_int;
use std::os::unix::io::RawFd;
use std::collections::HashMap;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::Duration;

use libc::{self, time_t};

use {io, Ready, PollOpt, Token};
use event::{self, Event};
use sys::unix::cvt;
use sys::unix::io::set_cloexec;

/// Each Selector has a globally unique(ish) ID associated with it. This ID
/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
/// registered with the `Selector`. If a type that is previously associated with
/// a `Selector` attempts to register itself with a different `Selector`, the
/// operation will return with an error. This matches windows behavior.
static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

pub struct Selector {
    id: usize,
    kq: RawFd,
    changes: RefCell<KeventList>,
}

impl Selector {
    pub fn new() -> io::Result<Selector> {
        // offset by 1 to avoid choosing 0 as the id of a selector
        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
        let kq = unsafe { try!(cvt(libc::kqueue())) };
        drop(set_cloexec(kq));

        Ok(Selector {
            id: id,
            kq: kq,
            changes: RefCell::new(KeventList(Vec::new())),
        })
    }

    pub fn id(&self) -> usize {
        self.id
    }

    pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> {
        let timeout = timeout.map(|to| {
            libc::timespec {
                tv_sec: cmp::min(to.as_secs(), time_t::max_value() as u64) as time_t,
                tv_nsec: to.subsec_nanos() as libc::c_long,
            }
        });
        let timeout = timeout.as_ref().map(|s| s as *const _).unwrap_or(0 as *const _);

        unsafe {
            let cnt = try!(cvt(libc::kevent(self.kq,
                                            0 as *const _,
                                            0,
                                            evts.sys_events.0.as_mut_ptr(),
                                            evts.sys_events.0.capacity() as i32,
                                            timeout)));

            self.changes.borrow_mut().0.clear();
            evts.sys_events.0.set_len(cnt as usize);

            Ok(evts.coalesce(awakener))
        }
    }

    pub fn register(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        trace!("registering; token={:?}; interests={:?}", token, interests);

        if interests.contains(Ready::readable()) {
            self.ev_register(fd,
                             token.into(),
                             libc::EVFILT_READ,
                             opts);
        }
        if interests.contains(Ready::writable()) {
            self.ev_register(fd,
                             token.into(),
                             libc::EVFILT_WRITE,
                             opts);
        }

        self.flush_changes()
    }

    pub fn reregister(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
        // Just need to call register here since EV_ADD is a mod if already
        // registered
        self.register(fd, token, interests, opts)
    }

    pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
        self.ev_push(fd, 0, libc::EVFILT_READ, libc::EV_DELETE);
        self.ev_push(fd, 0, libc::EVFILT_WRITE, libc::EV_DELETE);

        self.flush_changes()
    }

    fn ev_register(&self,
                   fd: RawFd,
                   token: usize,
                   filter: i16,
                   opts: PollOpt) {
        let mut flags = libc::EV_ADD;

        if opts.contains(PollOpt::edge()) {
            flags = flags | libc::EV_CLEAR;
        }

        if opts.contains(PollOpt::oneshot()) {
            flags = flags | libc::EV_ONESHOT;
        }

        self.ev_push(fd, token, filter, flags);
    }

    fn ev_push(&self,
               fd: RawFd,
               token: usize,
               filter: i16,
               flags: u16) {
        self.changes.borrow_mut().0.push(libc::kevent {
            ident: fd as ::libc::uintptr_t,
            filter: filter,
            flags: flags,
            fflags: 0,
            data: 0,
            udata: token as *mut _,
        });
    }

    fn flush_changes(&self) -> io::Result<()> {
        unsafe {
            let mut changes = self.changes.borrow_mut();
            try!(cvt(libc::kevent(self.kq,
                                  changes.0.as_mut_ptr() as *const _,
                                  changes.0.len() as i32,
                                  0 as *mut _,
                                  0,
                                  0 as *const _)));
            changes.0.clear();
            Ok(())
        }
    }
}

impl fmt::Debug for Selector {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Selector")
            .field("id", &self.id)
            .field("kq", &self.kq)
            .field("changes", &self.changes.borrow().0.len())
            .finish()
    }
}

impl Drop for Selector {
    fn drop(&mut self) {
        unsafe {
            let _ = libc::close(self.kq);
        }
    }
}

pub struct Events {
    sys_events: KeventList,
    events: Vec<Event>,
    event_map: HashMap<Token, usize>,
}

struct KeventList(Vec<libc::kevent>);

unsafe impl Send for KeventList {}
unsafe impl Sync for KeventList {}

impl Events {
    pub fn with_capacity(cap: usize) -> Events {
        Events {
            sys_events: KeventList(Vec::with_capacity(cap)),
            events: Vec::with_capacity(cap),
            event_map: HashMap::with_capacity(cap)
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.events.len()
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.events.is_empty()
    }

    pub fn get(&self, idx: usize) -> Option<Event> {
        self.events.get(idx).map(|e| *e)
    }

    fn coalesce(&mut self, awakener: Token) -> bool {
        let mut ret = false;
        self.events.clear();
        self.event_map.clear();

        for e in self.sys_events.0.iter() {
            let token = Token(e.udata as usize);
            let len = self.events.len();

            if token == awakener {
                // TODO: Should this return an error if event is an error. It
                // is not critical as spurious wakeups are permitted.
                ret = true;
                continue;
            }

            let idx = *self.event_map.entry(token)
                .or_insert(len);

            if idx == len {
                // New entry, insert the default
                self.events.push(Event::new(Ready::none(), token));

            }

            if e.flags & libc::EV_ERROR != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::error());
            }

            if e.filter == libc::EVFILT_READ {
                event::kind_mut(&mut self.events[idx]).insert(Ready::readable());
            } else if e.filter == libc::EVFILT_WRITE {
                event::kind_mut(&mut self.events[idx]).insert(Ready::writable());
            }

            if e.flags & libc::EV_EOF != 0 {
                event::kind_mut(&mut self.events[idx]).insert(Ready::hup());

                // When the read end of the socket is closed, EV_EOF is set on
                // flags, and fflags contains the error if there is one.
                if e.fflags != 0 {
                    event::kind_mut(&mut self.events[idx]).insert(Ready::error());
                }
            }
        }

        ret
    }

    pub fn push_event(&mut self, event: Event) {
        self.events.push(event);
    }
}

impl fmt::Debug for Events {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "Events {{ len: {} }}", self.sys_events.0.len())
    }
}
<|endoftext|>


<commit_before><commit_msg>Add parameters to SessionState::handle_connect<commit_after><|endoftext|>


<commit_before>use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::vec::Vec;
use std::io;
use std::env;
use std::collections::HashMap;

struct Tape {
  pos: usize,
  tape: Vec<isize>
}

impl Tape {
  fn new() -> Tape { Tape { pos: 0, tape: vec![0] } }
  fn get(&self) -> isize { self.tape[self.pos] }
  fn getc(&self) -> char { self.get() as u8 as char }
  fn inc(&mut self) { let x = self.tape.get_mut(self.pos); *x.unwrap() += 1; }
  fn dec(&mut self) { let x = self.tape.get_mut(self.pos); *x.unwrap() -= 1; }
  fn advance(&mut self) { self.pos += 1; if self.tape.len() <= self.pos { self.tape.push(0) } }
  fn devance(&mut self) { if self.pos > 0 { self.pos -= 1; } }
}

struct Program {
  code: Vec<char>,
  bracket_map: HashMap<usize, usize>
}

impl Program {
  fn new(content: String) -> Program {
    let mut code: Vec<char> = Vec::new();
    let mut bracket_map = HashMap::new();
    let mut leftstack = Vec::new();
    let mut pc = 0;

    for c in content.chars() {
      match c {
        '+' | '-' | '.' | ',' | '<' | '>' => (),
        '[' => { leftstack.push(pc); },
        ']' => match leftstack.pop() {
          Some(left) => { bracket_map.insert(left, pc); bracket_map.insert(pc, left); }
          None => ()
        },
        _ => { continue; }
      }
      code.push(c);
      pc += 1;
    }
    Program{ code: code, bracket_map: bracket_map }
  }

  fn run(&self) {
    let mut pc: usize = 0;
    let len = self.code.len();
    let mut tape = Tape::new();

    while pc < len {
      match self.code[pc] {
        '+' => tape.inc(),
        '-' => tape.dec(),
        '>' => tape.advance(),
        '<' => tape.devance(),
        '[' => { if tape.get() == 0 { pc = self.bracket_map[&pc]; } },
        ']' => { if tape.get() != 0 { pc = self.bracket_map[&pc]; } },
        '.' => { print!("{}", tape.getc()); io::stdout().flush().unwrap() },
        _ => ()
      }
      pc += 1;
    }
  }
}

fn main() {
  let arg1 = env::args().nth(1).unwrap();
  let path = Path::new(&arg1);
  let mut s = String::new();
  let mut file = File::open(&path).unwrap();
  file.read_to_string(&mut s).unwrap();
  Program::new(s).run()
}
<commit_msg>simplify brainfuck rust<commit_after>use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::vec::Vec;
use std::io;
use std::env;
use std::collections::HashMap;

struct Tape {
  pos: usize,
  tape: Vec<isize>
}

impl Tape {
  fn new() -> Tape { Tape { pos: 0, tape: vec![0] } }
  fn get(&self) -> isize { self.tape[self.pos] }
  fn getc(&self) -> char { self.get() as u8 as char }
  fn inc(&mut self) { self.tape[self.pos] += 1; }
  fn dec(&mut self) { self.tape[self.pos] -= 1; }
  fn advance(&mut self) { self.pos += 1; if self.tape.len() <= self.pos { self.tape.push(0) } }
  fn devance(&mut self) { if self.pos > 0 { self.pos -= 1; } }
}

struct Program {
  code: Vec<char>,
  bracket_map: HashMap<usize, usize>
}

impl Program {
  fn new(content: String) -> Program {
    let mut code: Vec<char> = Vec::new();
    let mut bracket_map = HashMap::new();
    let mut leftstack = Vec::new();
    let mut pc = 0;

    for c in content.chars() {
      match c {
        '+' | '-' | '.' | ',' | '<' | '>' => (),
        '[' => { leftstack.push(pc); },
        ']' => match leftstack.pop() {
          Some(left) => { bracket_map.insert(left, pc); bracket_map.insert(pc, left); }
          None => ()
        },
        _ => { continue; }
      }
      code.push(c);
      pc += 1;
    }
    Program{ code: code, bracket_map: bracket_map }
  }

  fn run(&self) {
    let mut pc: usize = 0;
    let len = self.code.len();
    let mut tape = Tape::new();

    while pc < len {
      match self.code[pc] {
        '+' => tape.inc(),
        '-' => tape.dec(),
        '>' => tape.advance(),
        '<' => tape.devance(),
        '[' => { if tape.get() == 0 { pc = self.bracket_map[&pc]; } },
        ']' => { if tape.get() != 0 { pc = self.bracket_map[&pc]; } },
        '.' => { print!("{}", tape.getc()); io::stdout().flush().unwrap() },
        _ => ()
      }
      pc += 1;
    }
  }
}

fn main() {
  let arg1 = env::args().nth(1).unwrap();
  let path = Path::new(&arg1);
  let mut s = String::new();
  let mut file = File::open(&path).unwrap();
  file.read_to_string(&mut s).unwrap();
  Program::new(s).run()
}
<|endoftext|>


<commit_before><commit_msg>Check for the SPIR-V disassembler before trying to run it<commit_after><|endoftext|>


<commit_before><commit_msg>Start parsing/displaying window info for drawing<commit_after><|endoftext|>


<commit_before><commit_msg>Fix line shift<commit_after><|endoftext|>


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

// Regression test for #52057. There is an implied bound
// that `I: 'a` where `'a` is the lifetime of `self` in `parse_first`;
// but to observe that, one must normalize first.
//
// run-pass

#![feature(nll)]

pub trait Parser {
    type Input;

    #[inline(always)]
    fn parse_first(input: &mut Self::Input);
}

impl<'a, I, P: ?Sized> Parser for &'a mut P
where
    P: Parser<Input = I>,
{
    type Input = I;

    fn parse_first(_: &mut Self::Input) {}
}

fn main() {}
<|endoftext|>


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

use syntax::ast;
use syntax::ptr::P;
use syntax::ext::base::ExtCtxt;
use syntax::codemap::DUMMY_SP;
use syntax::ext::build::AstBuilder;
use syntax::ext::quote::rt::ToTokens;
use syntax::parse::token;

use super::Builder;
use super::super::node;
use super::utils;

/// A visitor to build the field setters for primitive registers
pub struct BuildGetters<'a> {
  builder: &'a mut Builder,
  cx: &'a ExtCtxt<'a>,
}

impl<'a> BuildGetters<'a> {
  pub fn new(builder: &'a mut Builder, cx: &'a ExtCtxt<'a>)
      -> BuildGetters<'a> {
    BuildGetters { builder: builder, cx: cx }
  }
}

impl<'a> node::RegVisitor for BuildGetters<'a> {
  fn visit_prim_reg(&mut self, path: &Vec<String>,
                    reg: &node::Reg, _width: node::RegWidth,
                    fields: &Vec<node::Field>) {
    if fields.iter().any(|f| f.access != node::Access::WriteOnly) {
      let it = build_type(self.cx, path, reg);
      self.builder.push_item(it);

      let it = build_impl(self.cx, path, reg, fields);
      self.builder.push_item(it);
    }
  }
}

fn build_type(cx: &ExtCtxt, path: &Vec<String>,
              reg: &node::Reg) -> P<ast::Item>
{
  let packed_ty = utils::reg_primitive_type(cx, reg)
    .expect("Unexpected non-primitive register");
  let name = utils::getter_name(cx, path);
  let reg_doc = match reg.docstring {
    Some(d) => token::get_ident(d.node).get().into_string(),
    None => "no documentation".into_string(),
  };
  let docstring = format!("`{}`: {}", reg.name.node, reg_doc);
  let doc_attr = utils::doc_attribute(cx, utils::intern_string(cx, docstring));

  let item = quote_item!(cx,
    $doc_attr
    #[allow(non_camel_case_types)]
    pub struct $name {
      value: $packed_ty,
    }
  );
  let mut item: ast::Item = item.unwrap().deref().clone();
  item.span = reg.name.span;
  P(item)
}

fn build_new(cx: &ExtCtxt, path: &Vec<String>) -> P<ast::Item> {
  let reg_ty: P<ast::Ty> =
    cx.ty_ident(DUMMY_SP, utils::path_ident(cx, path));
  let getter_ty: P<ast::Ty> = cx.ty_ident(DUMMY_SP,
                                          utils::getter_name(cx, path));
  let item = quote_item!(cx,
    #[doc = "Create a getter reflecting the current value of the given register."]
    pub fn new(reg: & $reg_ty) -> $getter_ty {
      $getter_ty {
        value: reg.value.get(),
      }
    }
    );
  item.unwrap()
}

/// Given an `Expr` of the given register's primitive type, return
/// an `Expr` of the field type
fn from_primitive(cx: &ExtCtxt, reg: &node::Reg,
                  field: &node::Field, prim: P<ast::Expr>)
                  -> P<ast::Expr> {
  match field.ty.node {
    node::FieldType::UIntField => prim,
    node::FieldType::BoolField =>
      cx.expr_binary(DUMMY_SP, ast::BiNe,
                     prim, utils::expr_int(cx, 0)),
    node::FieldType::EnumField {..} => {
      let from = match reg.ty {
        node::RegType::RegPrim(width,_) =>
          match width {
            node::RegWidth::Reg32 => "from_u32",
            node::RegWidth::Reg16 => "from_u16",
            node::RegWidth::Reg8  => "from_u8",
          },
        _ => panic!("Can't convert group register to primitive type"),
      };
      cx.expr_method_call(
        DUMMY_SP,
        cx.expr_call_global(
          DUMMY_SP,
          vec!(cx.ident_of("core"),
               cx.ident_of("num"),
               cx.ident_of(from)),
          vec!(prim)
        ),
        cx.ident_of("unwrap"),
        Vec::new()
      )
    },
  }
}

fn build_impl(cx: &ExtCtxt, path: &Vec<String>, reg: &node::Reg,
              fields: &Vec<node::Field>) -> P<ast::Item> {
  let getter_ty = utils::getter_name(cx, path);
  let new = build_new(cx, path);
  let getters: Vec<P<ast::Method>> =
    FromIterator::from_iter(
      fields.iter()
        .map(|field| build_field_get_fn(cx, path, reg, field)));

  let it = quote_item!(cx,
    #[allow(dead_code)]
    impl $getter_ty {
      $new
      $getters
    }
  );
  it.unwrap()
}

/// Build a getter for a field
fn build_field_get_fn(cx: &ExtCtxt, path: &Vec<String>, reg: &node::Reg,
                      field: &node::Field) -> P<ast::Method>
{
  let fn_name = cx.ident_of(field.name.node.as_slice());
  let field_ty: P<ast::Ty> =
    cx.ty_path(utils::field_type_path(cx, path, reg, field), None);
  let mask = utils::mask(cx, field);
  let field_doc = match field.docstring {
    Some(d) => d.node,
    None => cx.ident_of("no documentation"),
  };
  let docstring = format!("Get value of `{}` field: {}",
                          field.name.node,
                          token::get_ident(field_doc).get());
  let doc_attr = utils::doc_attribute(cx, utils::intern_string(cx, docstring));

  if field.count.node == 1 {
    let shift = utils::shift(cx, None, field);
    let value = from_primitive(
      cx, reg, field,
      quote_expr!(cx, (self.value >> $shift) & $mask));
    quote_method!(cx,
      $doc_attr
      pub fn $fn_name(&self) -> $field_ty {
        $value
      }
    )
  } else {
    let shift = utils::shift(cx, Some(quote_expr!(cx, idx)), field);
    let value = from_primitive(
      cx, reg, field,
      quote_expr!(cx, (self.value >> $shift) & $mask));
    quote_method!(cx,
      $doc_attr
      pub fn $fn_name(&self, idx: uint) -> $field_ty {
        $value
      }
    )
  }
}
<commit_msg>ioreg: Add raw() function to Getter<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Ben Gamari <bgamari@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use syntax::ast;
use syntax::ptr::P;
use syntax::ext::base::ExtCtxt;
use syntax::codemap::DUMMY_SP;
use syntax::ext::build::AstBuilder;
use syntax::ext::quote::rt::ToTokens;
use syntax::parse::token;

use super::Builder;
use super::super::node;
use super::utils;

/// A visitor to build the field setters for primitive registers
pub struct BuildGetters<'a> {
  builder: &'a mut Builder,
  cx: &'a ExtCtxt<'a>,
}

impl<'a> BuildGetters<'a> {
  pub fn new(builder: &'a mut Builder, cx: &'a ExtCtxt<'a>)
      -> BuildGetters<'a> {
    BuildGetters { builder: builder, cx: cx }
  }
}

impl<'a> node::RegVisitor for BuildGetters<'a> {
  fn visit_prim_reg(&mut self, path: &Vec<String>,
                    reg: &node::Reg, _width: node::RegWidth,
                    fields: &Vec<node::Field>) {
    if fields.iter().any(|f| f.access != node::Access::WriteOnly) {
      let it = build_type(self.cx, path, reg);
      self.builder.push_item(it);

      let it = build_impl(self.cx, path, reg, fields);
      self.builder.push_item(it);
    }
  }
}

fn build_type(cx: &ExtCtxt, path: &Vec<String>,
              reg: &node::Reg) -> P<ast::Item>
{
  let packed_ty = utils::reg_primitive_type(cx, reg)
    .expect("Unexpected non-primitive register");
  let name = utils::getter_name(cx, path);
  let reg_doc = match reg.docstring {
    Some(d) => token::get_ident(d.node).get().into_string(),
    None => "no documentation".into_string(),
  };
  let docstring = format!("`{}`: {}", reg.name.node, reg_doc);
  let doc_attr = utils::doc_attribute(cx, utils::intern_string(cx, docstring));

  let item = quote_item!(cx,
    $doc_attr
    #[allow(non_camel_case_types)]
    pub struct $name {
      value: $packed_ty,
    }
  );
  let mut item: ast::Item = item.unwrap().deref().clone();
  item.span = reg.name.span;
  P(item)
}

fn build_new(cx: &ExtCtxt, path: &Vec<String>) -> P<ast::Item> {
  let reg_ty: P<ast::Ty> =
    cx.ty_ident(DUMMY_SP, utils::path_ident(cx, path));
  let getter_ty: P<ast::Ty> = cx.ty_ident(DUMMY_SP,
                                          utils::getter_name(cx, path));
  let item = quote_item!(cx,
    #[doc = "Create a getter reflecting the current value of the given register."]
    pub fn new(reg: & $reg_ty) -> $getter_ty {
      $getter_ty {
        value: reg.value.get(),
      }
    }
    );
  item.unwrap()
}

/// Given an `Expr` of the given register's primitive type, return
/// an `Expr` of the field type
fn from_primitive(cx: &ExtCtxt, reg: &node::Reg,
                  field: &node::Field, prim: P<ast::Expr>)
                  -> P<ast::Expr> {
  match field.ty.node {
    node::FieldType::UIntField => prim,
    node::FieldType::BoolField =>
      cx.expr_binary(DUMMY_SP, ast::BiNe,
                     prim, utils::expr_int(cx, 0)),
    node::FieldType::EnumField {..} => {
      let from = match reg.ty {
        node::RegType::RegPrim(width,_) =>
          match width {
            node::RegWidth::Reg32 => "from_u32",
            node::RegWidth::Reg16 => "from_u16",
            node::RegWidth::Reg8  => "from_u8",
          },
        _ => panic!("Can't convert group register to primitive type"),
      };
      cx.expr_method_call(
        DUMMY_SP,
        cx.expr_call_global(
          DUMMY_SP,
          vec!(cx.ident_of("core"),
               cx.ident_of("num"),
               cx.ident_of(from)),
          vec!(prim)
        ),
        cx.ident_of("unwrap"),
        Vec::new()
      )
    },
  }
}

fn build_impl(cx: &ExtCtxt, path: &Vec<String>, reg: &node::Reg,
              fields: &Vec<node::Field>) -> P<ast::Item> {
  let getter_ty = utils::getter_name(cx, path);
  let new = build_new(cx, path);
  let getters: Vec<P<ast::Method>> =
    FromIterator::from_iter(
      fields.iter()
        .map(|field| build_field_get_fn(cx, path, reg, field)));

  let packed_ty = utils::reg_primitive_type(cx, reg)
    .expect("Unexpected non-primitive register");
  let get_raw: P<ast::Method> = quote_method!(cx,
    #[doc = "Get the raw value of the register."]
    pub fn raw(&self) -> $packed_ty {
      self.value
    }
  );

  let it = quote_item!(cx,
    #[allow(dead_code)]
    impl $getter_ty {
      $new
      $getters
      $get_raw
    }
  );
  it.unwrap()
}

/// Build a getter for a field
fn build_field_get_fn(cx: &ExtCtxt, path: &Vec<String>, reg: &node::Reg,
                      field: &node::Field) -> P<ast::Method>
{
  let fn_name = cx.ident_of(field.name.node.as_slice());
  let field_ty: P<ast::Ty> =
    cx.ty_path(utils::field_type_path(cx, path, reg, field), None);
  let mask = utils::mask(cx, field);
  let field_doc = match field.docstring {
    Some(d) => d.node,
    None => cx.ident_of("no documentation"),
  };
  let docstring = format!("Get value of `{}` field: {}",
                          field.name.node,
                          token::get_ident(field_doc).get());
  let doc_attr = utils::doc_attribute(cx, utils::intern_string(cx, docstring));

  if field.count.node == 1 {
    let shift = utils::shift(cx, None, field);
    let value = from_primitive(
      cx, reg, field,
      quote_expr!(cx, (self.value >> $shift) & $mask));
    quote_method!(cx,
      $doc_attr
      pub fn $fn_name(&self) -> $field_ty {
        $value
      }
    )
  } else {
    let shift = utils::shift(cx, Some(quote_expr!(cx, idx)), field);
    let value = from_primitive(
      cx, reg, field,
      quote_expr!(cx, (self.value >> $shift) & $mask));
    quote_method!(cx,
      $doc_attr
      pub fn $fn_name(&self, idx: uint) -> $field_ty {
        $value
      }
    )
  }
}
<|endoftext|>


<commit_before><commit_msg>Test the debug representations of Number and Value<commit_after>#[macro_use]
extern crate serde_json;

use serde_json::Number;

#[test]
fn number() {
    assert_eq!(format!("{:?}", Number::from(1)), "PosInt(1)");
    assert_eq!(format!("{:?}", Number::from(-1)), "NegInt(-1)");
    assert_eq!(format!("{:?}", Number::from_f64(1.0).unwrap()), "Float(1.0)");
}

#[test]
fn value_null() {
    assert_eq!(format!("{:?}", json!(null)), "Null");
}

#[test]
fn value_bool() {
    assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
    assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
}

#[test]
fn value_number() {
    assert_eq!(format!("{:?}", json!(1)), "Number(PosInt(1))");
    assert_eq!(format!("{:?}", json!(-1)), "Number(NegInt(-1))");
    assert_eq!(format!("{:?}", json!(1.0)), "Number(Float(1.0))");
}

#[test]
fn value_string() {
    assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
}

#[test]
fn value_array() {
    assert_eq!(format!("{:?}", json!([])), "Array([])");
}

#[test]
fn value_object() {
    assert_eq!(format!("{:?}", json!({})), "Object({})");
}
<|endoftext|>


<commit_before>//! Just a dumping ground for cli stuff

use multirust::{Cfg, Result, Notification, Toolchain, Error};
use multirust_utils::{self, utils};
use multirust_utils::notify::NotificationLevel;
use std::ffi::OsStr;
use std::io::{self, Write, Read, BufRead};
use std::process::{self, Command};
use std;
use tty;
use term;

pub fn confirm(question: &str, default: bool) -> Result<bool> {
    print!("{} ", question);
    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    let r = match &*input {
        "y" | "Y" => true,
        "n" | "N" => false,
        "" => default,
        _ => false,
    };

    println!("");

    Ok(r)
}

fn read_line() -> Result<String> {
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let mut lines = stdin.lines();
    lines.next().and_then(|l| l.ok()).ok_or(Error::ReadStdin)
}

pub fn wait_for_keypress() -> Result<()> {
    let stdin = std::io::stdin();
    if stdin.bytes().next().is_some() {
        Ok(())
    } else {
        Err(Error::ReadStdin)
    }
}

pub fn set_globals(verbose: bool) -> Result<Cfg> {
    use download_tracker::DownloadTracker;
    use std::cell::RefCell;

    let download_tracker = RefCell::new(DownloadTracker::new());

    Cfg::from_env(shared_ntfy!(move |n: Notification| {
        if download_tracker.borrow_mut().handle_notification(&n) {
            return;
        }

        match n.level() {
            NotificationLevel::Verbose => {
                if verbose {
                    verbose!("{}", n);
                }
            }
            NotificationLevel::Info => {
                info!("{}", n);
            }
            NotificationLevel::Warn => {
                warn!("{}", n);
            }
            NotificationLevel::Error => {
                err!("{}", n);
            }
        }
    }))

}

pub fn run_inner<S: AsRef<OsStr>>(mut command: Command,
                                  args: &[S]) -> Result<()> {
    command.args(&args[1..]);
    // FIXME rust-lang/rust#32254. It's not clear to me
    // when and why this is needed.
    command.stdin(process::Stdio::inherit());

    let status = command.status();

    match status {
        Ok(status) => {
            // Ensure correct exit code is returned
            let code = status.code().unwrap_or(1);
            process::exit(code);
        }
        Err(e) => {
            Err(multirust_utils::Error::RunningCommand {
                name: args[0].as_ref().to_owned(),
                error: multirust_utils::raw::CommandError::Io(e),
            }.into())
        }
    }
}

pub fn show_channel_version(cfg: &Cfg, name: &str) -> Result<()> {
    let mut t = term::stdout().unwrap();
    if tty::stdout_isatty() { let _ = t.fg(term::color::BRIGHT_WHITE); }
    if tty::stdout_isatty() { let _ = t.bg(term::color::BLACK); }
    let _ = write!(t, "{}", name);
    if tty::stdout_isatty() { let _ = t.reset(); }
    let _ = writeln!(t, " revision:");
    try!(show_tool_versions(&try!(cfg.get_toolchain(&name, false))));
    Ok(())
}

pub fn show_tool_versions(toolchain: &Toolchain) -> Result<()> {
    println!("");

    if toolchain.exists() {
        let rustc_path = toolchain.binary_file("rustc");
        let cargo_path = toolchain.binary_file("cargo");

        if utils::is_file(&rustc_path) {
            let mut cmd = Command::new(&rustc_path);
            cmd.arg("--version");
            toolchain.set_ldpath(&mut cmd);

            if utils::cmd_status("rustc", &mut cmd).is_err() {
                println!("(failed to run rustc)");
            }
        } else {
            println!("(no rustc command in toolchain?)");
        }
        if utils::is_file(&cargo_path) {
            let mut cmd = Command::new(&cargo_path);
            cmd.arg("--version");
            toolchain.set_ldpath(&mut cmd);

            if utils::cmd_status("cargo", &mut cmd).is_err() {
                println!("(failed to run cargo)");
            }
        } else {
            println!("(no cargo command in toolchain?)");
        }
    } else {
        println!("(toolchain not installed)");
    }
    println!("");
    Ok(())
}

<commit_msg>Unused import<commit_after>//! Just a dumping ground for cli stuff

use multirust::{Cfg, Result, Notification, Toolchain, Error};
use multirust_utils::{self, utils};
use multirust_utils::notify::NotificationLevel;
use std::ffi::OsStr;
use std::io::{Write, Read, BufRead};
use std::process::{self, Command};
use std;
use tty;
use term;

pub fn confirm(question: &str, default: bool) -> Result<bool> {
    print!("{} ", question);
    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    let r = match &*input {
        "y" | "Y" => true,
        "n" | "N" => false,
        "" => default,
        _ => false,
    };

    println!("");

    Ok(r)
}

fn read_line() -> Result<String> {
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let mut lines = stdin.lines();
    lines.next().and_then(|l| l.ok()).ok_or(Error::ReadStdin)
}

pub fn wait_for_keypress() -> Result<()> {
    let stdin = std::io::stdin();
    if stdin.bytes().next().is_some() {
        Ok(())
    } else {
        Err(Error::ReadStdin)
    }
}

pub fn set_globals(verbose: bool) -> Result<Cfg> {
    use download_tracker::DownloadTracker;
    use std::cell::RefCell;

    let download_tracker = RefCell::new(DownloadTracker::new());

    Cfg::from_env(shared_ntfy!(move |n: Notification| {
        if download_tracker.borrow_mut().handle_notification(&n) {
            return;
        }

        match n.level() {
            NotificationLevel::Verbose => {
                if verbose {
                    verbose!("{}", n);
                }
            }
            NotificationLevel::Info => {
                info!("{}", n);
            }
            NotificationLevel::Warn => {
                warn!("{}", n);
            }
            NotificationLevel::Error => {
                err!("{}", n);
            }
        }
    }))

}

pub fn run_inner<S: AsRef<OsStr>>(mut command: Command,
                                  args: &[S]) -> Result<()> {
    command.args(&args[1..]);
    // FIXME rust-lang/rust#32254. It's not clear to me
    // when and why this is needed.
    command.stdin(process::Stdio::inherit());

    let status = command.status();

    match status {
        Ok(status) => {
            // Ensure correct exit code is returned
            let code = status.code().unwrap_or(1);
            process::exit(code);
        }
        Err(e) => {
            Err(multirust_utils::Error::RunningCommand {
                name: args[0].as_ref().to_owned(),
                error: multirust_utils::raw::CommandError::Io(e),
            }.into())
        }
    }
}

pub fn show_channel_version(cfg: &Cfg, name: &str) -> Result<()> {
    let mut t = term::stdout().unwrap();
    if tty::stdout_isatty() { let _ = t.fg(term::color::BRIGHT_WHITE); }
    if tty::stdout_isatty() { let _ = t.bg(term::color::BLACK); }
    let _ = write!(t, "{}", name);
    if tty::stdout_isatty() { let _ = t.reset(); }
    let _ = writeln!(t, " revision:");
    try!(show_tool_versions(&try!(cfg.get_toolchain(&name, false))));
    Ok(())
}

pub fn show_tool_versions(toolchain: &Toolchain) -> Result<()> {
    println!("");

    if toolchain.exists() {
        let rustc_path = toolchain.binary_file("rustc");
        let cargo_path = toolchain.binary_file("cargo");

        if utils::is_file(&rustc_path) {
            let mut cmd = Command::new(&rustc_path);
            cmd.arg("--version");
            toolchain.set_ldpath(&mut cmd);

            if utils::cmd_status("rustc", &mut cmd).is_err() {
                println!("(failed to run rustc)");
            }
        } else {
            println!("(no rustc command in toolchain?)");
        }
        if utils::is_file(&cargo_path) {
            let mut cmd = Command::new(&cargo_path);
            cmd.arg("--version");
            toolchain.set_ldpath(&mut cmd);

            if utils::cmd_status("cargo", &mut cmd).is_err() {
                println!("(failed to run cargo)");
            }
        } else {
            println!("(no cargo command in toolchain?)");
        }
    } else {
        println!("(toolchain not installed)");
    }
    println!("");
    Ok(())
}

<|endoftext|>


<commit_before><commit_msg>wm-session-agent: add initial binary<commit_after>extern crate wm_daemons;
use wm_daemons::config::load_config;
use wm_daemons::dbus_listen::{CallbackMap, SignalInfo, match_signal, make_signal_info};

extern crate config;
use self::config::types::Config;

extern crate dbus;
use self::dbus::{Connection, BusType};

use std::error::Error;

fn run_program(action: &str, conf: &Config) -> () {
    // TODO
}

fn handle_signal(info: &SignalInfo, conf: &Config) -> () {
    if info.member == Some("Lock".to_string()) {
        run_program("lock", conf);
    } else if info.member == Some("Unlock".to_string()) {
        run_program("unlock", conf);
    }
}

fn try_main() -> Result<(), Box<Error>> {
    let conf = try!(load_config("wm-session-agent", "config"));
    let conn = try!(Connection::get_private(BusType::System));

    let cbs: CallbackMap<Config> = vec![
        (make_signal_info(
            "org.freedesktop.login1.Session",
            "/org/freedesktop/login1/session/_33",
            "Lock",
        ), handle_signal),
        (make_signal_info(
            "org.freedesktop.login1.Session",
            "/org/freedesktop/login1/session/_33",
            "Unlock",
        ), handle_signal),
    ];

    for items in conn.iter(100) {
        match_signal(items, &cbs, &conf);
    }

    Ok(())
}

fn main() -> () {
    if let Err(err) = try_main() {
        panic!("{}", err.description());
    }
}
<|endoftext|>