<commit_before>#![allow(unused_variables)]
use std::str::FromStr;

use hyper::{self, Uri};

use serde::{Serialize, Deserialize};
use serde_json;

use client::{self, ApiClient};
use svc::common;

static BIGQUERY_ROOT: &str = "https://www.googleapis.com/bigquery/v2/projects";

pub struct BigQueryService {}
pub type Hub<'a> = client::Hub<'a, BigQueryService>;

#[derive(Default, Debug)]
pub struct ListDatasetsRequest {
    pub all: bool,
    pub filter: Option<String>,
    pub max_results: Option<usize>,
    pub page_token: Option<String>,
}

impl ListDatasetsRequest {
    fn to_query(&self) -> String {
        let mut params = vec![("all", self.all.to_string())];
        if let Some(ref filter) = self.filter {
            params.push(("filter", filter.clone()));
        }
        if let Some(ref max_results) = self.max_results {
            params.push(("maxResults", max_results.to_string()));
        }
        if let Some(ref page_token) = self.page_token {
            params.push(("pageToken", page_token.clone()));
        }
        client::encode_query_params(params)
    }
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListDatasetsResponse {
    pub next_page_token: Option<String>,

    pub datasets: Vec<DatasetMeta>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DatasetMeta {
    pub id: String,
    pub dataset_reference: DatasetReference,
    pub friendly_name: Option<String>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DatasetReference {
    pub project_id: String,
    pub dataset_id: String,
}

#[derive(Default, Debug)]
pub struct ListTablesRequest {
    pub max_results: Option<usize>,
    pub page_token: Option<String>,
}

impl ListTablesRequest {
    fn to_query(&self) -> String {
        let mut params = vec![];
        if let Some(ref max_results) = self.max_results {
            params.push(("maxResults", max_results.to_string()));
        }
        if let Some(ref page_token) = self.page_token {
            params.push(("pageToken", page_token.clone()));
        }
        client::encode_query_params(params)
    }
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListTablesResponse {
    pub next_page_token: Option<String>,
    pub tables: Vec<TableMeta>,
    pub total_items: usize,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableMeta {
    pub id: String,
    pub table_reference: TableReference,
    pub friendly_name: Option<String>,
    pub view: Option<ViewMeta>,

    #[serde(rename = "type")]
    pub type0: String,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ViewMeta {
    query: String,
    #[serde(default = "default_view_use_legacy_sql")]
    use_legacy_sql: bool,
}

fn default_view_use_legacy_sql() -> bool {
    true
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableReference {
    pub project_id: String,
    pub dataset_id: String,
    pub table_id: String,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DescribeTableResponse {
    pub id: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub schema: Option<TableFieldSchema>,

    #[serde(rename = "type")]
    pub type0: String,

    pub table_reference: TableReference,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub friendly_name: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub external_data_configuration: Option<ExtDataConfig>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub view: Option<ViewMeta>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ExtDataConfig {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub schema: Option<TableFieldSchema>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableFieldSchema {
    pub fields: Vec<TableField>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableField {
    pub name: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default = "default_table_field_mode")]
    pub mode: String,

    #[serde(rename = "type")]
    pub type0: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub fields: Option<Vec<TableField>>,
}

fn default_table_field_mode() -> String {
    "NULLABLE".into()
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobResource {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub kind: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub dry_run: Option<bool>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub job_reference: Option<JobReference>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<JobStatus>,

    pub configuration: JobConfiguration,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobConfiguration {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub query: Option<QueryResource>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct QueryResource {
    pub query: String,
    pub use_legacy_sql: bool,
    pub use_query_cache: bool,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub destination_table: Option<TableReference>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobStatus {
    pub state: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub error_result: Option<QueryError>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub errors: Option<Vec<QueryError>>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobReference {
    pub project_id: String,

    pub job_id: String,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct QueryError {
    pub reason: Option<String>,
    pub location: Option<String>,
    pub message: Option<String>,
    pub debug_info: Option<String>,
}

#[derive(Serialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GetQueryResultsRequest {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub timeout_ms: Option<usize>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_results: Option<usize>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub start_index: Option<usize>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub page_token: Option<String>,
}

impl GetQueryResultsRequest {
    fn to_query(&self) -> String {
        let mut params = Vec::new();
        if let Some(ref timeout_ms) = self.timeout_ms {
            params.push(("timeoutMs", timeout_ms.to_string()));
        }
        if let Some(ref max_results) = self.max_results {
            params.push(("maxResults", max_results.to_string()));
        }
        if let Some(ref page_token) = self.page_token {
            params.push(("pageToken", page_token.clone()));
        }
        if let Some(ref start_index) = self.start_index {
            params.push(("startIndex", start_index.to_string()));
        }
        client::encode_query_params(params)
    }
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GetQueryResultsResponse {
    pub schema: Option<TableFieldSchema>,
    pub job_reference: Option<JobReference>,
    pub total_rows: Option<String>,
    pub rows: Option<Vec<TableRow>>,
    pub job_complete: bool,
    pub page_token: Option<String>,
    pub errors: Option<Vec<QueryError>>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct TableRow {
    pub f: Vec<TableCell>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct TableCell {
    pub v: Cell,
}

#[serde(untagged)]
#[derive(Serialize, Deserialize, Debug)]
pub enum Cell {
    Value(Option<String>),
    Repeat(Vec<TableCell>),
    Row(TableRow),
}

impl Default for Cell {
    fn default() -> Self {
        Cell::Value(None)
    }
}

impl<'a> Hub<'a> {
    pub fn list_datasets(
        &self,
        token: &str,
        project_id: &str,
        req: &ListDatasetsRequest,
    ) -> client::Result<ListDatasetsResponse> {
        let path = format!(
            "{}/{}/datasets?{}",
            BIGQUERY_ROOT,
            project_id,
            req.to_query()
        );

        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<ListDatasetsResponse>(&uri, token.to_string())
    }

    pub fn list_tables(
        &self,
        token: &str,
        project_id: &str,
        dataset_id: &str,
        req: &ListTablesRequest,
    ) -> client::Result<ListTablesResponse> {
        let path = format!(
            "{}/{}/datasets/{}/tables?{}",
            BIGQUERY_ROOT,
            project_id,
            dataset_id,
            req.to_query()
        );
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<ListTablesResponse>(&uri, token.to_string())
    }

    pub fn describe_table(
        &self,
        token: &str,
        project_id: &str,
        dataset_id: &str,
        table_id: &str,
    ) -> client::Result<DescribeTableResponse> {
        let path = format!(
            "{}/{}/datasets/{}/tables/{}",
            BIGQUERY_ROOT,
            project_id,
            dataset_id,
            table_id
        );
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<DescribeTableResponse>(&uri, token.to_string())
    }

    pub fn create_job(
        &self,
        token: &str,
        project_id: &str,
        req: &JobResource,
    ) -> client::Result<JobResource> {
        let path = format!("{}/{}/jobs", BIGQUERY_ROOT, project_id);
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.post_bq::<_, _>(&uri, req, token.to_string())
    }

    pub fn cancel_job(
        &self,
        token: &str,
        project_id: &str,
        job_id: &str,
    ) -> client::Result<JobResource> {
        let path = format!("{}/{}/jobs/{}/cancel", BIGQUERY_ROOT, project_id, job_id);
        let uri = Uri::from_str(&path).expect("uri to be valid");

        #[derive(Deserialize, Debug)]
        #[serde(rename_all = "camelCase")]
        struct Response {
            pub job: JobResource,
        }

        self.post_bq::<_, Response>(&uri, common::Empty {}, token.to_string())
            .map(|r| r.job)
    }

    pub fn get_job(
        &self,
        token: &str,
        project_id: &str,
        job_id: &str,
    ) -> client::Result<JobResource> {
        let path = format!("{}/{}/jobs/{}", BIGQUERY_ROOT, project_id, job_id);
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<_>(&uri, token.to_string())
    }

    pub fn get_query_results(
        &self,
        token: &str,
        project_id: &str,
        job_id: &str,
        req: &GetQueryResultsRequest,
    ) -> client::Result<GetQueryResultsResponse> {
        let path = format!(
            "{}/{}/queries/{}?{}",
            BIGQUERY_ROOT,
            project_id,
            job_id,
            req.to_query()
        );
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<_>(&uri, token.to_string())
    }

    // helper method for making a GET request
    fn get_bq<D>(&self, uri: &hyper::Uri, token: String) -> client::Result<D>
    where
        for<'de> D: 'static + Send + Deserialize<'de>,
    {
        let mut req = hyper::Request::new(hyper::Method::Get, uri.clone());
        let auth = hyper::header::Authorization(hyper::header::Bearer { token });
        req.headers_mut().set(auth);

        self.request(req).map(|(_, res)| res)
    }

    // helper method for making a POST request with a JSON body
    fn post_bq<B: Serialize, D>(
        &self,
        uri: &hyper::Uri,
        body: B,
        token: String,
    ) -> client::Result<D>
    where
        for<'de> D: 'static + Send + Deserialize<'de>,
    {
        let mut req = hyper::Request::new(hyper::Method::Post, uri.clone());
        req.headers_mut().set(hyper::header::ContentType::json());

        let auth = hyper::header::Authorization(hyper::header::Bearer { token });
        req.headers_mut().set(auth);

        let body = serde_json::to_string(&body).unwrap();
        req.set_body(body);

        self.request(req).map(|(_, res)| res)
    }
}
<commit_msg>make fields pub<commit_after>#![allow(unused_variables)]
use std::str::FromStr;

use hyper::{self, Uri};

use serde::{Serialize, Deserialize};
use serde_json;

use client::{self, ApiClient};
use svc::common;

static BIGQUERY_ROOT: &str = "https://www.googleapis.com/bigquery/v2/projects";

pub struct BigQueryService {}
pub type Hub<'a> = client::Hub<'a, BigQueryService>;

#[derive(Default, Debug)]
pub struct ListDatasetsRequest {
    pub all: bool,
    pub filter: Option<String>,
    pub max_results: Option<usize>,
    pub page_token: Option<String>,
}

impl ListDatasetsRequest {
    fn to_query(&self) -> String {
        let mut params = vec![("all", self.all.to_string())];
        if let Some(ref filter) = self.filter {
            params.push(("filter", filter.clone()));
        }
        if let Some(ref max_results) = self.max_results {
            params.push(("maxResults", max_results.to_string()));
        }
        if let Some(ref page_token) = self.page_token {
            params.push(("pageToken", page_token.clone()));
        }
        client::encode_query_params(params)
    }
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListDatasetsResponse {
    pub next_page_token: Option<String>,

    pub datasets: Vec<DatasetMeta>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DatasetMeta {
    pub id: String,
    pub dataset_reference: DatasetReference,
    pub friendly_name: Option<String>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DatasetReference {
    pub project_id: String,
    pub dataset_id: String,
}

#[derive(Default, Debug)]
pub struct ListTablesRequest {
    pub max_results: Option<usize>,
    pub page_token: Option<String>,
}

impl ListTablesRequest {
    fn to_query(&self) -> String {
        let mut params = vec![];
        if let Some(ref max_results) = self.max_results {
            params.push(("maxResults", max_results.to_string()));
        }
        if let Some(ref page_token) = self.page_token {
            params.push(("pageToken", page_token.clone()));
        }
        client::encode_query_params(params)
    }
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListTablesResponse {
    pub next_page_token: Option<String>,
    pub tables: Vec<TableMeta>,
    pub total_items: usize,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableMeta {
    pub id: String,
    pub table_reference: TableReference,
    pub friendly_name: Option<String>,
    pub view: Option<ViewMeta>,

    #[serde(rename = "type")]
    pub type0: String,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ViewMeta {
    pub query: String,
    #[serde(default = "default_view_use_legacy_sql")]
    pub use_legacy_sql: bool,
}

fn default_view_use_legacy_sql() -> bool {
    true
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableReference {
    pub project_id: String,
    pub dataset_id: String,
    pub table_id: String,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct DescribeTableResponse {
    pub id: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub schema: Option<TableFieldSchema>,

    #[serde(rename = "type")]
    pub type0: String,

    pub table_reference: TableReference,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub friendly_name: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub external_data_configuration: Option<ExtDataConfig>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub view: Option<ViewMeta>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ExtDataConfig {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub schema: Option<TableFieldSchema>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableFieldSchema {
    pub fields: Vec<TableField>,
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TableField {
    pub name: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default = "default_table_field_mode")]
    pub mode: String,

    #[serde(rename = "type")]
    pub type0: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub fields: Option<Vec<TableField>>,
}

fn default_table_field_mode() -> String {
    "NULLABLE".into()
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobResource {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub kind: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub dry_run: Option<bool>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub job_reference: Option<JobReference>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<JobStatus>,

    pub configuration: JobConfiguration,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobConfiguration {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub query: Option<QueryResource>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct QueryResource {
    pub query: String,
    pub use_legacy_sql: bool,
    pub use_query_cache: bool,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub destination_table: Option<TableReference>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobStatus {
    pub state: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub error_result: Option<QueryError>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub errors: Option<Vec<QueryError>>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct JobReference {
    pub project_id: String,

    pub job_id: String,
}

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct QueryError {
    pub reason: Option<String>,
    pub location: Option<String>,
    pub message: Option<String>,
    pub debug_info: Option<String>,
}

#[derive(Serialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GetQueryResultsRequest {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub timeout_ms: Option<usize>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_results: Option<usize>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub start_index: Option<usize>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub page_token: Option<String>,
}

impl GetQueryResultsRequest {
    fn to_query(&self) -> String {
        let mut params = Vec::new();
        if let Some(ref timeout_ms) = self.timeout_ms {
            params.push(("timeoutMs", timeout_ms.to_string()));
        }
        if let Some(ref max_results) = self.max_results {
            params.push(("maxResults", max_results.to_string()));
        }
        if let Some(ref page_token) = self.page_token {
            params.push(("pageToken", page_token.clone()));
        }
        if let Some(ref start_index) = self.start_index {
            params.push(("startIndex", start_index.to_string()));
        }
        client::encode_query_params(params)
    }
}

#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GetQueryResultsResponse {
    pub schema: Option<TableFieldSchema>,
    pub job_reference: Option<JobReference>,
    pub total_rows: Option<String>,
    pub rows: Option<Vec<TableRow>>,
    pub job_complete: bool,
    pub page_token: Option<String>,
    pub errors: Option<Vec<QueryError>>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct TableRow {
    pub f: Vec<TableCell>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct TableCell {
    pub v: Cell,
}

#[serde(untagged)]
#[derive(Serialize, Deserialize, Debug)]
pub enum Cell {
    Value(Option<String>),
    Repeat(Vec<TableCell>),
    Row(TableRow),
}

impl Default for Cell {
    fn default() -> Self {
        Cell::Value(None)
    }
}

impl<'a> Hub<'a> {
    pub fn list_datasets(
        &self,
        token: &str,
        project_id: &str,
        req: &ListDatasetsRequest,
    ) -> client::Result<ListDatasetsResponse> {
        let path = format!(
            "{}/{}/datasets?{}",
            BIGQUERY_ROOT,
            project_id,
            req.to_query()
        );

        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<ListDatasetsResponse>(&uri, token.to_string())
    }

    pub fn list_tables(
        &self,
        token: &str,
        project_id: &str,
        dataset_id: &str,
        req: &ListTablesRequest,
    ) -> client::Result<ListTablesResponse> {
        let path = format!(
            "{}/{}/datasets/{}/tables?{}",
            BIGQUERY_ROOT,
            project_id,
            dataset_id,
            req.to_query()
        );
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<ListTablesResponse>(&uri, token.to_string())
    }

    pub fn describe_table(
        &self,
        token: &str,
        project_id: &str,
        dataset_id: &str,
        table_id: &str,
    ) -> client::Result<DescribeTableResponse> {
        let path = format!(
            "{}/{}/datasets/{}/tables/{}",
            BIGQUERY_ROOT,
            project_id,
            dataset_id,
            table_id
        );
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<DescribeTableResponse>(&uri, token.to_string())
    }

    pub fn create_job(
        &self,
        token: &str,
        project_id: &str,
        req: &JobResource,
    ) -> client::Result<JobResource> {
        let path = format!("{}/{}/jobs", BIGQUERY_ROOT, project_id);
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.post_bq::<_, _>(&uri, req, token.to_string())
    }

    pub fn cancel_job(
        &self,
        token: &str,
        project_id: &str,
        job_id: &str,
    ) -> client::Result<JobResource> {
        let path = format!("{}/{}/jobs/{}/cancel", BIGQUERY_ROOT, project_id, job_id);
        let uri = Uri::from_str(&path).expect("uri to be valid");

        #[derive(Deserialize, Debug)]
        #[serde(rename_all = "camelCase")]
        struct Response {
            pub job: JobResource,
        }

        self.post_bq::<_, Response>(&uri, common::Empty {}, token.to_string())
            .map(|r| r.job)
    }

    pub fn get_job(
        &self,
        token: &str,
        project_id: &str,
        job_id: &str,
    ) -> client::Result<JobResource> {
        let path = format!("{}/{}/jobs/{}", BIGQUERY_ROOT, project_id, job_id);
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<_>(&uri, token.to_string())
    }

    pub fn get_query_results(
        &self,
        token: &str,
        project_id: &str,
        job_id: &str,
        req: &GetQueryResultsRequest,
    ) -> client::Result<GetQueryResultsResponse> {
        let path = format!(
            "{}/{}/queries/{}?{}",
            BIGQUERY_ROOT,
            project_id,
            job_id,
            req.to_query()
        );
        let uri = Uri::from_str(&path).expect("uri to be valid");
        self.get_bq::<_>(&uri, token.to_string())
    }

    // helper method for making a GET request
    fn get_bq<D>(&self, uri: &hyper::Uri, token: String) -> client::Result<D>
    where
        for<'de> D: 'static + Send + Deserialize<'de>,
    {
        let mut req = hyper::Request::new(hyper::Method::Get, uri.clone());
        let auth = hyper::header::Authorization(hyper::header::Bearer { token });
        req.headers_mut().set(auth);

        self.request(req).map(|(_, res)| res)
    }

    // helper method for making a POST request with a JSON body
    fn post_bq<B: Serialize, D>(
        &self,
        uri: &hyper::Uri,
        body: B,
        token: String,
    ) -> client::Result<D>
    where
        for<'de> D: 'static + Send + Deserialize<'de>,
    {
        let mut req = hyper::Request::new(hyper::Method::Post, uri.clone());
        req.headers_mut().set(hyper::header::ContentType::json());

        let auth = hyper::header::Authorization(hyper::header::Bearer { token });
        req.headers_mut().set(auth);

        let body = serde_json::to_string(&body).unwrap();
        req.set_body(body);

        self.request(req).map(|(_, res)| res)
    }
}
<|endoftext|>


<commit_before>use ast::punc::*;
use ast::token::*;
use std::io::{BufReader, BufferedReader, Buffer, IoError, IoResult, EndOfFile};
use std::char::from_u32;
use std::num::from_str_radix;
use std::from_str::FromStr;
/// A Javascript lexer
pub struct Lexer<B> {
    /// The list of tokens generated so far
    pub tokens : Vec<Token>,
    /// The current line number in the script
    line_number : uint,
    /// The current column number in the script
    column_number : uint,
    /// The reader
    buffer: B,
    /// The peeked character buffer
    peek_buffer: String
}
impl<B:Buffer> Lexer<B> {
    /// Creates a new lexer with empty buffers
    pub fn new(buffer: B) -> Lexer<B> {
        Lexer {
            tokens: Vec::new(),
            line_number: 1,
            column_number: 0,
            buffer: buffer,
            peek_buffer: String::new()
        }
    }
    #[inline(always)]
    fn push_token(&mut self, tk:TokenData) {
        self.tokens.push(Token::new(tk, self.line_number, self.column_number))
    }
    #[inline(always)]
    fn push_punc(&mut self, punc:Punctuator) {
        self.push_token(TPunctuator(punc));
    }
    /// Processes an input stream from a string into an array of tokens
    pub fn lex_str(script:&str) -> Vec<Token> {
        let script_bytes:&[u8] = script.as_bytes();
        let reader = BufReader::new(script_bytes);
        let buf_reader = BufferedReader::new(reader);
        let mut lexer = Lexer::new(buf_reader);
        lexer.lex().unwrap();
        lexer.tokens
    }
    fn next(&mut self) -> IoResult<char> {
        if self.peek_buffer.len() == 0 {
            self.buffer.read_char()
        } else {
            Ok(match self.peek_buffer.pop_char() {
                Some(v) => v,
                None => unreachable!()
            })
        }
    }
    fn peek_for(&mut self, peek:char) -> bool {
        if self.peek_buffer.len() > 0 {
            let matched = self.peek_buffer.as_slice().char_at(self.peek_buffer.len() - 1) == peek;
            if matched {
                self.peek_buffer.pop_char();
            }
            matched
        } else {
            match self.buffer.read_char() {
                Ok(ch) if ch == peek => {
                    self.column_number += 1;
                    true
                },
                Ok(ch) if ch != peek => {
                    self.peek_buffer.push_char(ch);
                    false
                },
                _ => false
            }
        }
    }
    /// Processes an input stream from the `buffer` into a vector of tokens
    pub fn lex(&mut self) -> IoResult<()> {
        loop {
            let ch = match self.next() {
                Ok(ch) => ch,
                Err(ref err) if err.kind == EndOfFile => break,
                Err(err) => return Err(err)
            };
            self.column_number += 1;
            match ch {
                '"' | '\'' => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\'' if ch == '\'' => {
                                break;
                            },
                            '"' if ch == '"' => {
                                break;
                            },
                            '\\' => {
                                let escape = try!(self.next());
                                if escape != '\n' {
                                    let escaped_ch = match escape {
                                        'n' => '\n',
                                        'r' => '\r',
                                        't' => '\t',
                                        'b' => '\x08',
                                        'f' => '\x0c',
                                        '0' => '\0',
                                        'x' => {
                                            let mut nums = String::with_capacity(2);
                                            for _ in range(0, 2) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 2;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        'u' => {
                                            let mut nums = String::new();
                                            for _ in range(0, 4) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 4;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        '\'' | '"' => escape,
                                        _ => fail!("{}:{}: Invalid escape `{}`", self.line_number, self.column_number, ch)
                                    };
                                    buf.push_char(escaped_ch);
                                }
                            },
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TStringLiteral(buf))
                },
                '0' if self.peek_for('x') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            ch if ch.is_digit_radix(16) => buf.push_char(ch),
                            ch => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str_radix(buf.as_slice(), 16).unwrap()));
                },
                '0' => {
                    let mut buf = "0".into_string();
                    let mut gone_decimal = false;
                    loop {
                        let ch = self.next();
                        match ch {
                            Ok(ch) if ch.is_digit_radix(8) =>
                                buf.push_char(ch),
                            Ok('8') | Ok('9') | Ok('.') => {
                                gone_decimal = true;
                                buf.push_char(ch.unwrap());
                            },
                            Ok(ch) => {
                                self.peek_buffer.push_char(ch);
                                break;
                            },
                            Err(IoError {kind: EndOfFile, ..}) =>
                                break,
                            Err(err) =>
                                return Err(err)
                        }
                    }
                    self.push_token(TNumericLiteral(if gone_decimal {
                        from_str(buf.as_slice())
                    } else {
                        from_str_radix(buf.as_slice(), 8)
                    }.unwrap()));
                },
                _ if ch.is_digit() => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            '.' => buf.push_char(ch),
                            _ if ch.is_digit() => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str(buf.as_slice()).unwrap()));
                },
                _ if ch.is_alphabetic() || ch == '$' || ch == '_' => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            _ if ch.is_alphabetic() || ch.is_digit() || ch == '_' => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(match buf.as_slice() {
                        "true" => TBooleanLiteral(true),
                        "false" => TBooleanLiteral(false),
                        "null" => TNullLiteral,
                        slice => match FromStr::from_str(slice) {
                            Some(keyword) => TKeyword(keyword),
                            None => TIdentifier(buf.clone())
                        }
                    });
                },
                ';' => {
                    self.push_punc(PSemicolon);
                },
                ':' => {
                    self.push_punc(PColon);
                },
                '.' => {
                    self.push_punc(PDot);
                },
                '(' => {
                    self.push_punc(POpenParen);
                },
                ')' => {
                    self.push_punc(PCloseParen);
                },
                ',' => {
                    self.push_punc(PComma);
                },
                '{' => {
                    self.push_punc(POpenBlock);
                },
                '}' => {
                    self.push_punc(PCloseBlock);
                },
                '[' => {
                    self.push_punc(POpenBracket);
                },
                ']' => {
                    self.push_punc(PCloseBracket);
                },
                '?' => {
                    self.push_punc(PQuestion);
                },
                '/' if self.peek_for('/') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.peek_for('*') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            '*' if self.peek_for('/') => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.peek_for('=') => {
                    self.push_punc(PAssignDiv);
                },
                '/' => {
                    self.push_punc(PDiv);
                },
                '*' if self.peek_for('=') => {
                    self.push_punc(PAssignMul);
                },
                '*' => {
                    self.push_punc(PMul);
                },
                '+' if self.peek_for('=') => {
                    self.push_punc(PAssignAdd);
                },
                '+' if self.peek_for('+') => {
                    self.push_punc(PInc);
                },
                '+' => {
                    self.push_punc(PAdd);
                },
                '-' if self.peek_for('=') => {
                    self.push_punc(PAssignSub);
                },
                '-' if self.peek_for('-') => {
                    self.push_punc(PDec);
                },
                '-' => {
                    self.push_punc(PSub);
                },
                '%' if self.peek_for('=') => {
                    self.push_punc(PAssignMod);
                },
                '%' => {
                    self.push_punc(PMod);
                },
                '|' if self.peek_for('|') => {
                    self.push_punc(PBoolOr);
                },
                '|' if self.peek_for('=') => {
                    self.push_punc(PAssignOr);
                },
                '|' => {
                    self.push_punc(POr);
                },
                '&' if self.peek_for('&') => {
                    self.push_punc(PBoolAnd);
                },
                '&' if self.peek_for('=') => {
                    self.push_punc(PAssignAnd);
                },
                '&' => {
                    self.push_punc(PAnd);
                },
                '^' if self.peek_for('=') => {
                    self.push_punc(PAssignXor);
                },
                '^' => {
                    self.push_punc(PXor);
                },
                '=' if self.peek_for('>') => {
                    self.push_punc(PArrow);
                },
                '=' if self.peek_for('=') => {
                    if self.peek_for('=') {
                        self.push_punc(PStrictEq);
                    } else {
                        self.push_punc(PEq);
                    }
                },
                '=' => {
                    self.push_punc(PAssign);
                },
                '<' if self.peek_for('=') => {
                    self.push_punc(PLessThanOrEq);
                },
                '<' if self.peek_for('<') => {
                    if self.peek_for('=') {
                        self.push_punc(PAssignLeftSh);
                    } else {
                        self.push_punc(PLeftSh);
                    }
                },
                '<' => {
                    self.push_punc(PLessThan);
                },
                '>' if self.peek_for('=') => {
                    self.push_punc(PGreaterThanOrEq);
                },
                '>' if self.peek_for('>') => {
                    if self.peek_for('=') {
                        self.push_punc(PAssignRightSh);
                    } else if self.peek_for('>') {
                        if self.peek_for('=') {
                            self.push_punc(PAssignURightSh);
                        } else {
                            self.push_punc(PURightSh);
                        }
                    } else {
                        self.push_punc(PRightSh);
                    }
                },
                '>' => {
                        self.push_punc(PGreaterThan);
                },
                '!' if self.peek_for('=') => {
                    if self.peek_for('=') {
                        self.push_punc(PStrictNotEq);
                    } else {
                        self.push_punc(PNotEq);
                    }
                },
                '!' => {
                    self.push_punc(PNot);
                },
                '~' => {
                    self.push_punc(PNeg);
                },
                '\n' | '\u2028'|'\u2029' => {
                    self.line_number += 1;
                    self.column_number = 0;
                },
                '\r' => {
                    self.column_number = 0;
                },
                ' ' => (),
                ch => fail!("{}:{}: Unexpected '{}'", self.line_number, self.column_number, ch)
            };
        };
        Ok(())
    }
}<commit_msg>Rename `peek_next` to `next_is`<commit_after>use ast::punc::*;
use ast::token::*;
use std::io::{BufReader, BufferedReader, Buffer, IoError, IoResult, EndOfFile};
use std::char::from_u32;
use std::num::from_str_radix;
use std::from_str::FromStr;
/// A Javascript lexer
pub struct Lexer<B> {
    /// The list of tokens generated so far
    pub tokens : Vec<Token>,
    /// The current line number in the script
    line_number : uint,
    /// The current column number in the script
    column_number : uint,
    /// The reader
    buffer: B,
    /// The peeked character buffer
    peek_buffer: String
}
impl<B:Buffer> Lexer<B> {
    /// Creates a new lexer with empty buffers
    pub fn new(buffer: B) -> Lexer<B> {
        Lexer {
            tokens: Vec::new(),
            line_number: 1,
            column_number: 0,
            buffer: buffer,
            peek_buffer: String::new()
        }
    }
    #[inline(always)]
    fn push_token(&mut self, tk:TokenData) {
        self.tokens.push(Token::new(tk, self.line_number, self.column_number))
    }
    #[inline(always)]
    fn push_punc(&mut self, punc:Punctuator) {
        self.push_token(TPunctuator(punc));
    }
    /// Processes an input stream from a string into an array of tokens
    pub fn lex_str(script:&str) -> Vec<Token> {
        let script_bytes:&[u8] = script.as_bytes();
        let reader = BufReader::new(script_bytes);
        let buf_reader = BufferedReader::new(reader);
        let mut lexer = Lexer::new(buf_reader);
        lexer.lex().unwrap();
        lexer.tokens
    }
    fn next(&mut self) -> IoResult<char> {
        if self.peek_buffer.len() == 0 {
            self.buffer.read_char()
        } else {
            Ok(match self.peek_buffer.pop_char() {
                Some(v) => v,
                None => unreachable!()
            })
        }
    }
    fn next_is(&mut self, peek:char) -> bool {
        if self.peek_buffer.len() > 0 {
            let matched = self.peek_buffer.as_slice().char_at(self.peek_buffer.len() - 1) == peek;
            if matched {
                self.peek_buffer.pop_char();
            }
            matched
        } else {
            match self.buffer.read_char() {
                Ok(ch) if ch == peek => {
                    self.column_number += 1;
                    true
                },
                Ok(ch) if ch != peek => {
                    self.peek_buffer.push_char(ch);
                    false
                },
                _ => false
            }
        }
    }
    /// Processes an input stream from the `buffer` into a vector of tokens
    pub fn lex(&mut self) -> IoResult<()> {
        loop {
            let ch = match self.next() {
                Ok(ch) => ch,
                Err(ref err) if err.kind == EndOfFile => break,
                Err(err) => return Err(err)
            };
            self.column_number += 1;
            match ch {
                '"' | '\'' => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\'' if ch == '\'' => {
                                break;
                            },
                            '"' if ch == '"' => {
                                break;
                            },
                            '\\' => {
                                let escape = try!(self.next());
                                if escape != '\n' {
                                    let escaped_ch = match escape {
                                        'n' => '\n',
                                        'r' => '\r',
                                        't' => '\t',
                                        'b' => '\x08',
                                        'f' => '\x0c',
                                        '0' => '\0',
                                        'x' => {
                                            let mut nums = String::with_capacity(2);
                                            for _ in range(0, 2) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 2;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        'u' => {
                                            let mut nums = String::new();
                                            for _ in range(0, 4) {
                                                nums.push_char(try!(self.next()));
                                            }
                                            self.column_number += 4;
                                            let as_num = match from_str_radix(nums.as_slice(), 16) {
                                                Some(v) => v,
                                                None => 0
                                            };
                                            match from_u32(as_num) {
                                                Some(v) => v,
                                                None => fail!("{}:{}: {} is not a valid unicode scalar value", self.line_number, self.column_number, as_num)
                                            }
                                        },
                                        '\'' | '"' => escape,
                                        _ => fail!("{}:{}: Invalid escape `{}`", self.line_number, self.column_number, ch)
                                    };
                                    buf.push_char(escaped_ch);
                                }
                            },
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TStringLiteral(buf))
                },
                '0' if self.next_is('x') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            ch if ch.is_digit_radix(16) => buf.push_char(ch),
                            ch => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str_radix(buf.as_slice(), 16).unwrap()));
                },
                '0' => {
                    let mut buf = "0".into_string();
                    let mut gone_decimal = false;
                    loop {
                        let ch = self.next();
                        match ch {
                            Ok(ch) if ch.is_digit_radix(8) =>
                                buf.push_char(ch),
                            Ok('8') | Ok('9') | Ok('.') => {
                                gone_decimal = true;
                                buf.push_char(ch.unwrap());
                            },
                            Ok(ch) => {
                                self.peek_buffer.push_char(ch);
                                break;
                            },
                            Err(IoError {kind: EndOfFile, ..}) =>
                                break,
                            Err(err) =>
                                return Err(err)
                        }
                    }
                    self.push_token(TNumericLiteral(if gone_decimal {
                        from_str(buf.as_slice())
                    } else {
                        from_str_radix(buf.as_slice(), 8)
                    }.unwrap()));
                },
                _ if ch.is_digit() => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            '.' => buf.push_char(ch),
                            _ if ch.is_digit() => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(TNumericLiteral(from_str(buf.as_slice()).unwrap()));
                },
                _ if ch.is_alphabetic() || ch == '$' || ch == '_' => {
                    let mut buf = String::new();
                    buf.push_char(ch);
                    loop {
                        let ch = try!(self.next());
                        match ch {
                            _ if ch.is_alphabetic() || ch.is_digit() || ch == '_' => buf.push_char(ch),
                            _ => {
                                self.peek_buffer.push_char(ch);
                                break;
                            }
                        }
                    }
                    self.push_token(match buf.as_slice() {
                        "true" => TBooleanLiteral(true),
                        "false" => TBooleanLiteral(false),
                        "null" => TNullLiteral,
                        slice => match FromStr::from_str(slice) {
                            Some(keyword) => TKeyword(keyword),
                            None => TIdentifier(buf.clone())
                        }
                    });
                },
                ';' => {
                    self.push_punc(PSemicolon);
                },
                ':' => {
                    self.push_punc(PColon);
                },
                '.' => {
                    self.push_punc(PDot);
                },
                '(' => {
                    self.push_punc(POpenParen);
                },
                ')' => {
                    self.push_punc(PCloseParen);
                },
                ',' => {
                    self.push_punc(PComma);
                },
                '{' => {
                    self.push_punc(POpenBlock);
                },
                '}' => {
                    self.push_punc(PCloseBlock);
                },
                '[' => {
                    self.push_punc(POpenBracket);
                },
                ']' => {
                    self.push_punc(PCloseBracket);
                },
                '?' => {
                    self.push_punc(PQuestion);
                },
                '/' if self.next_is('/') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.next_is('*') => {
                    let mut buf = String::new();
                    loop {
                        match try!(self.next()) {
                            '\n' => break,
                            '*' if self.next_is('/') => break,
                            ch => buf.push_char(ch)
                        }
                    }
                    self.push_token(TComment(buf));
                },
                '/' if self.next_is('=') => {
                    self.push_punc(PAssignDiv);
                },
                '/' => {
                    self.push_punc(PDiv);
                },
                '*' if self.next_is('=') => {
                    self.push_punc(PAssignMul);
                },
                '*' => {
                    self.push_punc(PMul);
                },
                '+' if self.next_is('=') => {
                    self.push_punc(PAssignAdd);
                },
                '+' if self.next_is('+') => {
                    self.push_punc(PInc);
                },
                '+' => {
                    self.push_punc(PAdd);
                },
                '-' if self.next_is('=') => {
                    self.push_punc(PAssignSub);
                },
                '-' if self.next_is('-') => {
                    self.push_punc(PDec);
                },
                '-' => {
                    self.push_punc(PSub);
                },
                '%' if self.next_is('=') => {
                    self.push_punc(PAssignMod);
                },
                '%' => {
                    self.push_punc(PMod);
                },
                '|' if self.next_is('|') => {
                    self.push_punc(PBoolOr);
                },
                '|' if self.next_is('=') => {
                    self.push_punc(PAssignOr);
                },
                '|' => {
                    self.push_punc(POr);
                },
                '&' if self.next_is('&') => {
                    self.push_punc(PBoolAnd);
                },
                '&' if self.next_is('=') => {
                    self.push_punc(PAssignAnd);
                },
                '&' => {
                    self.push_punc(PAnd);
                },
                '^' if self.next_is('=') => {
                    self.push_punc(PAssignXor);
                },
                '^' => {
                    self.push_punc(PXor);
                },
                '=' if self.next_is('>') => {
                    self.push_punc(PArrow);
                },
                '=' if self.next_is('=') => {
                    if self.next_is('=') {
                        self.push_punc(PStrictEq);
                    } else {
                        self.push_punc(PEq);
                    }
                },
                '=' => {
                    self.push_punc(PAssign);
                },
                '<' if self.next_is('=') => {
                    self.push_punc(PLessThanOrEq);
                },
                '<' if self.next_is('<') => {
                    if self.next_is('=') {
                        self.push_punc(PAssignLeftSh);
                    } else {
                        self.push_punc(PLeftSh);
                    }
                },
                '<' => {
                    self.push_punc(PLessThan);
                },
                '>' if self.next_is('=') => {
                    self.push_punc(PGreaterThanOrEq);
                },
                '>' if self.next_is('>') => {
                    if self.next_is('=') {
                        self.push_punc(PAssignRightSh);
                    } else if self.next_is('>') {
                        if self.next_is('=') {
                            self.push_punc(PAssignURightSh);
                        } else {
                            self.push_punc(PURightSh);
                        }
                    } else {
                        self.push_punc(PRightSh);
                    }
                },
                '>' => {
                        self.push_punc(PGreaterThan);
                },
                '!' if self.next_is('=') => {
                    if self.next_is('=') {
                        self.push_punc(PStrictNotEq);
                    } else {
                        self.push_punc(PNotEq);
                    }
                },
                '!' => {
                    self.push_punc(PNot);
                },
                '~' => {
                    self.push_punc(PNeg);
                },
                '\n' | '\u2028'|'\u2029' => {
                    self.line_number += 1;
                    self.column_number = 0;
                },
                '\r' => {
                    self.column_number = 0;
                },
                ' ' => (),
                ch => fail!("{}:{}: Unexpected '{}'", self.line_number, self.column_number, ch)
            };
        };
        Ok(())
    }
}<|endoftext|>


<commit_before>
use prelude::*;

use fixedbitset::FixedBitSet;
use std::collections::HashSet;
use std::marker::PhantomData;

use visit::{
    GraphBase,
    IntoNeighbors,
    IntoNodeIdentifiers,
    IntoNodeReferences,
    IntoNeighborsDirected,
    NodeIndexable,
    Visitable,
    VisitMap,
    GraphProp,
    IntoEdges,
    IntoEdgeReferences,
};
use visit::{Data, NodeCompactIndexable, NodeCount};
use data::{DataMap};

/// A graph filter for nodes.
pub trait FilterNode<N>
{
    fn include_node(&self, node: N) -> bool { let _ = node; true }
}

impl<F, N> FilterNode<N> for F
    where F: Fn(N) -> bool,
{
    fn include_node(&self, n: N) -> bool {
        (*self)(n)
    }
}

/// This filter includes the nodes that are contained in the set.
impl<N> FilterNode<N> for FixedBitSet
    where FixedBitSet: VisitMap<N>,
{
    fn include_node(&self, n: N) -> bool {
        self.is_visited(&n)
    }
}

/// This filter includes the nodes that are contained in the set.
impl<N, S> FilterNode<N> for HashSet<N, S>
    where HashSet<N, S>: VisitMap<N>,
{
    fn include_node(&self, n: N) -> bool {
        self.is_visited(&n)
    }
}

/// A node-filtered adaptor of a graph.
#[derive(Copy, Clone, Debug)]
pub struct NodeFiltered<G, F>(pub G, pub F);

impl<F, G> NodeFiltered<G, F>
    where G: GraphBase,
          F: Fn(G::NodeId) -> bool,
{
    /// Create an `NodeFiltered` adaptor from the closure `filter`.
    pub fn from_fn(graph: G, filter: F) -> Self {
        NodeFiltered(graph, filter)
    }
}

impl<G, F> GraphBase for NodeFiltered<G, F> where G: GraphBase {
    type NodeId = G::NodeId;
    type EdgeId = G::EdgeId;
}

impl<'a, G, F> IntoNeighbors for &'a NodeFiltered<G, F>
    where G: IntoNeighbors,
          F: FilterNode<G::NodeId>,
{
    type Neighbors = NodeFilteredNeighbors<'a, G::Neighbors, F>;
    fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
        NodeFilteredNeighbors {
            include_source: self.1.include_node(n),
            iter: self.0.neighbors(n),
            f: &self.1,
        }
    }
}

/// A filtered neighbors iterator.
pub struct NodeFilteredNeighbors<'a, I, F: 'a>
{
    include_source: bool,
    iter: I,
    f: &'a F,
}

impl<'a, I, F> Iterator for NodeFilteredNeighbors<'a, I, F>
    where I: Iterator,
          I::Item: Copy,
          F: FilterNode<I::Item>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        if !self.include_source {
            None
        } else {
            (&mut self.iter).filter(move |&target| f.include_node(target)).next()
        }
    }
}

impl<'a, G, F> IntoNeighborsDirected for &'a NodeFiltered<G, F>
    where G: IntoNeighborsDirected,
          F: FilterNode<G::NodeId>,
{
    type NeighborsDirected = NodeFilteredNeighbors<'a, G::NeighborsDirected, F>;
    fn neighbors_directed(self, n: G::NodeId, dir: Direction)
        -> Self::NeighborsDirected {
        NodeFilteredNeighbors {
            include_source: self.1.include_node(n),
            iter: self.0.neighbors_directed(n, dir),
            f: &self.1,
        }
    }
}

impl<'a, G, F> IntoNodeIdentifiers for &'a NodeFiltered<G, F>
    where G: IntoNodeIdentifiers,
          F: FilterNode<G::NodeId>,
{
    type NodeIdentifiers = NodeFilteredNeighbors<'a, G::NodeIdentifiers, F>;
    fn node_identifiers(self) -> Self::NodeIdentifiers {
        NodeFilteredNeighbors {
            include_source: true,
            iter: self.0.node_identifiers(),
            f: &self.1,
        }
    }
}

impl<'a, G, F> IntoEdgeReferences for &'a NodeFiltered<G, F>
    where G: IntoEdgeReferences,
          F: FilterNode<G::NodeId>,
{
    type EdgeRef = G::EdgeRef;
    type EdgeReferences = NodeFilteredEdgeReferences<'a, G, G::EdgeReferences, F>;
    fn edge_references(self) -> Self::EdgeReferences {
        NodeFilteredEdgeReferences {
            graph: PhantomData,
            iter: self.0.edge_references(),
            f: &self.1,
        }
    }
}

/// A filtered iterator
pub struct NodeFilteredEdgeReferences<'a, G, I, F: 'a>
{
    graph: PhantomData<G>,
    iter: I,
    f: &'a F,
}

impl<'a, G, I, F> Iterator for NodeFilteredEdgeReferences<'a, G, I, F>
    where F: FilterNode<G::NodeId>,
          G: IntoEdgeReferences,
          I: Iterator<Item=G::EdgeRef>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        (&mut self.iter).filter(move |&edge|
            f.include_node(edge.source()) && f.include_node(edge.target())
        ).next()
    }
}

impl<'a, G, F> IntoEdges for &'a NodeFiltered<G, F>
    where G: IntoEdges,
          F: FilterNode<G::NodeId>,
{
    type Edges = NodeFilteredEdges<'a, G, G::Edges, F>;
    fn edges(self, a: G::NodeId) -> Self::Edges {
        NodeFilteredEdges {
            graph: PhantomData,
            include_source: self.1.include_node(a),
            iter: self.0.edges(a),
            f: &self.1,
        }
    }
}

/// A filtered iterator
pub struct NodeFilteredEdges<'a, G, I, F: 'a>
{
    graph: PhantomData<G>,
    include_source: bool,
    iter: I,
    f: &'a F,
}

impl<'a, G, I, F> Iterator for NodeFilteredEdges<'a, G, I, F>
    where F: FilterNode<G::NodeId>,
          G: IntoEdges,
          I: Iterator<Item=G::EdgeRef>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        if !self.include_source {
            None
        } else {
            let f = self.f;
            (&mut self.iter).filter(move |&edge|
                                    f.include_node(edge.target())).next()
        }
    }
}

impl<G, F> DataMap for NodeFiltered<G, F>
    where G: DataMap,
          F: FilterNode<G::NodeId>,
{
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
        if self.1.include_node(id) {
            self.0.node_weight(id)
        } else {
            None
        }
    }

    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
        self.0.edge_weight(id)
    }
}

macro_rules! access0 {
    ($e:expr) => ($e.0)
}

Data!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
NodeIndexable!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
GraphProp!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
Visitable!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}

/// A graph filter for edges
pub trait FilterEdge<Edge>
{
    /// The default implementation is to include all edges
    fn include_edge(&self, edge: Edge) -> bool { let _ = edge; true }
}

impl<F, N> FilterEdge<N> for F
    where F: Fn(N) -> bool,
{
    fn include_edge(&self, n: N) -> bool {
        (*self)(n)
    }
}

/// An edge-filtered adaptor of a graph.
///
/// The adaptor may filter out edges. The filter implements the trait
/// `FilterEdge`. Closures of type `Fn(G::EdgeRef) -> bool` already
/// implement this trait.
///
/// The filter may use edge source, target, id, and weight to select whether to
/// include the edge or not.
#[derive(Copy, Clone, Debug)]
pub struct EdgeFiltered<G, F>(pub G, pub F);

impl<F, G> EdgeFiltered<G, F>
    where G: IntoEdgeReferences,
          F: Fn(G::EdgeRef) -> bool,
{
    /// Create an `EdgeFiltered` adaptor from the closure `filter`.
    pub fn from_fn(graph: G, filter: F) -> Self {
        EdgeFiltered(graph, filter)
    }
}

impl<G, F> GraphBase for EdgeFiltered<G, F> where G: GraphBase {
    type NodeId = G::NodeId;
    type EdgeId = G::EdgeId;
}

impl<'a, G, F> IntoNeighbors for &'a EdgeFiltered<G, F>
    where G: IntoEdges,
          F: FilterEdge<G::EdgeRef>,
{
    type Neighbors = EdgeFilteredNeighbors<'a, G, F>;
    fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
        EdgeFilteredNeighbors {
            iter: self.0.edges(n),
            f: &self.1,
        }
    }
}

/// A filtered neighbors iterator.
pub struct EdgeFilteredNeighbors<'a, G, F: 'a>
    where G: IntoEdges,
{
    iter: G::Edges,
    f: &'a F,
}

impl<'a, G, F> Iterator for EdgeFilteredNeighbors<'a, G, F>
    where F: FilterEdge<G::EdgeRef>,
          G: IntoEdges,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        (&mut self.iter).filter_map(move |edge| {
            if f.include_edge(edge) {
                Some(edge.target())
            } else { None }
        }).next()
    }
}

impl<'a, G, F> IntoEdgeReferences for &'a EdgeFiltered<G, F>
    where G: IntoEdgeReferences,
          F: FilterEdge<G::EdgeRef>,
{
    type EdgeRef = G::EdgeRef;
    type EdgeReferences = EdgeFilteredEdges<'a, G, G::EdgeReferences, F>;
    fn edge_references(self) -> Self::EdgeReferences {
        EdgeFilteredEdges {
            graph: PhantomData,
            iter: self.0.edge_references(),
            f: &self.1,
        }
    }
}

impl<'a, G, F> IntoEdges for &'a EdgeFiltered<G, F>
    where G: IntoEdges,
          F: FilterEdge<G::EdgeRef>,
{
    type Edges = EdgeFilteredEdges<'a, G, G::Edges, F>;
    fn edges(self, n: G::NodeId) -> Self::Edges {
        EdgeFilteredEdges {
            graph: PhantomData,
            iter: self.0.edges(n),
            f: &self.1,
        }
    }
}

/// A filtered edges iterator
pub struct EdgeFilteredEdges<'a, G, I, F: 'a>
{
    graph: PhantomData<G>,
    iter: I,
    f: &'a F,
}

impl<'a, G, I, F> Iterator for EdgeFilteredEdges<'a, G, I, F>
    where F: FilterEdge<G::EdgeRef>,
          G: IntoEdgeReferences,
          I: Iterator<Item=G::EdgeRef>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        (&mut self.iter).filter(move |&edge| f.include_edge(edge)).next()
    }
}

Data!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
GraphProp!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
IntoNodeIdentifiers!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
IntoNodeReferences!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
NodeCompactIndexable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
NodeCount!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
NodeIndexable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
Visitable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
<commit_msg>filtered: No default impls for the filter traits<commit_after>
use prelude::*;

use fixedbitset::FixedBitSet;
use std::collections::HashSet;
use std::marker::PhantomData;

use visit::{
    GraphBase,
    IntoNeighbors,
    IntoNodeIdentifiers,
    IntoNodeReferences,
    IntoNeighborsDirected,
    NodeIndexable,
    Visitable,
    VisitMap,
    GraphProp,
    IntoEdges,
    IntoEdgeReferences,
};
use visit::{Data, NodeCompactIndexable, NodeCount};
use data::{DataMap};

/// A graph filter for nodes.
pub trait FilterNode<N>
{
    /// Return true to have the node be part of the graph
    fn include_node(&self, node: N) -> bool;
}

impl<F, N> FilterNode<N> for F
    where F: Fn(N) -> bool,
{
    fn include_node(&self, n: N) -> bool {
        (*self)(n)
    }
}

/// This filter includes the nodes that are contained in the set.
impl<N> FilterNode<N> for FixedBitSet
    where FixedBitSet: VisitMap<N>,
{
    fn include_node(&self, n: N) -> bool {
        self.is_visited(&n)
    }
}

/// This filter includes the nodes that are contained in the set.
impl<N, S> FilterNode<N> for HashSet<N, S>
    where HashSet<N, S>: VisitMap<N>,
{
    fn include_node(&self, n: N) -> bool {
        self.is_visited(&n)
    }
}

/// A node-filtered adaptor of a graph.
#[derive(Copy, Clone, Debug)]
pub struct NodeFiltered<G, F>(pub G, pub F);

impl<F, G> NodeFiltered<G, F>
    where G: GraphBase,
          F: Fn(G::NodeId) -> bool,
{
    /// Create an `NodeFiltered` adaptor from the closure `filter`.
    pub fn from_fn(graph: G, filter: F) -> Self {
        NodeFiltered(graph, filter)
    }
}

impl<G, F> GraphBase for NodeFiltered<G, F> where G: GraphBase {
    type NodeId = G::NodeId;
    type EdgeId = G::EdgeId;
}

impl<'a, G, F> IntoNeighbors for &'a NodeFiltered<G, F>
    where G: IntoNeighbors,
          F: FilterNode<G::NodeId>,
{
    type Neighbors = NodeFilteredNeighbors<'a, G::Neighbors, F>;
    fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
        NodeFilteredNeighbors {
            include_source: self.1.include_node(n),
            iter: self.0.neighbors(n),
            f: &self.1,
        }
    }
}

/// A filtered neighbors iterator.
pub struct NodeFilteredNeighbors<'a, I, F: 'a>
{
    include_source: bool,
    iter: I,
    f: &'a F,
}

impl<'a, I, F> Iterator for NodeFilteredNeighbors<'a, I, F>
    where I: Iterator,
          I::Item: Copy,
          F: FilterNode<I::Item>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        if !self.include_source {
            None
        } else {
            (&mut self.iter).filter(move |&target| f.include_node(target)).next()
        }
    }
}

impl<'a, G, F> IntoNeighborsDirected for &'a NodeFiltered<G, F>
    where G: IntoNeighborsDirected,
          F: FilterNode<G::NodeId>,
{
    type NeighborsDirected = NodeFilteredNeighbors<'a, G::NeighborsDirected, F>;
    fn neighbors_directed(self, n: G::NodeId, dir: Direction)
        -> Self::NeighborsDirected {
        NodeFilteredNeighbors {
            include_source: self.1.include_node(n),
            iter: self.0.neighbors_directed(n, dir),
            f: &self.1,
        }
    }
}

impl<'a, G, F> IntoNodeIdentifiers for &'a NodeFiltered<G, F>
    where G: IntoNodeIdentifiers,
          F: FilterNode<G::NodeId>,
{
    type NodeIdentifiers = NodeFilteredNeighbors<'a, G::NodeIdentifiers, F>;
    fn node_identifiers(self) -> Self::NodeIdentifiers {
        NodeFilteredNeighbors {
            include_source: true,
            iter: self.0.node_identifiers(),
            f: &self.1,
        }
    }
}

impl<'a, G, F> IntoEdgeReferences for &'a NodeFiltered<G, F>
    where G: IntoEdgeReferences,
          F: FilterNode<G::NodeId>,
{
    type EdgeRef = G::EdgeRef;
    type EdgeReferences = NodeFilteredEdgeReferences<'a, G, G::EdgeReferences, F>;
    fn edge_references(self) -> Self::EdgeReferences {
        NodeFilteredEdgeReferences {
            graph: PhantomData,
            iter: self.0.edge_references(),
            f: &self.1,
        }
    }
}

/// A filtered iterator
pub struct NodeFilteredEdgeReferences<'a, G, I, F: 'a>
{
    graph: PhantomData<G>,
    iter: I,
    f: &'a F,
}

impl<'a, G, I, F> Iterator for NodeFilteredEdgeReferences<'a, G, I, F>
    where F: FilterNode<G::NodeId>,
          G: IntoEdgeReferences,
          I: Iterator<Item=G::EdgeRef>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        (&mut self.iter).filter(move |&edge|
            f.include_node(edge.source()) && f.include_node(edge.target())
        ).next()
    }
}

impl<'a, G, F> IntoEdges for &'a NodeFiltered<G, F>
    where G: IntoEdges,
          F: FilterNode<G::NodeId>,
{
    type Edges = NodeFilteredEdges<'a, G, G::Edges, F>;
    fn edges(self, a: G::NodeId) -> Self::Edges {
        NodeFilteredEdges {
            graph: PhantomData,
            include_source: self.1.include_node(a),
            iter: self.0.edges(a),
            f: &self.1,
        }
    }
}

/// A filtered iterator
pub struct NodeFilteredEdges<'a, G, I, F: 'a>
{
    graph: PhantomData<G>,
    include_source: bool,
    iter: I,
    f: &'a F,
}

impl<'a, G, I, F> Iterator for NodeFilteredEdges<'a, G, I, F>
    where F: FilterNode<G::NodeId>,
          G: IntoEdges,
          I: Iterator<Item=G::EdgeRef>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        if !self.include_source {
            None
        } else {
            let f = self.f;
            (&mut self.iter).filter(move |&edge|
                                    f.include_node(edge.target())).next()
        }
    }
}

impl<G, F> DataMap for NodeFiltered<G, F>
    where G: DataMap,
          F: FilterNode<G::NodeId>,
{
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
        if self.1.include_node(id) {
            self.0.node_weight(id)
        } else {
            None
        }
    }

    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
        self.0.edge_weight(id)
    }
}

macro_rules! access0 {
    ($e:expr) => ($e.0)
}

Data!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
NodeIndexable!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
GraphProp!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
Visitable!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}

/// A graph filter for edges
pub trait FilterEdge<Edge> {
    /// Return true to have the edge be part of the graph
    fn include_edge(&self, edge: Edge) -> bool;
}

impl<F, N> FilterEdge<N> for F
    where F: Fn(N) -> bool,
{
    fn include_edge(&self, n: N) -> bool {
        (*self)(n)
    }
}

/// An edge-filtered adaptor of a graph.
///
/// The adaptor may filter out edges. The filter implements the trait
/// `FilterEdge`. Closures of type `Fn(G::EdgeRef) -> bool` already
/// implement this trait.
///
/// The filter may use edge source, target, id, and weight to select whether to
/// include the edge or not.
#[derive(Copy, Clone, Debug)]
pub struct EdgeFiltered<G, F>(pub G, pub F);

impl<F, G> EdgeFiltered<G, F>
    where G: IntoEdgeReferences,
          F: Fn(G::EdgeRef) -> bool,
{
    /// Create an `EdgeFiltered` adaptor from the closure `filter`.
    pub fn from_fn(graph: G, filter: F) -> Self {
        EdgeFiltered(graph, filter)
    }
}

impl<G, F> GraphBase for EdgeFiltered<G, F> where G: GraphBase {
    type NodeId = G::NodeId;
    type EdgeId = G::EdgeId;
}

impl<'a, G, F> IntoNeighbors for &'a EdgeFiltered<G, F>
    where G: IntoEdges,
          F: FilterEdge<G::EdgeRef>,
{
    type Neighbors = EdgeFilteredNeighbors<'a, G, F>;
    fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
        EdgeFilteredNeighbors {
            iter: self.0.edges(n),
            f: &self.1,
        }
    }
}

/// A filtered neighbors iterator.
pub struct EdgeFilteredNeighbors<'a, G, F: 'a>
    where G: IntoEdges,
{
    iter: G::Edges,
    f: &'a F,
}

impl<'a, G, F> Iterator for EdgeFilteredNeighbors<'a, G, F>
    where F: FilterEdge<G::EdgeRef>,
          G: IntoEdges,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        (&mut self.iter).filter_map(move |edge| {
            if f.include_edge(edge) {
                Some(edge.target())
            } else { None }
        }).next()
    }
}

impl<'a, G, F> IntoEdgeReferences for &'a EdgeFiltered<G, F>
    where G: IntoEdgeReferences,
          F: FilterEdge<G::EdgeRef>,
{
    type EdgeRef = G::EdgeRef;
    type EdgeReferences = EdgeFilteredEdges<'a, G, G::EdgeReferences, F>;
    fn edge_references(self) -> Self::EdgeReferences {
        EdgeFilteredEdges {
            graph: PhantomData,
            iter: self.0.edge_references(),
            f: &self.1,
        }
    }
}

impl<'a, G, F> IntoEdges for &'a EdgeFiltered<G, F>
    where G: IntoEdges,
          F: FilterEdge<G::EdgeRef>,
{
    type Edges = EdgeFilteredEdges<'a, G, G::Edges, F>;
    fn edges(self, n: G::NodeId) -> Self::Edges {
        EdgeFilteredEdges {
            graph: PhantomData,
            iter: self.0.edges(n),
            f: &self.1,
        }
    }
}

/// A filtered edges iterator
pub struct EdgeFilteredEdges<'a, G, I, F: 'a>
{
    graph: PhantomData<G>,
    iter: I,
    f: &'a F,
}

impl<'a, G, I, F> Iterator for EdgeFilteredEdges<'a, G, I, F>
    where F: FilterEdge<G::EdgeRef>,
          G: IntoEdgeReferences,
          I: Iterator<Item=G::EdgeRef>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let f = self.f;
        (&mut self.iter).filter(move |&edge| f.include_edge(edge)).next()
    }
}

Data!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
GraphProp!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
IntoNodeIdentifiers!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
IntoNodeReferences!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
NodeCompactIndexable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
NodeCount!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
NodeIndexable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
Visitable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
<|endoftext|>


<commit_before>extern crate kernel32;
/// meminfo
///
/// A tool to show memory content of processes
///
extern crate winapi;

use winapi::{
    DWORD, HANDLE, LPSYSTEM_INFO, LPVOID, MEMORY_BASIC_INFORMATION, PVOID, SIZE_T, SYSTEM_INFO,
};

fn main() {
    let this_pid: DWORD;
    let this_proc: HANDLE;
    let min_app_addr: LPVOID;
    let max_app_addr: LPVOID;

    let mut base_addr: PVOID;
    let mut proc_info: SYSTEM_INFO;
    let mut mem_info: MEMORY_BASIC_INFORMATION;

    const MEM_SIZE: usize = std::mem::size_of::<MEMORY_BASIC_INFORMATION>();

    // init mutable values
    unsafe {
        base_addr = std::mem::zeroed();
        proc_info = std::mem::zeroed();
        mem_info = std::mem::zeroed();
    }

    // get current process
    unsafe {
        this_pid = kernel32::GetCurrentProcessId();
        this_proc = kernel32::GetCurrentProcess();
        kernel32::GetSystemInfo(&mut proc_info as LPSYSTEM_INFO);
    }

    min_app_addr = proc_info.lpMinimumApplicationAddress;
    max_app_addr = proc_info.lpMaximumApplicationAddress;

    println!("{:?} @ {:p}", this_pid, this_proc);
    println!("{:?}", proc_info);
    println!("min: {:p}, max: {:p}", min_app_addr, max_app_addr);
}
<commit_msg>scan thru process memory<commit_after>extern crate kernel32;
/// meminfo
///
/// A tool to show memory content of processes
///
extern crate winapi;

use winapi::{
    DWORD, HANDLE, LPSYSTEM_INFO, LPVOID, MEMORY_BASIC_INFORMATION, PVOID, SIZE_T, SYSTEM_INFO,
};

fn main() {
    let this_pid: DWORD;
    let this_proc: HANDLE;
    let min_app_addr: LPVOID;
    let max_app_addr: LPVOID;

    let mut base_addr: PVOID;
    let mut proc_info: SYSTEM_INFO;
    let mut mem_info: MEMORY_BASIC_INFORMATION;

    const MEM_SIZE: usize = std::mem::size_of::<MEMORY_BASIC_INFORMATION>();

    // init mutable values
    unsafe {
        base_addr = std::mem::zeroed();
        proc_info = std::mem::zeroed();
        mem_info = std::mem::zeroed();
    }

    // get current process
    unsafe {
        this_pid = kernel32::GetCurrentProcessId();
        this_proc = kernel32::GetCurrentProcess();
        kernel32::GetSystemInfo(&mut proc_info as LPSYSTEM_INFO);
    }

    min_app_addr = proc_info.lpMinimumApplicationAddress;
    max_app_addr = proc_info.lpMaximumApplicationAddress;

    println!("{:?} @ {:p}", this_pid, this_proc);
    println!("{:?}", proc_info);
    println!("min: {:p}, max: {:p}", min_app_addr, max_app_addr);

    // scan thu process memory space
    loop {
        let rc: SIZE_T = unsafe {
            kernel32::VirtualQueryEx(this_proc, base_addr, &mut mem_info, MEM_SIZE as SIZE_T)
        };
        if rc == 0 {
            break;
        }

        println!("{:?}", mem_info);
        base_addr = ((base_addr as u64) + mem_info.RegionSize) as PVOID;
    }
}
<|endoftext|>


<commit_before>// Copyright 2021 The Chromium OS Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! Structs for VFIO listener and endpoint.

use std::convert::From;
use std::fs::File;
use std::io::{IoSlice, IoSliceMut};
use std::marker::PhantomData;
use std::os::unix::io::RawFd;
use std::path::Path;

use base::{AsRawDescriptor, Event, RawDescriptor};
use remain::sorted;
use thiserror::Error as ThisError;

use super::{Error, Result};
use crate::connection::{Endpoint as EndpointTrait, Listener as ListenerTrait, Req};

/// Errors for `Device::recv_into_bufs()`.
#[sorted]
#[derive(Debug, ThisError)]
pub enum RecvIntoBufsError {
    /// Connection is closed.
    #[error("connection is closed")]
    Disconnect,
    /// Fatal error while receiving data.
    #[error("failed to receive data via VFIO: {0:#}")]
    Fatal(anyhow::Error),
}

impl From<RecvIntoBufsError> for Error {
    fn from(e: RecvIntoBufsError) -> Self {
        match e {
            RecvIntoBufsError::Disconnect => Error::Disconnect,
            RecvIntoBufsError::Fatal(e) => Error::VfioDeviceError(e),
        }
    }
}

/// VFIO device which can be used as virtio-vhost-user device backend.
pub trait Device {
    /// This event must be read before handle_request() is called.
    fn event(&self) -> &Event;

    /// Starts VFIO device.
    fn start(&mut self) -> std::result::Result<(), anyhow::Error>;

    /// Sends data in the given slice of slices.
    fn send_bufs(
        &mut self,
        iovs: &[IoSlice],
        fds: Option<&[RawFd]>,
    ) -> std::result::Result<usize, anyhow::Error>;

    /// Receives data into the given slice of slices and returns the size of the received data.
    fn recv_into_bufs(
        &mut self,
        iovs: &mut [IoSliceMut],
    ) -> std::result::Result<usize, RecvIntoBufsError>;
}

/// Listener for accepting incoming connections from virtio-vhost-user device through VFIO.
pub struct Listener<D: Device> {
    // device will be dropped when Listener::accept() is called.
    device: Option<D>,
}

impl<D: Device> Listener<D> {
    /// Creates a VFIO listener.
    pub fn new(device: D) -> Result<Self> {
        Ok(Self {
            device: Some(device),
        })
    }
}

impl<D: Device> ListenerTrait for Listener<D> {
    type Connection = D;

    fn accept(&mut self) -> Result<Option<Self::Connection>> {
        let mut device = self
            .device
            .take()
            .expect("Listener isn't initialized correctly");
        device.start().map_err(Error::VfioDeviceError)?;
        Ok(Some(device))
    }

    fn set_nonblocking(&self, _block: bool) -> Result<()> {
        unimplemented!("set_nonblocking");
    }
}

/// Endpoint for vhost-user connection through VFIO.
pub struct Endpoint<R: Req, D: Device> {
    device: D,
    _r: PhantomData<R>,
}

impl<R: Req, D: Device> EndpointTrait<R> for Endpoint<R, D> {
    type Listener = Listener<D>;

    /// Create an endpoint from a stream object.
    fn from_connection(device: D) -> Self {
        Self {
            device,
            _r: PhantomData,
        }
    }

    fn connect<P: AsRef<Path>>(_path: P) -> Result<Self> {
        // TODO: remove this method from Endpoint trait?
        panic!("VfioEndpoint cannot create a connection from path");
    }

    fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawFd]>) -> Result<usize> {
        self.device
            .send_bufs(iovs, fds)
            .map_err(Error::VfioDeviceError)
    }

    fn recv_into_bufs(
        &mut self,
        bufs: &mut [IoSliceMut],
        _allow_fd: bool, /* ignore, as VFIO doesn't receive FDs */
    ) -> Result<(usize, Option<Vec<File>>)> {
        let size = self
            .device
            .recv_into_bufs(bufs)
            .map_err::<Error, _>(From::<RecvIntoBufsError>::from)?;

        // VFIO backend doesn't receive any files.
        Ok((size, None))
    }
}

impl<R: Req, D: Device> AsRawDescriptor for Endpoint<R, D> {
    fn as_raw_descriptor(&self) -> RawDescriptor {
        self.device.event().as_raw_descriptor()
    }
}
<commit_msg>vmm_vhost: fix the VFIO implementation of set_nonblocking()<commit_after>// Copyright 2021 The Chromium OS Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! Structs for VFIO listener and endpoint.

use std::convert::From;
use std::fs::File;
use std::io::{IoSlice, IoSliceMut};
use std::marker::PhantomData;
use std::os::unix::io::RawFd;
use std::path::Path;

use base::{AsRawDescriptor, Event, RawDescriptor};
use remain::sorted;
use thiserror::Error as ThisError;

use super::{Error, Result};
use crate::connection::{Endpoint as EndpointTrait, Listener as ListenerTrait, Req};

/// Errors for `Device::recv_into_bufs()`.
#[sorted]
#[derive(Debug, ThisError)]
pub enum RecvIntoBufsError {
    /// Connection is closed.
    #[error("connection is closed")]
    Disconnect,
    /// Fatal error while receiving data.
    #[error("failed to receive data via VFIO: {0:#}")]
    Fatal(anyhow::Error),
}

impl From<RecvIntoBufsError> for Error {
    fn from(e: RecvIntoBufsError) -> Self {
        match e {
            RecvIntoBufsError::Disconnect => Error::Disconnect,
            RecvIntoBufsError::Fatal(e) => Error::VfioDeviceError(e),
        }
    }
}

/// VFIO device which can be used as virtio-vhost-user device backend.
pub trait Device {
    /// This event must be read before handle_request() is called.
    fn event(&self) -> &Event;

    /// Starts VFIO device.
    fn start(&mut self) -> std::result::Result<(), anyhow::Error>;

    /// Sends data in the given slice of slices.
    fn send_bufs(
        &mut self,
        iovs: &[IoSlice],
        fds: Option<&[RawFd]>,
    ) -> std::result::Result<usize, anyhow::Error>;

    /// Receives data into the given slice of slices and returns the size of the received data.
    fn recv_into_bufs(
        &mut self,
        iovs: &mut [IoSliceMut],
    ) -> std::result::Result<usize, RecvIntoBufsError>;
}

/// Listener for accepting incoming connections from virtio-vhost-user device through VFIO.
pub struct Listener<D: Device> {
    // device will be dropped when Listener::accept() is called.
    device: Option<D>,
}

impl<D: Device> Listener<D> {
    /// Creates a VFIO listener.
    pub fn new(device: D) -> Result<Self> {
        Ok(Self {
            device: Some(device),
        })
    }
}

impl<D: Device> ListenerTrait for Listener<D> {
    type Connection = D;

    fn accept(&mut self) -> Result<Option<Self::Connection>> {
        let mut device = self
            .device
            .take()
            .expect("Listener isn't initialized correctly");
        device.start().map_err(Error::VfioDeviceError)?;
        Ok(Some(device))
    }

    fn set_nonblocking(&self, _block: bool) -> Result<()> {
        // `accept` will never block on a VFIO connection.
        Ok(())
    }
}

/// Endpoint for vhost-user connection through VFIO.
pub struct Endpoint<R: Req, D: Device> {
    device: D,
    _r: PhantomData<R>,
}

impl<R: Req, D: Device> EndpointTrait<R> for Endpoint<R, D> {
    type Listener = Listener<D>;

    /// Create an endpoint from a stream object.
    fn from_connection(device: D) -> Self {
        Self {
            device,
            _r: PhantomData,
        }
    }

    fn connect<P: AsRef<Path>>(_path: P) -> Result<Self> {
        // TODO: remove this method from Endpoint trait?
        panic!("VfioEndpoint cannot create a connection from path");
    }

    fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawFd]>) -> Result<usize> {
        self.device
            .send_bufs(iovs, fds)
            .map_err(Error::VfioDeviceError)
    }

    fn recv_into_bufs(
        &mut self,
        bufs: &mut [IoSliceMut],
        _allow_fd: bool, /* ignore, as VFIO doesn't receive FDs */
    ) -> Result<(usize, Option<Vec<File>>)> {
        let size = self
            .device
            .recv_into_bufs(bufs)
            .map_err::<Error, _>(From::<RecvIntoBufsError>::from)?;

        // VFIO backend doesn't receive any files.
        Ok((size, None))
    }
}

impl<R: Req, D: Device> AsRawDescriptor for Endpoint<R, D> {
    fn as_raw_descriptor(&self) -> RawDescriptor {
        self.device.event().as_raw_descriptor()
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate futures;
extern crate fern;
#[macro_use]
extern crate json;
extern crate jsonwebtoken;
#[macro_use]
extern crate log;
extern crate tokio_core;
extern crate tokio_tungstenite;
extern crate tungstenite;
#[macro_use]
extern crate redis_async;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate structopt;
#[macro_use]
extern crate structopt_derive;
extern crate uuid;

pub mod auth;
pub mod cli;
pub mod config;
#[macro_use]
pub mod engine;
pub mod error;
pub mod logging;
pub mod proxy;

use cli::{CliOptions};
use config::{get_config};
use engine::{Engine};
use engine::router::{Router, extract_endpoints};
use structopt::StructOpt;
use logging::{setup_logger};
use proxy::{Proxy};

fn main() {
    let cli = CliOptions::from_args();
    match setup_logger(&cli) {
        Ok(_) => {},
        Err(err) => println!("Logger isn't instantiated: {}", err)
    };

    let config = get_config(&cli.config);
    let endpoints = extract_endpoints(config);
    let router = Box::new(Router::new(endpoints));
    let engine = Box::new(Engine::new(router));

    let proxy = Box::new(Proxy::new(engine, &cli));
    let address = format!("{}:{}", cli.ip, cli.port).parse().unwrap();
    proxy.run(address);
}
<commit_msg>Updated main.rs<commit_after>//! WebSocket-over-RabbitMQ reverse proxy
//!

extern crate chrono;
extern crate futures;
extern crate fern;
#[macro_use]
extern crate json;
extern crate jsonwebtoken;
#[macro_use]
extern crate log;
extern crate tokio_core;
extern crate tokio_tungstenite;
extern crate tungstenite;
#[macro_use]
extern crate redis_async;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate structopt;
#[macro_use]
extern crate structopt_derive;
extern crate uuid;

pub mod auth;
pub mod cli;
pub mod config;
#[macro_use]
pub mod engine;
pub mod error;
pub mod logging;
pub mod proxy;

use cli::{CliOptions};
use config::{get_config};
use engine::{Engine};
use engine::router::{Router, extract_endpoints};
use structopt::StructOpt;
use logging::{setup_logger};
use proxy::{Proxy};

fn main() {
    let cli = CliOptions::from_args();
    match setup_logger(&cli) {
        Ok(_) => {},
        Err(err) => println!("Logger isn't instantiated: {}", err)
    };

    let config = get_config(&cli.config);
    let endpoints = extract_endpoints(config);
    let router = Box::new(Router::new(endpoints));
    let engine = Box::new(Engine::new(router));

    let proxy = Box::new(Proxy::new(engine, &cli));
    let address = format!("{}:{}", cli.ip, cli.port).parse().unwrap();
    proxy.run(address);
}
<|endoftext|>