<commit_before>//! Contains traits responsible for the actual construction of SQL statements
//!
//! The types in this module are part of Diesel's public API, but are generally
//! only useful for implementing Diesel plugins. Applications should generally
//! not need to care about the types inside of this module.

#[macro_use]
mod query_id;
#[macro_use]
mod clause_macro;

mod ast_pass;
pub mod bind_collector;
pub(crate) mod combination_clause;
mod debug_query;
mod delete_statement;
mod distinct_clause;
pub(crate) mod from_clause;
pub(crate) mod functions;
mod group_by_clause;
mod having_clause;
pub(crate) mod insert_statement;
pub(crate) mod limit_clause;
pub(crate) mod limit_offset_clause;
pub(crate) mod locking_clause;
pub(crate) mod nodes;
pub(crate) mod offset_clause;
pub(crate) mod order_clause;
mod returning_clause;
pub(crate) mod select_clause;
pub(crate) mod select_statement;
mod sql_query;
pub(crate) mod update_statement;
pub(crate) mod upsert;
mod where_clause;

#[doc(inline)]
pub use self::ast_pass::AstPass;
#[doc(inline)]
pub use self::bind_collector::BindCollector;
#[doc(inline)]
pub use self::debug_query::DebugQuery;
#[doc(inline)]
pub use self::delete_statement::{BoxedDeleteStatement, DeleteStatement};
#[doc(inline)]
pub use self::insert_statement::{
    IncompleteInsertOrIgnoreStatement, IncompleteInsertStatement, IncompleteReplaceStatement,
    InsertOrIgnoreStatement, InsertStatement, ReplaceStatement,
};
#[doc(inline)]
pub use self::query_id::QueryId;
#[doc(inline)]
pub use self::sql_query::{BoxedSqlQuery, SqlQuery};
#[doc(inline)]
pub use self::upsert::on_conflict_target_decorations::DecoratableTarget;

#[doc(inline)]
pub use self::update_statement::changeset::AsChangeset;
#[doc(inline)]
pub use self::update_statement::target::{IntoUpdateTarget, UpdateTarget};
#[doc(inline)]
pub use self::update_statement::{BoxedUpdateStatement, UpdateStatement};

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::limit_clause::{LimitClause, NoLimitClause};
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::limit_offset_clause::{BoxedLimitOffsetClause, LimitOffsetClause};
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::offset_clause::{NoOffsetClause, OffsetClause};

#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
#[doc(inline)]
pub(crate) use self::insert_statement::batch_insert::BatchInsert;
#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::insert_statement::{UndecoratedInsertRecord, ValuesClause};

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
#[doc(inline)]
pub use self::insert_statement::DefaultValues;

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
#[doc(inline)]
pub use self::returning_clause::ReturningClause;

#[doc(inline)]
#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::select_clause::SelectClauseExpression;

#[doc(inline)]
#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::from_clause::{FromClause, NoFromClause};

pub(crate) use self::insert_statement::ColumnList;
pub(crate) use self::select_statement::BoxedSelectStatement;
pub(crate) use self::select_statement::SelectStatement;

#[cfg(feature = "postgres_backend")]
pub use crate::pg::query_builder::only::Only;

use crate::backend::{Backend, HasBindCollector};
use crate::result::QueryResult;
use std::error::Error;

#[doc(hidden)]
pub type Binds = Vec<Option<Vec<u8>>>;
/// A specialized Result type used with the query builder.
pub type BuildQueryResult = Result<(), Box<dyn Error + Send + Sync>>;

/// Constructs a SQL query from a Diesel AST.
///
/// The only reason you should ever need to interact with this trait is if you
/// are extending Diesel with support for a new backend. Plugins which extend
/// the query builder with new capabilities will interact with [`AstPass`]
/// instead.
///
pub trait QueryBuilder<DB: Backend> {
    /// Add `sql` to the end of the query being constructed.
    fn push_sql(&mut self, sql: &str);

    /// Quote `identifier`, and add it to the end of the query being
    /// constructed.
    fn push_identifier(&mut self, identifier: &str) -> QueryResult<()>;

    /// Add a placeholder for a bind parameter to the end of the query being
    /// constructed.
    fn push_bind_param(&mut self);

    /// Increases the internal counter for bind parameters without adding the
    /// bind parameter itself to the query
    fn push_bind_param_value_only(&mut self) {}

    /// Returns the constructed SQL query.
    fn finish(self) -> String;
}

/// A complete SQL query with a return type.
///
/// This can be a select statement, or a command such as `update` or `insert`
/// with a `RETURNING` clause. Unlike [`Expression`], types implementing this
/// trait are guaranteed to be executable on their own.
///
/// A type which doesn't implement this trait may still represent a complete SQL
/// query. For example, an `INSERT` statement without a `RETURNING` clause will
/// not implement this trait, but can still be executed.
///
/// [`Expression`]: crate::expression::Expression
pub trait Query {
    /// The SQL type that this query represents.
    ///
    /// This is the SQL type of the `SELECT` clause for select statements, and
    /// the SQL type of the `RETURNING` clause for insert, update, or delete
    /// statements.
    type SqlType;
}

impl<'a, T: Query> Query for &'a T {
    type SqlType = T::SqlType;
}

/// Indicates that a type is a `SELECT` statement.
///
/// This trait differs from `Query` in two ways:
/// - It is implemented only for select statements, rather than all queries
///   which return a value.
/// - It has looser constraints. A type implementing `SelectQuery` is known to
///   be potentially valid if used as a subselect, but it is not necessarily
///   able to be executed.
pub trait SelectQuery {
    /// The SQL type of the `SELECT` clause
    type SqlType;
}

/// An untyped fragment of SQL.
///
/// This may be a complete SQL command (such as an update statement without a
/// `RETURNING` clause), or a subsection (such as our internal types used to
/// represent a `WHERE` clause). Implementations of [`ExecuteDsl`] and
/// [`LoadQuery`] will generally require that this trait be implemented.
///
/// [`ExecuteDsl`]: crate::query_dsl::methods::ExecuteDsl
/// [`LoadQuery`]: crate::query_dsl::methods::LoadQuery
pub trait QueryFragment<DB: Backend, SP = self::private::NotSpecialized> {
    /// Walk over this `QueryFragment` for all passes.
    ///
    /// This method is where the actual behavior of an AST node is implemented.
    /// This method will contain the behavior required for all possible AST
    /// passes. See [`AstPass`] for more details.
    ///
    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()>;

    /// Converts this `QueryFragment` to its SQL representation.
    ///
    /// This method should only be called by implementations of `Connection`.
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn to_sql(&self, out: &mut DB::QueryBuilder, backend: &DB) -> QueryResult<()> {
        self.walk_ast(AstPass::to_sql(out, backend))
    }

    /// Serializes all bind parameters in this query.
    ///
    /// A bind parameter is a value which is sent separately from the query
    /// itself. It is represented in SQL with a placeholder such as `?` or `$1`.
    ///
    /// This method should only be called by implementations of `Connection`.
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn collect_binds<'b>(
        &'b self,
        out: &mut <DB as HasBindCollector<'b>>::BindCollector,
        metadata_lookup: &mut DB::MetadataLookup,
        backend: &'b DB,
    ) -> QueryResult<()> {
        self.walk_ast(AstPass::collect_binds(out, metadata_lookup, backend))
    }

    /// Is this query safe to store in the prepared statement cache?
    ///
    /// In order to keep our prepared statement cache at a reasonable size, we
    /// avoid caching any queries which represent a potentially unbounded number
    /// of SQL queries. Generally this will only return `true` for queries for
    /// which `to_sql` will always construct exactly identical SQL.
    ///
    /// Some examples of where this method will return `false` are:
    ///
    /// - `SqlLiteral` (We don't know if the SQL was constructed dynamically, so
    ///   we must assume that it was)
    /// - `In` and `NotIn` (Each value requires a separate bind param
    ///   placeholder)
    ///
    /// This method should only be called by implementations of `Connection`.
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn is_safe_to_cache_prepared(&self, backend: &DB) -> QueryResult<bool> {
        let mut result = true;
        self.walk_ast(AstPass::is_safe_to_cache_prepared(&mut result, backend))?;
        Ok(result)
    }

    /// Does walking this AST have any effect?
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn is_noop(&self, backend: &DB) -> QueryResult<bool> {
        let mut result = true;
        self.walk_ast(AstPass::is_noop(&mut result, backend))?;
        Ok(result)
    }
}

impl<T: ?Sized, DB> QueryFragment<DB> for Box<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<'a, T: ?Sized, DB> QueryFragment<DB> for &'a T
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<DB: Backend> QueryFragment<DB> for () {
    fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<T, DB> QueryFragment<DB> for Option<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        match *self {
            Some(ref c) => c.walk_ast(out),
            None => Ok(()),
        }
    }
}

/// A trait used to construct type erased boxed variant of the current query node
///
/// Mainly useful for implementing third party backends
pub trait IntoBoxedClause<'a, DB> {
    /// Resulting type
    type BoxedClause;

    /// Convert the given query node in it's boxed representation
    fn into_boxed(self) -> Self::BoxedClause;
}

/// Types that can be converted into a complete, typed SQL query.
///
/// This is used internally to automatically add the right select clause when
/// none is specified, or to automatically add `RETURNING *` in certain contexts.
///
/// A type which implements this trait is guaranteed to be valid for execution.
pub trait AsQuery {
    /// The SQL type of `Self::Query`
    type SqlType;

    /// What kind of query does this type represent?
    type Query: Query<SqlType = Self::SqlType>;

    /// Converts a type which semantically represents a SQL query into the
    /// actual query being executed. See the trait level docs for more.
    // This method is part of our public API,
    // so we won't change the name to just appease clippy
    // (Also the trait is literally named `AsQuery` so
    // naming the method similary is fine)
    #[allow(clippy::wrong_self_convention)]
    fn as_query(self) -> Self::Query;
}

/// Takes a query `QueryFragment` expression as an argument and returns a type
/// that implements `fmt::Display` and `fmt::Debug` to show the query.
///
/// The `Display` implementation will show the exact query being sent to the
/// server, with a comment showing the values of the bind parameters. The
/// `Debug` implementation will include the same information in a more
/// structured form, and respects pretty printing.
///
/// # Example
///
/// ### Returning SQL from a count statement:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # use diesel::*;
/// # use schema::*;
/// #
/// # fn main() {
/// #   use schema::users::dsl::*;
/// let sql = debug_query::<DB, _>(&users.count()).to_string();
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(sql, r#"SELECT COUNT(*) FROM "users" -- binds: []"#);
/// # } else {
/// assert_eq!(sql, "SELECT COUNT(*) FROM `users` -- binds: []");
/// # }
///
/// let query = users.find(1);
/// let debug = debug_query::<DB, _>(&query);
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(debug.to_string(), "SELECT \"users\".\"id\", \"users\".\"name\" \
/// #         FROM \"users\" WHERE (\"users\".\"id\" = $1) -- binds: [1]");
/// # } else {
/// assert_eq!(debug.to_string(), "SELECT `users`.`id`, `users`.`name` FROM `users` \
///     WHERE (`users`.`id` = ?) -- binds: [1]");
/// # }
///
/// let debug = format!("{:?}", debug);
/// # if !cfg!(feature = "postgres") { // Escaping that string is a pain
/// let expected = "Query { \
///     sql: \"SELECT `users`.`id`, `users`.`name` FROM `users` WHERE \
///         (`users`.`id` = ?)\", \
///     binds: [1] \
/// }";
/// assert_eq!(debug, expected);
/// # }
/// # }
/// ```
pub fn debug_query<DB, T>(query: &T) -> DebugQuery<'_, T, DB> {
    DebugQuery::new(query)
}

mod private {
    #[allow(missing_debug_implementations, missing_copy_implementations)]
    pub struct NotSpecialized;
}
<commit_msg>Also replace `Self` with `T` for `impl<T: Query> AsQuery for T`<commit_after>//! Contains traits responsible for the actual construction of SQL statements
//!
//! The types in this module are part of Diesel's public API, but are generally
//! only useful for implementing Diesel plugins. Applications should generally
//! not need to care about the types inside of this module.

#[macro_use]
mod query_id;
#[macro_use]
mod clause_macro;

mod ast_pass;
pub mod bind_collector;
pub(crate) mod combination_clause;
mod debug_query;
mod delete_statement;
mod distinct_clause;
pub(crate) mod from_clause;
pub(crate) mod functions;
mod group_by_clause;
mod having_clause;
pub(crate) mod insert_statement;
pub(crate) mod limit_clause;
pub(crate) mod limit_offset_clause;
pub(crate) mod locking_clause;
pub(crate) mod nodes;
pub(crate) mod offset_clause;
pub(crate) mod order_clause;
mod returning_clause;
pub(crate) mod select_clause;
pub(crate) mod select_statement;
mod sql_query;
pub(crate) mod update_statement;
pub(crate) mod upsert;
mod where_clause;

#[doc(inline)]
pub use self::ast_pass::AstPass;
#[doc(inline)]
pub use self::bind_collector::BindCollector;
#[doc(inline)]
pub use self::debug_query::DebugQuery;
#[doc(inline)]
pub use self::delete_statement::{BoxedDeleteStatement, DeleteStatement};
#[doc(inline)]
pub use self::insert_statement::{
    IncompleteInsertOrIgnoreStatement, IncompleteInsertStatement, IncompleteReplaceStatement,
    InsertOrIgnoreStatement, InsertStatement, ReplaceStatement,
};
#[doc(inline)]
pub use self::query_id::QueryId;
#[doc(inline)]
pub use self::sql_query::{BoxedSqlQuery, SqlQuery};
#[doc(inline)]
pub use self::upsert::on_conflict_target_decorations::DecoratableTarget;

#[doc(inline)]
pub use self::update_statement::changeset::AsChangeset;
#[doc(inline)]
pub use self::update_statement::target::{IntoUpdateTarget, UpdateTarget};
#[doc(inline)]
pub use self::update_statement::{BoxedUpdateStatement, UpdateStatement};

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::limit_clause::{LimitClause, NoLimitClause};
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::limit_offset_clause::{BoxedLimitOffsetClause, LimitOffsetClause};
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::offset_clause::{NoOffsetClause, OffsetClause};

#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
#[doc(inline)]
pub(crate) use self::insert_statement::batch_insert::BatchInsert;
#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::insert_statement::{UndecoratedInsertRecord, ValuesClause};

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
#[doc(inline)]
pub use self::insert_statement::DefaultValues;

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
#[doc(inline)]
pub use self::returning_clause::ReturningClause;

#[doc(inline)]
#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::select_clause::SelectClauseExpression;

#[doc(inline)]
#[diesel_derives::__diesel_public_if(
    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::from_clause::{FromClause, NoFromClause};

pub(crate) use self::insert_statement::ColumnList;
pub(crate) use self::select_statement::BoxedSelectStatement;
pub(crate) use self::select_statement::SelectStatement;

#[cfg(feature = "postgres_backend")]
pub use crate::pg::query_builder::only::Only;

use crate::backend::{Backend, HasBindCollector};
use crate::result::QueryResult;
use std::error::Error;

#[doc(hidden)]
pub type Binds = Vec<Option<Vec<u8>>>;
/// A specialized Result type used with the query builder.
pub type BuildQueryResult = Result<(), Box<dyn Error + Send + Sync>>;

/// Constructs a SQL query from a Diesel AST.
///
/// The only reason you should ever need to interact with this trait is if you
/// are extending Diesel with support for a new backend. Plugins which extend
/// the query builder with new capabilities will interact with [`AstPass`]
/// instead.
///
pub trait QueryBuilder<DB: Backend> {
    /// Add `sql` to the end of the query being constructed.
    fn push_sql(&mut self, sql: &str);

    /// Quote `identifier`, and add it to the end of the query being
    /// constructed.
    fn push_identifier(&mut self, identifier: &str) -> QueryResult<()>;

    /// Add a placeholder for a bind parameter to the end of the query being
    /// constructed.
    fn push_bind_param(&mut self);

    /// Increases the internal counter for bind parameters without adding the
    /// bind parameter itself to the query
    fn push_bind_param_value_only(&mut self) {}

    /// Returns the constructed SQL query.
    fn finish(self) -> String;
}

/// A complete SQL query with a return type.
///
/// This can be a select statement, or a command such as `update` or `insert`
/// with a `RETURNING` clause. Unlike [`Expression`], types implementing this
/// trait are guaranteed to be executable on their own.
///
/// A type which doesn't implement this trait may still represent a complete SQL
/// query. For example, an `INSERT` statement without a `RETURNING` clause will
/// not implement this trait, but can still be executed.
///
/// [`Expression`]: crate::expression::Expression
pub trait Query {
    /// The SQL type that this query represents.
    ///
    /// This is the SQL type of the `SELECT` clause for select statements, and
    /// the SQL type of the `RETURNING` clause for insert, update, or delete
    /// statements.
    type SqlType;
}

impl<'a, T: Query> Query for &'a T {
    type SqlType = T::SqlType;
}

/// Indicates that a type is a `SELECT` statement.
///
/// This trait differs from `Query` in two ways:
/// - It is implemented only for select statements, rather than all queries
///   which return a value.
/// - It has looser constraints. A type implementing `SelectQuery` is known to
///   be potentially valid if used as a subselect, but it is not necessarily
///   able to be executed.
pub trait SelectQuery {
    /// The SQL type of the `SELECT` clause
    type SqlType;
}

/// An untyped fragment of SQL.
///
/// This may be a complete SQL command (such as an update statement without a
/// `RETURNING` clause), or a subsection (such as our internal types used to
/// represent a `WHERE` clause). Implementations of [`ExecuteDsl`] and
/// [`LoadQuery`] will generally require that this trait be implemented.
///
/// [`ExecuteDsl`]: crate::query_dsl::methods::ExecuteDsl
/// [`LoadQuery`]: crate::query_dsl::methods::LoadQuery
pub trait QueryFragment<DB: Backend, SP = self::private::NotSpecialized> {
    /// Walk over this `QueryFragment` for all passes.
    ///
    /// This method is where the actual behavior of an AST node is implemented.
    /// This method will contain the behavior required for all possible AST
    /// passes. See [`AstPass`] for more details.
    ///
    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()>;

    /// Converts this `QueryFragment` to its SQL representation.
    ///
    /// This method should only be called by implementations of `Connection`.
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn to_sql(&self, out: &mut DB::QueryBuilder, backend: &DB) -> QueryResult<()> {
        self.walk_ast(AstPass::to_sql(out, backend))
    }

    /// Serializes all bind parameters in this query.
    ///
    /// A bind parameter is a value which is sent separately from the query
    /// itself. It is represented in SQL with a placeholder such as `?` or `$1`.
    ///
    /// This method should only be called by implementations of `Connection`.
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn collect_binds<'b>(
        &'b self,
        out: &mut <DB as HasBindCollector<'b>>::BindCollector,
        metadata_lookup: &mut DB::MetadataLookup,
        backend: &'b DB,
    ) -> QueryResult<()> {
        self.walk_ast(AstPass::collect_binds(out, metadata_lookup, backend))
    }

    /// Is this query safe to store in the prepared statement cache?
    ///
    /// In order to keep our prepared statement cache at a reasonable size, we
    /// avoid caching any queries which represent a potentially unbounded number
    /// of SQL queries. Generally this will only return `true` for queries for
    /// which `to_sql` will always construct exactly identical SQL.
    ///
    /// Some examples of where this method will return `false` are:
    ///
    /// - `SqlLiteral` (We don't know if the SQL was constructed dynamically, so
    ///   we must assume that it was)
    /// - `In` and `NotIn` (Each value requires a separate bind param
    ///   placeholder)
    ///
    /// This method should only be called by implementations of `Connection`.
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn is_safe_to_cache_prepared(&self, backend: &DB) -> QueryResult<bool> {
        let mut result = true;
        self.walk_ast(AstPass::is_safe_to_cache_prepared(&mut result, backend))?;
        Ok(result)
    }

    /// Does walking this AST have any effect?
    #[diesel_derives::__diesel_public_if(
        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
    )]
    fn is_noop(&self, backend: &DB) -> QueryResult<bool> {
        let mut result = true;
        self.walk_ast(AstPass::is_noop(&mut result, backend))?;
        Ok(result)
    }
}

impl<T: ?Sized, DB> QueryFragment<DB> for Box<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<'a, T: ?Sized, DB> QueryFragment<DB> for &'a T
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<DB: Backend> QueryFragment<DB> for () {
    fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<T, DB> QueryFragment<DB> for Option<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        match *self {
            Some(ref c) => c.walk_ast(out),
            None => Ok(()),
        }
    }
}

/// A trait used to construct type erased boxed variant of the current query node
///
/// Mainly useful for implementing third party backends
pub trait IntoBoxedClause<'a, DB> {
    /// Resulting type
    type BoxedClause;

    /// Convert the given query node in it's boxed representation
    fn into_boxed(self) -> Self::BoxedClause;
}

/// Types that can be converted into a complete, typed SQL query.
///
/// This is used internally to automatically add the right select clause when
/// none is specified, or to automatically add `RETURNING *` in certain contexts.
///
/// A type which implements this trait is guaranteed to be valid for execution.
pub trait AsQuery {
    /// The SQL type of `Self::Query`
    type SqlType;

    /// What kind of query does this type represent?
    type Query: Query<SqlType = Self::SqlType>;

    /// Converts a type which semantically represents a SQL query into the
    /// actual query being executed. See the trait level docs for more.
    // This method is part of our public API,
    // so we won't change the name to just appease clippy
    // (Also the trait is literally named `AsQuery` so
    // naming the method similary is fine)
    #[allow(clippy::wrong_self_convention)]
    fn as_query(self) -> Self::Query;
}

impl<T: Query> AsQuery for T {
    type SqlType = <T as Query>::SqlType;
    type Query = T;

    fn as_query(self) -> <T as AsQuery>::Query {
        self
    }
}

/// Takes a query `QueryFragment` expression as an argument and returns a type
/// that implements `fmt::Display` and `fmt::Debug` to show the query.
///
/// The `Display` implementation will show the exact query being sent to the
/// server, with a comment showing the values of the bind parameters. The
/// `Debug` implementation will include the same information in a more
/// structured form, and respects pretty printing.
///
/// # Example
///
/// ### Returning SQL from a count statement:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # use diesel::*;
/// # use schema::*;
/// #
/// # fn main() {
/// #   use schema::users::dsl::*;
/// let sql = debug_query::<DB, _>(&users.count()).to_string();
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(sql, r#"SELECT COUNT(*) FROM "users" -- binds: []"#);
/// # } else {
/// assert_eq!(sql, "SELECT COUNT(*) FROM `users` -- binds: []");
/// # }
///
/// let query = users.find(1);
/// let debug = debug_query::<DB, _>(&query);
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(debug.to_string(), "SELECT \"users\".\"id\", \"users\".\"name\" \
/// #         FROM \"users\" WHERE (\"users\".\"id\" = $1) -- binds: [1]");
/// # } else {
/// assert_eq!(debug.to_string(), "SELECT `users`.`id`, `users`.`name` FROM `users` \
///     WHERE (`users`.`id` = ?) -- binds: [1]");
/// # }
///
/// let debug = format!("{:?}", debug);
/// # if !cfg!(feature = "postgres") { // Escaping that string is a pain
/// let expected = "Query { \
///     sql: \"SELECT `users`.`id`, `users`.`name` FROM `users` WHERE \
///         (`users`.`id` = ?)\", \
///     binds: [1] \
/// }";
/// assert_eq!(debug, expected);
/// # }
/// # }
/// ```
pub fn debug_query<DB, T>(query: &T) -> DebugQuery<'_, T, DB> {
    DebugQuery::new(query)
}

mod private {
    #[allow(missing_debug_implementations, missing_copy_implementations)]
    pub struct NotSpecialized;
}
<|endoftext|>


<commit_before>extern crate djinn;
extern crate redis;
extern crate redis_cluster;
extern crate rustc_serialize;

use std::thread;
use redis::{Client, Commands};
use redis_cluster::Cluster;
use djinn::{Agent, Manager, Simulation, Population, Worker, Uuid, Redis, WebSocketServer};

#[derive(RustcDecodable, RustcEncodable, Debug, PartialEq, Clone)]
pub struct MyState {
    name: String,
    health: usize,
}

#[derive(RustcDecodable, RustcEncodable, Debug, PartialEq, Clone)]
pub struct MyWorld {
    weather: String,
}

#[derive(RustcDecodable, RustcEncodable, Debug, PartialEq, Clone)]
pub enum MyUpdate {
    ChangeName(String),
    ChangeHealth(usize),
}

#[derive(Clone)]
pub struct MySimulation;

impl Simulation for MySimulation {
    type State = MyState;
    type Update = MyUpdate;
    type World = MyWorld;

    fn on_spawn<R: Redis>(&self,
                          agent: Agent<Self::State>,
                          population: &Population<Self, R>)
                          -> () {
        population.index(agent.state.name.as_ref(), agent.id.clone());
    }

    fn on_death<R: Redis>(&self,
                          agent: Agent<Self::State>,
                          population: &Population<Self, R>)
                          -> () {
        population.unindex(agent.state.name.as_ref(), agent.id.clone());
    }

    fn decide<R: Redis>(&self,
                        agent: Agent<Self::State>,
                        world: Self::World,
                        population: &Population<Self, R>)
                        -> Vec<(Uuid, Self::Update)> {
        let mut updates = Vec::new();
        match agent.state.name.as_ref() {
            "hello" => {
                let agents = population.lookup("goodbye");
                for a in agents {
                    updates.push((a.id, MyUpdate::ChangeHealth(12)));
                }
            }
            "goodbye" => (),
            _ => println!("my name is unknown"),
        }
        updates
    }

    fn update(&self, state: Self::State, updates: Vec<Self::Update>) -> Self::State {
        let mut state = state.clone();
        for update in updates {
            state = match update {
                MyUpdate::ChangeName(name) => {
                    MyState {
                        name: name,
                        health: state.health,
                    }
                }
                MyUpdate::ChangeHealth(health) => {
                    MyState {
                        name: state.name,
                        health: state.health + health,
                    }
                }
            }
        }
        state
    }
}

fn main() {
    let health = 10;
    let state = MyState {
        name: "hello".to_string(),
        health: 0,
    };
    let state2 = MyState {
        name: "goodbye".to_string(),
        health: health,
    };

    let sim = MySimulation {};
    let world = MyWorld { weather: "sunny".to_string() };

    // Setup the manager
    let addr = "redis://127.0.0.1/";

    let startup_nodes =
        vec!["redis://127.0.0.1:7000", "redis://127.0.0.1:7001", "redis://127.0.0.1:7002"];
    // let pop_client = Cluster::new(startup_nodes.clone());
    let pop_client = Client::open(addr).unwrap();
    let mut manager = Manager::new(addr, pop_client, sim, world);

    // Spawn the population
    manager.population.spawn(state.clone());
    let id = manager.population.spawn(state2.clone());
    manager.population.update();
    assert_eq!(manager.population.count(), 2);

    // Create a worker on a separate thread
    let worker_t = thread::spawn(move || {
        let sim = MySimulation {};
        let pop_client = Client::open(addr).unwrap();
        // let pop_client = Cluster::new(startup_nodes.clone());
        let worker = Worker::new(addr, pop_client, sim);
        worker.start();
    });

    // Create a websocket server to pass messages to frontend clients
    let mut ws = WebSocketServer::new("127.0.0.1:3012", addr);
    ws.start();

    // Give the frontend some time to connect
    thread::sleep_ms(2000);

    let n_steps = 10;

    // Create a client to listen to our reports
    let log_t = thread::spawn(move || {
        let client = Client::open(addr).unwrap();
        let mut pubsub = client.get_pubsub().unwrap();
        pubsub.subscribe("weather").unwrap();
        for _ in 0..n_steps {
            let msg = pubsub.get_message().unwrap();
            let payload: String = msg.get_payload().unwrap();
            println!("This step's weather is {}", payload);
        }
    });

    // Register a really simple reporter
    manager.register_reporter(1, |step, pop, conn| {
        let world = pop.world();
        let _: () = conn.publish("weather", world.weather.clone()).unwrap();
        let _: () = conn.publish("ws", world.weather.clone()).unwrap();
    });

    // Run the manager on a separate thread
    let manager_t = thread::spawn(move || {
        manager.run(n_steps);
        manager
    });

    manager = manager_t.join().unwrap();
    worker_t.join().unwrap();
    log_t.join().unwrap();

    // Check that things are working
    let agent = match manager.population.get_agent(id) {
        Some(a) => a,
        None => panic!("Couldn't find the agent"),
    };
    println!("{:?}", agent);
    assert_eq!(agent.state.health, health + (12 * n_steps));

    // Shutdown the websocket server
    ws.shutdown();
}
<commit_msg>fixed and documented basic example<commit_after>//! # Basic simulation
//! A really basic simulation to demonstrate
//! some features of Djinn:
//!
//! - how to write a basic simulation
//! - how to create a websocket server and publish to it
//! - how to publish and listen to events
//! - how to register a simulation reporter
//! - how to run a simulation

extern crate djinn;
extern crate redis;
extern crate rustc_serialize;

use std::thread;
use redis::{Client, Commands};
use djinn::{Agent, Manager, Simulation, Population, Updates, Redis, WebSocketServer, run};

const HEALTH_START: usize = 10;
const HEALTH_CHANGE: usize = 10;

#[derive(RustcDecodable, RustcEncodable, Debug, PartialEq, Clone)]
pub struct State {
    health: usize,
}

#[derive(RustcDecodable, RustcEncodable, Debug, PartialEq, Clone)]
pub struct World {
    weather: String,
}

#[derive(RustcDecodable, RustcEncodable, Debug, PartialEq, Clone)]
pub enum Update {
    ChangeHealth(usize),
}

#[derive(Clone)]
pub struct BasicSim;

impl Simulation for BasicSim {
    type State = State;
    type Update = Update;
    type World = World;

    fn decide<R: Redis>(&self,
                        agent: &Agent<Self::State>,
                        world: &Self::World,
                        population: &Population<Self, R>,
                        updates: &mut Updates<Self>)
                        -> () {
        updates.queue(agent.id, Update::ChangeHealth(HEALTH_CHANGE));
    }

    fn update(&self, mut state: &mut Self::State, updates: Vec<Self::Update>) -> bool {
        let updated = updates.len() > 0;
        for update in updates {
            match update {
                Update::ChangeHealth(health) => {
                    state.health += health;
                }
            }
        }
        updated
    }
}

fn main() {
    let sim = BasicSim {};
    let world = World { weather: "sunny".to_string() };

    // Setup the manager
    let addr = "redis://127.0.0.1/";
    let client = Client::open(addr).unwrap();
    let mut manager = Manager::new(addr, client, sim.clone());

    // Spawn the population
    manager.spawn(State { health: 0 });
    let id = manager.spawn(State { health: HEALTH_START });

    // Create a websocket server to pass messages to frontend clients
    let mut ws = WebSocketServer::new("127.0.0.1:3012", addr);
    ws.start();

    // Give the frontend some time to connect
    thread::sleep_ms(2000);

    let n_steps = 10;

    // Create a client to listen to events
    let log_t = thread::spawn(move || {
        let client = Client::open(addr).unwrap();
        let mut pubsub = client.get_pubsub().unwrap();
        pubsub.subscribe("weather").unwrap();
        for step in 0..n_steps {
            let msg = pubsub.get_message().unwrap();
            let payload: String = msg.get_payload().unwrap();
            println!("[{:02}] This step's weather is {}", step, payload);
        }
    });

    // Register a really simple reporter
    manager.register_reporter(1, |step, pop, conn| {
        let world = pop.world();
        let _: () = conn.publish("weather", world.weather.clone()).unwrap();
        let _: () = conn.publish("ws", world.weather.clone()).unwrap();
    });

    manager = run(sim, world, manager, 4, n_steps);
    log_t.join().unwrap();

    // Check that things are working
    let agent = match manager.population.get_agent(id) {
        Some(a) => a,
        None => panic!("Couldn't find the agent"),
    };
    println!("{:?}", agent);
    assert_eq!(agent.state.health, HEALTH_START + (HEALTH_CHANGE * n_steps));

    // Shutdown the websocket server
    ws.shutdown();
}
<|endoftext|>


<commit_before>extern crate polydraw;

use std::cmp::{min, max};

use polydraw::{Application, Renderer, RenderFrame};

struct MouseRenderer {
   mouse_x: i32,
   mouse_y: i32,
}

impl MouseRenderer {
   fn new() -> Self {
      MouseRenderer {
         mouse_x: 1000000,
         mouse_y: 1000000,
      }
   }
}

impl Renderer for MouseRenderer {
   fn render(&mut self, frame: &mut RenderFrame) {
      frame.clear();

      let half = 35_u32;

      let x_start = max(0, self.mouse_x - half as i32);
      let x_end = min(frame.width as i32, self.mouse_x + half as i32);

      let y_start = max(0, self.mouse_y - half as i32);
      let y_end = min(frame.height as i32, self.mouse_y + half as i32);

      for y in y_start..y_end {
         let row_i = 3 * y * frame.width as i32;
         for x in x_start..x_end {
            let i = (3 * x + row_i) as usize;
            frame.data[i] = 33;
            frame.data[i + 1] = 168;
            frame.data[i + 2] = 222;
         }
      }
   }

   fn mouse_moved(&mut self, x: i32, y: i32) {
      self.mouse_x = x;
      self.mouse_y = y;
   }
}

fn main() {
   let mut renderer = MouseRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Mouse")
      .run();
}
<commit_msg>Mouse example using put_pixel method<commit_after>extern crate polydraw;

use std::cmp::{min, max};

use polydraw::{Application, Renderer, RenderFrame};
use polydraw::draw::RGB;

struct MouseRenderer {
   mouse_x: i32,
   mouse_y: i32,
}

impl MouseRenderer {
   fn new() -> Self {
      MouseRenderer {
         mouse_x: 1000000,
         mouse_y: 1000000,
      }
   }
}

impl Renderer for MouseRenderer {
   fn render(&mut self, frame: &mut RenderFrame) {
      frame.clear();

      let color = RGB::new(33, 168, 222);

      let half = 35_u32;

      let x_start = max(0, self.mouse_x - half as i32);
      let x_end = min(frame.width as i32, self.mouse_x + half as i32);

      let y_start = max(0, self.mouse_y - half as i32);
      let y_end = min(frame.height as i32, self.mouse_y + half as i32);

      for y in y_start..y_end {
         for x in x_start..x_end {
            frame.put_pixel(x, y, &color);
         }
      }
   }

   fn mouse_moved(&mut self, x: i32, y: i32) {
      self.mouse_x = x;
      self.mouse_y = y;
   }
}

fn main() {
   let mut renderer = MouseRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Mouse")
      .run();
}
<|endoftext|>


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

use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::MessageEventBinding;
use dom::bindings::codegen::Bindings::MessageEventBinding::MessageEventMethods;
use dom::bindings::codegen::InheritTypes::{EventCast, MessageEventDerived};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::trace::Traceable;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, MessageEventTypeId};
use dom::eventtarget::{EventTarget, EventTargetHelpers};

use servo_util::str::DOMString;

use js::jsapi::JSContext;
use js::jsval::JSVal;

#[jstraceable]
#[must_root]
pub struct MessageEvent {
    event: Event,
    data: Traceable<JSVal>,
    origin: DOMString,
    lastEventId: DOMString,
}

impl MessageEventDerived for Event {
    fn is_messageevent(&self) -> bool {
        self.type_id == MessageEventTypeId
    }
}

impl MessageEvent {
    fn new_inherited(data: JSVal, origin: DOMString, lastEventId: DOMString)
                         -> MessageEvent {
        MessageEvent {
            event: Event::new_inherited(MessageEventTypeId),
            data: Traceable::new(data),
            origin: origin,
            lastEventId: lastEventId,
        }
    }

    pub fn new(global: &GlobalRef, type_: DOMString,
               bubbles: bool, cancelable: bool,
               data: JSVal, origin: DOMString, lastEventId: DOMString)
               -> Temporary<MessageEvent> {
        let ev = reflect_dom_object(box MessageEvent::new_inherited(data, origin, lastEventId),
                                    global,
                                    MessageEventBinding::Wrap).root();
        let event: JSRef<Event> = EventCast::from_ref(*ev);
        event.InitEvent(type_, bubbles, cancelable);
        Temporary::from_rooted(*ev)
    }

    pub fn Constructor(global: &GlobalRef,
                       type_: DOMString,
                       init: &MessageEventBinding::MessageEventInit)
                       -> Fallible<Temporary<MessageEvent>> {
        let ev = MessageEvent::new(global, type_, init.parent.bubbles, init.parent.cancelable,
                                   init.data, init.origin.clone(), init.lastEventId.clone());
        Ok(ev)
    }
}

impl MessageEvent {
    pub fn dispatch_jsval(target: JSRef<EventTarget>,
                          scope: &GlobalRef,
                          message: JSVal) {
        let messageevent = MessageEvent::new(
            scope, "message".to_string(), false, false, message,
            "".to_string(), "".to_string()).root();
        let event: JSRef<Event> = EventCast::from_ref(*messageevent);
        target.dispatch_event_with_target(None, event).unwrap();
    }
}

impl<'a> MessageEventMethods for JSRef<'a, MessageEvent> {
    fn Data(self, _cx: *mut JSContext) -> JSVal {
        *self.data
    }

    fn Origin(self) -> DOMString {
        self.origin.clone()
    }

    fn LastEventId(self) -> DOMString {
        self.lastEventId.clone()
    }
}

impl Reflectable for MessageEvent {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.event.reflector()
    }
}
<commit_msg>Remove Traceable from messageevent.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::MessageEventBinding;
use dom::bindings::codegen::Bindings::MessageEventBinding::MessageEventMethods;
use dom::bindings::codegen::InheritTypes::{EventCast, MessageEventDerived};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, MessageEventTypeId};
use dom::eventtarget::{EventTarget, EventTargetHelpers};

use servo_util::str::DOMString;

use js::jsapi::JSContext;
use js::jsval::JSVal;

#[jstraceable]
#[must_root]
pub struct MessageEvent {
    event: Event,
    data: JSVal,
    origin: DOMString,
    lastEventId: DOMString,
}

impl MessageEventDerived for Event {
    fn is_messageevent(&self) -> bool {
        self.type_id == MessageEventTypeId
    }
}

impl MessageEvent {
    fn new_inherited(data: JSVal, origin: DOMString, lastEventId: DOMString)
                         -> MessageEvent {
        MessageEvent {
            event: Event::new_inherited(MessageEventTypeId),
            data: data,
            origin: origin,
            lastEventId: lastEventId,
        }
    }

    pub fn new(global: &GlobalRef, type_: DOMString,
               bubbles: bool, cancelable: bool,
               data: JSVal, origin: DOMString, lastEventId: DOMString)
               -> Temporary<MessageEvent> {
        let ev = reflect_dom_object(box MessageEvent::new_inherited(data, origin, lastEventId),
                                    global,
                                    MessageEventBinding::Wrap).root();
        let event: JSRef<Event> = EventCast::from_ref(*ev);
        event.InitEvent(type_, bubbles, cancelable);
        Temporary::from_rooted(*ev)
    }

    pub fn Constructor(global: &GlobalRef,
                       type_: DOMString,
                       init: &MessageEventBinding::MessageEventInit)
                       -> Fallible<Temporary<MessageEvent>> {
        let ev = MessageEvent::new(global, type_, init.parent.bubbles, init.parent.cancelable,
                                   init.data, init.origin.clone(), init.lastEventId.clone());
        Ok(ev)
    }
}

impl MessageEvent {
    pub fn dispatch_jsval(target: JSRef<EventTarget>,
                          scope: &GlobalRef,
                          message: JSVal) {
        let messageevent = MessageEvent::new(
            scope, "message".to_string(), false, false, message,
            "".to_string(), "".to_string()).root();
        let event: JSRef<Event> = EventCast::from_ref(*messageevent);
        target.dispatch_event_with_target(None, event).unwrap();
    }
}

impl<'a> MessageEventMethods for JSRef<'a, MessageEvent> {
    fn Data(self, _cx: *mut JSContext) -> JSVal {
        self.data
    }

    fn Origin(self) -> DOMString {
        self.origin.clone()
    }

    fn LastEventId(self) -> DOMString {
        self.lastEventId.clone()
    }
}

impl Reflectable for MessageEvent {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.event.reflector()
    }
}
<|endoftext|>


<commit_before>//! When *constructing* `hir`, we start at some parent syntax node and recursively
//! lower the children.
//!
//! This modules allows one to go in the opposite direction: start with a syntax
//! node for a *child*, and get its hir.

use either::Either;
use hir_expand::HirFileId;
use syntax::ast::HasDocComments;

use crate::{
    db::DefDatabase,
    dyn_map::DynMap,
    item_scope::ItemScope,
    keys,
    src::{HasChildSource, HasSource},
    AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, ModuleDefId,
    ModuleId, TraitId, VariantId,
};

pub trait ChildBySource {
    fn child_by_source(&self, db: &dyn DefDatabase, file_id: HirFileId) -> DynMap {
        let mut res = DynMap::default();
        self.child_by_source_to(db, &mut res, file_id);
        res
    }
    fn child_by_source_to(&self, db: &dyn DefDatabase, map: &mut DynMap, file_id: HirFileId);
}

impl ChildBySource for TraitId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let data = db.trait_data(*self);
        // FIXME attribute macros
        for (_name, item) in data.items.iter() {
            match *item {
                AssocItemId::FunctionId(func) => {
                    let loc = func.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::FUNCTION].insert(src, func)
                    }
                }
                AssocItemId::ConstId(konst) => {
                    let loc = konst.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::CONST].insert(src, konst)
                    }
                }
                AssocItemId::TypeAliasId(ty) => {
                    let loc = ty.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::TYPE_ALIAS].insert(src, ty)
                    }
                }
            }
        }
    }
}

impl ChildBySource for ImplId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let data = db.impl_data(*self);
        // FIXME attribute macros
        for &item in data.items.iter() {
            match item {
                AssocItemId::FunctionId(func) => {
                    let loc = func.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::FUNCTION].insert(src, func)
                    }
                }
                AssocItemId::ConstId(konst) => {
                    let loc = konst.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::CONST].insert(src, konst)
                    }
                }
                AssocItemId::TypeAliasId(ty) => {
                    let loc = ty.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::TYPE_ALIAS].insert(src, ty)
                    }
                }
            }
        }
    }
}

impl ChildBySource for ModuleId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let def_map = self.def_map(db);
        let module_data = &def_map[self.local_id];
        module_data.scope.child_by_source_to(db, res, file_id);
    }
}

impl ChildBySource for ItemScope {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        self.declarations().for_each(|item| add_module_def(db, file_id, res, item));
        self.macros().for_each(|(_, makro)| {
            let ast_id = makro.ast_id();
            if ast_id.either(|it| it.file_id, |it| it.file_id) == file_id {
                let src = match ast_id {
                    Either::Left(ast_id) => ast_id.with_value(ast_id.to_node(db.upcast())),
                    // FIXME: Do we need to add proc-macros into a PROCMACRO dynmap here?
                    Either::Right(_fn) => return,
                };
                res[keys::MACRO_CALL].insert(src, makro);
            }
        });
        self.unnamed_consts().for_each(|konst| {
            let src = konst.lookup(db).source(db);
            res[keys::CONST].insert(src, konst);
        });
        self.impls().for_each(|imp| add_impl(db, file_id, res, imp));
        self.attr_macro_invocs().for_each(|(ast_id, call_id)| {
            let item = ast_id.with_value(ast_id.to_node(db.upcast()));
            res[keys::ATTR_MACRO_CALL].insert(item, call_id);
        });
        self.derive_macro_invocs().for_each(|(ast_id, calls)| {
            let adt = ast_id.to_node(db.upcast());
            for (attr_id, calls) in calls {
                if let Some(Either::Right(attr)) =
                    adt.doc_comments_and_attrs().nth(attr_id.ast_index as usize)
                {
                    res[keys::DERIVE_MACRO_CALL]
                        .insert(ast_id.with_value(attr), (attr_id, calls.into()));
                }
            }
        });

        fn add_module_def(
            db: &dyn DefDatabase,
            file_id: HirFileId,
            map: &mut DynMap,
            item: ModuleDefId,
        ) {
            match item {
                ModuleDefId::FunctionId(func) => {
                    let loc = func.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::FUNCTION].insert(src, func)
                    }
                }
                ModuleDefId::ConstId(konst) => {
                    let loc = konst.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::CONST].insert(src, konst)
                    }
                }
                ModuleDefId::StaticId(statik) => {
                    let loc = statik.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::STATIC].insert(src, statik)
                    }
                }
                ModuleDefId::TypeAliasId(ty) => {
                    let loc = ty.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::TYPE_ALIAS].insert(src, ty)
                    }
                }
                ModuleDefId::TraitId(trait_) => {
                    let loc = trait_.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::TRAIT].insert(src, trait_)
                    }
                }
                ModuleDefId::AdtId(adt) => match adt {
                    AdtId::StructId(strukt) => {
                        let loc = strukt.lookup(db);
                        if loc.id.file_id() == file_id {
                            let src = loc.source(db);
                            map[keys::STRUCT].insert(src, strukt)
                        }
                    }
                    AdtId::UnionId(union_) => {
                        let loc = union_.lookup(db);
                        if loc.id.file_id() == file_id {
                            let src = loc.source(db);
                            map[keys::UNION].insert(src, union_)
                        }
                    }
                    AdtId::EnumId(enum_) => {
                        let loc = enum_.lookup(db);
                        if loc.id.file_id() == file_id {
                            let src = loc.source(db);
                            map[keys::ENUM].insert(src, enum_)
                        }
                    }
                },
                _ => (),
            }
        }
        fn add_impl(db: &dyn DefDatabase, file_id: HirFileId, map: &mut DynMap, imp: ImplId) {
            let loc = imp.lookup(db);
            if loc.id.file_id() == file_id {
                let src = loc.source(db);
                map[keys::IMPL].insert(src, imp)
            }
        }
    }
}

impl ChildBySource for VariantId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, _: HirFileId) {
        let arena_map = self.child_source(db);
        let arena_map = arena_map.as_ref();
        let parent = *self;
        for (local_id, source) in arena_map.value.iter() {
            let id = FieldId { parent, local_id };
            match source.clone() {
                Either::Left(source) => {
                    res[keys::TUPLE_FIELD].insert(arena_map.with_value(source), id)
                }
                Either::Right(source) => {
                    res[keys::RECORD_FIELD].insert(arena_map.with_value(source), id)
                }
            }
        }
    }
}

impl ChildBySource for EnumId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, _: HirFileId) {
        let arena_map = self.child_source(db);
        let arena_map = arena_map.as_ref();
        for (local_id, source) in arena_map.value.iter() {
            let id = EnumVariantId { parent: *self, local_id };
            res[keys::VARIANT].insert(arena_map.with_value(source.clone()), id)
        }
    }
}

impl ChildBySource for DefWithBodyId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let body = db.body(*self);
        for (_, def_map) in body.blocks(db) {
            // All block expressions are merged into the same map, because they logically all add
            // inner items to the containing `DefWithBodyId`.
            def_map[def_map.root()].scope.child_by_source_to(db, res, file_id);
        }
    }
}
<commit_msg>Filter out macro calls by file id in when building DynMap<commit_after>//! When *constructing* `hir`, we start at some parent syntax node and recursively
//! lower the children.
//!
//! This modules allows one to go in the opposite direction: start with a syntax
//! node for a *child*, and get its hir.

use either::Either;
use hir_expand::HirFileId;
use syntax::ast::HasDocComments;

use crate::{
    db::DefDatabase,
    dyn_map::DynMap,
    item_scope::ItemScope,
    keys,
    src::{HasChildSource, HasSource},
    AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, ModuleDefId,
    ModuleId, TraitId, VariantId,
};

pub trait ChildBySource {
    fn child_by_source(&self, db: &dyn DefDatabase, file_id: HirFileId) -> DynMap {
        let mut res = DynMap::default();
        self.child_by_source_to(db, &mut res, file_id);
        res
    }
    fn child_by_source_to(&self, db: &dyn DefDatabase, map: &mut DynMap, file_id: HirFileId);
}

impl ChildBySource for TraitId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let data = db.trait_data(*self);
        // FIXME attribute macros
        for (_name, item) in data.items.iter() {
            match *item {
                AssocItemId::FunctionId(func) => {
                    let loc = func.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::FUNCTION].insert(src, func)
                    }
                }
                AssocItemId::ConstId(konst) => {
                    let loc = konst.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::CONST].insert(src, konst)
                    }
                }
                AssocItemId::TypeAliasId(ty) => {
                    let loc = ty.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::TYPE_ALIAS].insert(src, ty)
                    }
                }
            }
        }
    }
}

impl ChildBySource for ImplId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let data = db.impl_data(*self);
        // FIXME attribute macros
        for &item in data.items.iter() {
            match item {
                AssocItemId::FunctionId(func) => {
                    let loc = func.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::FUNCTION].insert(src, func)
                    }
                }
                AssocItemId::ConstId(konst) => {
                    let loc = konst.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::CONST].insert(src, konst)
                    }
                }
                AssocItemId::TypeAliasId(ty) => {
                    let loc = ty.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        res[keys::TYPE_ALIAS].insert(src, ty)
                    }
                }
            }
        }
    }
}

impl ChildBySource for ModuleId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let def_map = self.def_map(db);
        let module_data = &def_map[self.local_id];
        module_data.scope.child_by_source_to(db, res, file_id);
    }
}

impl ChildBySource for ItemScope {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        self.declarations().for_each(|item| add_module_def(db, file_id, res, item));
        self.macros().for_each(|(_, makro)| {
            let ast_id = makro.ast_id();
            if ast_id.either(|it| it.file_id, |it| it.file_id) == file_id {
                let src = match ast_id {
                    Either::Left(ast_id) => ast_id.with_value(ast_id.to_node(db.upcast())),
                    // FIXME: Do we need to add proc-macros into a PROCMACRO dynmap here?
                    Either::Right(_fn) => return,
                };
                res[keys::MACRO_CALL].insert(src, makro);
            }
        });
        self.unnamed_consts().for_each(|konst| {
            let loc = konst.lookup(db);
            if loc.id.file_id() == file_id {
                let src = loc.source(db);
                res[keys::CONST].insert(src, konst);
            }
        });
        self.impls().for_each(|imp| add_impl(db, file_id, res, imp));
        self.attr_macro_invocs().for_each(|(ast_id, call_id)| {
            if ast_id.file_id == file_id {
                let item = ast_id.with_value(ast_id.to_node(db.upcast()));
                res[keys::ATTR_MACRO_CALL].insert(item, call_id);
            }
        });
        self.derive_macro_invocs().for_each(|(ast_id, calls)| {
            if ast_id.file_id != file_id {
                return;
            }
            let adt = ast_id.to_node(db.upcast());
            for (attr_id, calls) in calls {
                if let Some(Either::Right(attr)) =
                    adt.doc_comments_and_attrs().nth(attr_id.ast_index as usize)
                {
                    res[keys::DERIVE_MACRO_CALL]
                        .insert(ast_id.with_value(attr), (attr_id, calls.into()));
                }
            }
        });

        fn add_module_def(
            db: &dyn DefDatabase,
            file_id: HirFileId,
            map: &mut DynMap,
            item: ModuleDefId,
        ) {
            match item {
                ModuleDefId::FunctionId(func) => {
                    let loc = func.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::FUNCTION].insert(src, func)
                    }
                }
                ModuleDefId::ConstId(konst) => {
                    let loc = konst.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::CONST].insert(src, konst)
                    }
                }
                ModuleDefId::StaticId(statik) => {
                    let loc = statik.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::STATIC].insert(src, statik)
                    }
                }
                ModuleDefId::TypeAliasId(ty) => {
                    let loc = ty.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::TYPE_ALIAS].insert(src, ty)
                    }
                }
                ModuleDefId::TraitId(trait_) => {
                    let loc = trait_.lookup(db);
                    if loc.id.file_id() == file_id {
                        let src = loc.source(db);
                        map[keys::TRAIT].insert(src, trait_)
                    }
                }
                ModuleDefId::AdtId(adt) => match adt {
                    AdtId::StructId(strukt) => {
                        let loc = strukt.lookup(db);
                        if loc.id.file_id() == file_id {
                            let src = loc.source(db);
                            map[keys::STRUCT].insert(src, strukt)
                        }
                    }
                    AdtId::UnionId(union_) => {
                        let loc = union_.lookup(db);
                        if loc.id.file_id() == file_id {
                            let src = loc.source(db);
                            map[keys::UNION].insert(src, union_)
                        }
                    }
                    AdtId::EnumId(enum_) => {
                        let loc = enum_.lookup(db);
                        if loc.id.file_id() == file_id {
                            let src = loc.source(db);
                            map[keys::ENUM].insert(src, enum_)
                        }
                    }
                },
                _ => (),
            }
        }
        fn add_impl(db: &dyn DefDatabase, file_id: HirFileId, map: &mut DynMap, imp: ImplId) {
            let loc = imp.lookup(db);
            if loc.id.file_id() == file_id {
                let src = loc.source(db);
                map[keys::IMPL].insert(src, imp)
            }
        }
    }
}

impl ChildBySource for VariantId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, _: HirFileId) {
        let arena_map = self.child_source(db);
        let arena_map = arena_map.as_ref();
        let parent = *self;
        for (local_id, source) in arena_map.value.iter() {
            let id = FieldId { parent, local_id };
            match source.clone() {
                Either::Left(source) => {
                    res[keys::TUPLE_FIELD].insert(arena_map.with_value(source), id)
                }
                Either::Right(source) => {
                    res[keys::RECORD_FIELD].insert(arena_map.with_value(source), id)
                }
            }
        }
    }
}

impl ChildBySource for EnumId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, _: HirFileId) {
        let arena_map = self.child_source(db);
        let arena_map = arena_map.as_ref();
        for (local_id, source) in arena_map.value.iter() {
            let id = EnumVariantId { parent: *self, local_id };
            res[keys::VARIANT].insert(arena_map.with_value(source.clone()), id)
        }
    }
}

impl ChildBySource for DefWithBodyId {
    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
        let body = db.body(*self);
        for (_, def_map) in body.blocks(db) {
            // All block expressions are merged into the same map, because they logically all add
            // inner items to the containing `DefWithBodyId`.
            def_map[def_map.root()].scope.child_by_source_to(db, res, file_id);
        }
    }
}
<|endoftext|>


<commit_before>//! Procedural macros are implemented by compiling the macro providing crate
//! to a dynamic library with a particular ABI which the compiler uses to expand
//! macros. Unfortunately this ABI is not specified and can change from version
//! to version of the compiler. To support this we copy the ABI from the rust
//! compiler into submodules of this module (e.g proc_macro_srv::abis::abi_1_47).
//!
//! All of these ABIs are subsumed in the `Abi` enum, which exposes a simple
//! interface the rest of rust analyzer can use to talk to the macro
//! provider.
//!
//! # Adding a new ABI
//!
//! To add a new ABI you'll need to copy the source of the target proc_macro
//! crate from the source tree of the Rust compiler into this directory tree.
//! Then you'll need to modify it
//! - Remove any feature! or other things which won't compile on stable
//! - change any absolute imports to relative imports within the ABI tree
//!
//! Then you'll need to add a branch to the `Abi` enum and an implementation of
//! `Abi::expand`, `Abi::list_macros` and `Abi::from_lib` for the new ABI. See
//! `proc_macro_srv/src/abis/abi_1_47/mod.rs` for an example. Finally you'll
//! need to update the conditionals in `Abi::from_lib` to return your new ABI
//! for the relevant versions of the rust compiler
//!

// pub(crate) so tests can use the TokenStream, more notes in test/utils.rs
pub(crate) mod abi_1_47;
mod abi_1_55;
mod abi_1_56;
mod abi_1_58;

use super::dylib::LoadProcMacroDylibError;
pub(crate) use abi_1_47::Abi as Abi_1_47;
pub(crate) use abi_1_55::Abi as Abi_1_55;
pub(crate) use abi_1_56::Abi as Abi_1_56;
pub(crate) use abi_1_58::Abi as Abi_1_58;
use libloading::Library;
use proc_macro_api::{ProcMacroKind, RustCInfo};

pub struct PanicMessage {
    message: Option<String>,
}

impl PanicMessage {
    pub fn as_str(&self) -> Option<String> {
        self.message.clone()
    }
}

pub(crate) enum Abi {
    Abi1_47(Abi_1_47),
    Abi1_55(Abi_1_55),
    Abi1_56(Abi_1_56),
    Abi1_58(Abi_1_58),
}

impl Abi {
    /// Load a new ABI.
    ///
    /// # Arguments
    ///
    /// *`lib` - The dynamic library containing the macro implementations
    /// *`symbol_name` - The symbol name the macros can be found attributes
    /// *`info` - RustCInfo about the compiler that was used to compile the
    ///           macro crate. This is the information we use to figure out
    ///           which ABI to return
    pub fn from_lib(
        lib: &Library,
        symbol_name: String,
        info: RustCInfo,
    ) -> Result<Abi, LoadProcMacroDylibError> {
        if info.version.0 != 1 {
            Err(LoadProcMacroDylibError::UnsupportedABI)
        } else if info.version.1 < 47 {
            Err(LoadProcMacroDylibError::UnsupportedABI)
        } else if info.version.1 < 54 {
            let inner = unsafe { Abi_1_47::from_lib(lib, symbol_name) }?;
            Ok(Abi::Abi1_47(inner))
        } else if info.version.1 < 56 {
            let inner = unsafe { Abi_1_55::from_lib(lib, symbol_name) }?;
            Ok(Abi::Abi1_55(inner))
        } else if info.version.1 < 57 {
            let inner = unsafe { Abi_1_56::from_lib(lib, symbol_name) }?;
            Ok(Abi::Abi1_56(inner))
        } else {
            let inner = unsafe { Abi_1_58::from_lib(lib, symbol_name) }?;
            Ok(Abi::Abi1_58(inner))
        }
    }

    pub fn expand(
        &self,
        macro_name: &str,
        macro_body: &tt::Subtree,
        attributes: Option<&tt::Subtree>,
    ) -> Result<tt::Subtree, PanicMessage> {
        match self {
            Self::Abi1_55(abi) => abi.expand(macro_name, macro_body, attributes),
            Self::Abi1_47(abi) => abi.expand(macro_name, macro_body, attributes),
            Self::Abi1_56(abi) => abi.expand(macro_name, macro_body, attributes),
            Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
        }
    }

    pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
        match self {
            Self::Abi1_47(abi) => abi.list_macros(),
            Self::Abi1_55(abi) => abi.list_macros(),
            Self::Abi1_56(abi) => abi.list_macros(),
            Self::Abi1_58(abi) => abi.list_macros(),
        }
    }
}
<commit_msg>Fix proc macro ABI version checks<commit_after>//! Procedural macros are implemented by compiling the macro providing crate
//! to a dynamic library with a particular ABI which the compiler uses to expand
//! macros. Unfortunately this ABI is not specified and can change from version
//! to version of the compiler. To support this we copy the ABI from the rust
//! compiler into submodules of this module (e.g proc_macro_srv::abis::abi_1_47).
//!
//! All of these ABIs are subsumed in the `Abi` enum, which exposes a simple
//! interface the rest of rust analyzer can use to talk to the macro
//! provider.
//!
//! # Adding a new ABI
//!
//! To add a new ABI you'll need to copy the source of the target proc_macro
//! crate from the source tree of the Rust compiler into this directory tree.
//! Then you'll need to modify it
//! - Remove any feature! or other things which won't compile on stable
//! - change any absolute imports to relative imports within the ABI tree
//!
//! Then you'll need to add a branch to the `Abi` enum and an implementation of
//! `Abi::expand`, `Abi::list_macros` and `Abi::from_lib` for the new ABI. See
//! `proc_macro_srv/src/abis/abi_1_47/mod.rs` for an example. Finally you'll
//! need to update the conditionals in `Abi::from_lib` to return your new ABI
//! for the relevant versions of the rust compiler
//!

// pub(crate) so tests can use the TokenStream, more notes in test/utils.rs
pub(crate) mod abi_1_47;
mod abi_1_55;
mod abi_1_56;
mod abi_1_58;

use super::dylib::LoadProcMacroDylibError;
pub(crate) use abi_1_47::Abi as Abi_1_47;
pub(crate) use abi_1_55::Abi as Abi_1_55;
pub(crate) use abi_1_56::Abi as Abi_1_56;
pub(crate) use abi_1_58::Abi as Abi_1_58;
use libloading::Library;
use proc_macro_api::{ProcMacroKind, RustCInfo};

pub struct PanicMessage {
    message: Option<String>,
}

impl PanicMessage {
    pub fn as_str(&self) -> Option<String> {
        self.message.clone()
    }
}

pub(crate) enum Abi {
    Abi1_47(Abi_1_47),
    Abi1_55(Abi_1_55),
    Abi1_56(Abi_1_56),
    Abi1_58(Abi_1_58),
}

impl Abi {
    /// Load a new ABI.
    ///
    /// # Arguments
    ///
    /// *`lib` - The dynamic library containing the macro implementations
    /// *`symbol_name` - The symbol name the macros can be found attributes
    /// *`info` - RustCInfo about the compiler that was used to compile the
    ///           macro crate. This is the information we use to figure out
    ///           which ABI to return
    pub fn from_lib(
        lib: &Library,
        symbol_name: String,
        info: RustCInfo,
    ) -> Result<Abi, LoadProcMacroDylibError> {
        // FIXME: this should use exclusive ranges when they're stable
        // https://github.com/rust-lang/rust/issues/37854
        match (info.version.0, info.version.1) {
            (1, 47..=54) => {
                let inner = unsafe { Abi_1_47::from_lib(lib, symbol_name) }?;
                Ok(Abi::Abi1_47(inner))
            }
            (1, 55..=55) => {
                let inner = unsafe { Abi_1_55::from_lib(lib, symbol_name) }?;
                Ok(Abi::Abi1_55(inner))
            }
            (1, 56..=57) => {
                let inner = unsafe { Abi_1_56::from_lib(lib, symbol_name) }?;
                Ok(Abi::Abi1_56(inner))
            }
            (1, 58..) => {
                let inner = unsafe { Abi_1_58::from_lib(lib, symbol_name) }?;
                Ok(Abi::Abi1_58(inner))
            }
            _ => Err(LoadProcMacroDylibError::UnsupportedABI),
        }
    }

    pub fn expand(
        &self,
        macro_name: &str,
        macro_body: &tt::Subtree,
        attributes: Option<&tt::Subtree>,
    ) -> Result<tt::Subtree, PanicMessage> {
        match self {
            Self::Abi1_55(abi) => abi.expand(macro_name, macro_body, attributes),
            Self::Abi1_47(abi) => abi.expand(macro_name, macro_body, attributes),
            Self::Abi1_56(abi) => abi.expand(macro_name, macro_body, attributes),
            Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
        }
    }

    pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
        match self {
            Self::Abi1_47(abi) => abi.list_macros(),
            Self::Abi1_55(abi) => abi.list_macros(),
            Self::Abi1_56(abi) => abi.list_macros(),
            Self::Abi1_58(abi) => abi.list_macros(),
        }
    }
}
<|endoftext|>


<commit_before>use cf = core_foundation;
use cf::base::{
    AbstractCFTypeRef,
    CFIndex,
    CFTypeID,
    CFTypeRef,
    CFWrapper,
};

use libc::{c_void, c_char, size_t};

pub type CGDataProviderGetBytesCallback = *u8;
pub type CGDataProviderReleaseInfoCallback = *u8;
pub type CGDataProviderRewindCallback = *u8;
pub type CGDataProviderSkipBytesCallback = *u8;
pub type CGDataProviderSkipForwardCallback = *u8;

pub type CGDataProviderGetBytePointerCallback = *u8;
pub type CGDataProviderGetBytesAtOffsetCallback = *u8;
pub type CGDataProviderReleaseBytePointerCallback = *u8;
pub type CGDataProviderReleaseDataCallback = *u8;
pub type CGDataProviderGetBytesAtPositionCallback = *u8;

struct __CGDataProvider { private: () }
pub type CGDataProviderRef = *__CGDataProvider;

pub impl CGDataProviderRef : AbstractCFTypeRef {
    pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
}

pub type CGDataProvider = CFWrapper<CGDataProviderRef, (), ()>;

pub trait CGDataProviderMethods {
    static fn new_from_buffer(buf: *u8, len: uint) -> CGDataProvider;
}

pub impl CGDataProvider : CGDataProviderMethods {
    static fn new_from_buffer(buf: *u8, len: uint) -> CGDataProvider unsafe {
        let result = CGDataProviderCreateWithData(
            ptr::null(),
            cast::transmute(buf),
            len as size_t,
            ptr::null());

        CFWrapper::wrap_owned(result)
    }
}

#[nolink]
#[link_args="-framework ApplicationServices"]
pub extern {
    //fn CGDataProviderCopyData
    //fn CGDataProviderCreateDirect
    //fn CGDataProviderCreateSequential
    //fn CGDataProviderCreateWithCFData
    fn CGDataProviderCreateWithData(info: *c_void,
                                    data: *c_void,
                                    size: size_t,
                                    releaseData: CGDataProviderReleaseDataCallback
                                   ) -> CGDataProviderRef;
    fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
    //fn CGDataProviderCreateWithURL
    fn CGDataProviderGetTypeID() -> CFTypeID;
    fn CGDataProviderRelease(provider: CGDataProviderRef);
    fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef;
}
<commit_msg>Move CGDataProvider static methods outside of trait/impl.<commit_after>use cf = core_foundation;
use cf::base::{
    AbstractCFTypeRef,
    CFIndex,
    CFTypeID,
    CFTypeRef,
    CFWrapper,
};

use libc::{c_void, c_char, size_t};

pub type CGDataProviderGetBytesCallback = *u8;
pub type CGDataProviderReleaseInfoCallback = *u8;
pub type CGDataProviderRewindCallback = *u8;
pub type CGDataProviderSkipBytesCallback = *u8;
pub type CGDataProviderSkipForwardCallback = *u8;

pub type CGDataProviderGetBytePointerCallback = *u8;
pub type CGDataProviderGetBytesAtOffsetCallback = *u8;
pub type CGDataProviderReleaseBytePointerCallback = *u8;
pub type CGDataProviderReleaseDataCallback = *u8;
pub type CGDataProviderGetBytesAtPositionCallback = *u8;

struct __CGDataProvider { private: () }
pub type CGDataProviderRef = *__CGDataProvider;

pub impl CGDataProviderRef : AbstractCFTypeRef {
    pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
}

pub type CGDataProvider = CFWrapper<CGDataProviderRef, (), ()>;

pub fn new_from_buffer(buf: *u8, len: uint) -> CGDataProvider unsafe {
        let result = CGDataProviderCreateWithData(
            ptr::null(),
            cast::transmute(buf),
            len as size_t,
            ptr::null());

        CFWrapper::wrap_owned(result)
}

#[nolink]
#[link_args="-framework ApplicationServices"]
pub extern {
    //fn CGDataProviderCopyData
    //fn CGDataProviderCreateDirect
    //fn CGDataProviderCreateSequential
    //fn CGDataProviderCreateWithCFData
    fn CGDataProviderCreateWithData(info: *c_void,
                                    data: *c_void,
                                    size: size_t,
                                    releaseData: CGDataProviderReleaseDataCallback
                                   ) -> CGDataProviderRef;
    fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
    //fn CGDataProviderCreateWithURL
    fn CGDataProviderGetTypeID() -> CFTypeID;
    fn CGDataProviderRelease(provider: CGDataProviderRef);
    fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef;
}
<|endoftext|>


<commit_before>extern crate postgres;
extern crate chrono;

use postgres::{Connection, SslMode, types};
use std::io::{self, Read};

enum Align {
    Left,
    Right,
    Center,
}

#[allow(dead_code)]
enum Color {
    White,
    BoldWhite,
    BoldRed,
    BoldGreen,
    BoldBlue,
}

fn color_text(text: &str, color: Color) -> String {
    let clrstr = match color {
        Color::White       => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[37m", text)        },
        Color::BoldWhite   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[37m", text) },
        Color::BoldRed     => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[31m", text) },
        Color::BoldGreen   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[32m", text) },
        Color::BoldBlue    => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[34m", text) },
    };

    clrstr
}

fn parse_result(column: &postgres::rows::Row, coltype: &Vec<types::Type>, colpos: usize) -> String {
    let val: String = match coltype[colpos] {
        types::Type::Text | types::Type::Varchar => column.get(colpos),
        types::Type::Bool => {
            let tmpbool: bool = column.get(colpos);
            match tmpbool {
                true  => String::from("true"),
                false => String::from("false"),
            }
        },
        types::Type::Int2 | types::Type::Int4 => {
            let tmpint: i32 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Int8 => {
            let tmpint: i64 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Float4 => {
            let tmpflt: f32 = column.get(colpos);
            tmpflt.to_string()
        },
        types::Type::Float8 => {
            let tmpflt: f64 = column.get(colpos);
            tmpflt.to_string()
        },
        types::Type::Timestamp => {
            let tmpdate: chrono::NaiveDateTime = column.get(colpos);
            tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
        },
        types::Type::TimestampTZ => {
            let tmpdate: chrono::DateTime<chrono::UTC> = column.get(colpos);
            tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
        },
        types::Type::Date => {
            let tmpdate: chrono::NaiveDate = column.get(colpos);
            tmpdate.format("%Y-%m-%d").to_string()
        },
        _ => String::from(""),
    };

    val
}

fn get_alignment(coltype: &types::Type) -> Align {
    match coltype {
        &types::Type::Int2   => Align::Right,
        &types::Type::Int4   => Align::Right,
        &types::Type::Int8   => Align::Right,
        &types::Type::Float4 => Align::Right,
        &types::Type::Float8 => Align::Right,
        _                    => Align::Left,
    }
}

fn pad_gen(len: usize, pad: &str) -> String {
    let mut padstr = String::from("");

    for _ in 0..len {
        padstr = padstr + pad;
    }

    padstr
}

fn format_field(column: &str, width: usize, align: Align) -> String {
    let padlen: usize = width - column.len();
    let extra: usize = padlen % 2;

    let ret: String = match align {
        Align::Center   => { format!("{}{}{}", pad_gen(padlen/2, " "), column, pad_gen((padlen/2)+extra, " ")) },
        Align::Right    => { format!("{}{}", pad_gen(padlen, " "), column) },
        Align::Left     => { format!("{}{}", column, pad_gen(padlen, " ")) },
    };

    ret
}

fn print_row(coltypes: &Vec<types::Type>, colwidths: &Vec<usize>, rowdata: &Vec<String>) {
    for (i, col) in rowdata.iter().enumerate() {
        if i > 0 {
            print!("{}", color_text("|", Color::BoldWhite));
        }

        print!(" {} ", format_field(&col, colwidths[i], get_alignment(&coltypes[i])));
    }

    println!("");
}

fn print_header(colwidths: &Vec<usize>, colnames: &Vec<String>) {
    for (i, name) in colnames.iter().enumerate() {
        if i > 0 {
            print!("{}", color_text("|", Color::BoldWhite));
        }

        print!(" {} ", color_text(&format_field(&name, colwidths[i], Align::Center), Color::BoldWhite));
    }

    println!("");
    for (i, col) in colwidths.iter().enumerate() {
        if i > 0 {
            print!("{}", color_text("|", Color::BoldWhite));
        }

        print!("{}", color_text(&pad_gen(col+2, "-"), Color::BoldWhite));
    }

    println!("");
}

fn main() {
    let mut buf = String::new();
    let mut colnames: Vec<String> = Vec::new();
    let mut coldata: Vec<Vec<String>> = Vec::new();
    let mut colwidths: Vec<usize> = Vec::new();
    let mut coltypes: Vec<types::Type> = Vec::new();

    io::stdin().read_to_string(&mut buf);

    let conn = Connection::connect("postgres://jeff@localhost/feclink", SslMode::None).unwrap();
    let res = &conn.query(&mut buf, &[]).unwrap();
    let numcols = res.columns().len();

    for col in res.columns() {
        let colname = String::from(col.name());
        colwidths.push(colname.len());
        colnames.push(colname);
        coltypes.push(col.type_().clone());
    }

    for row in res.iter() {
        let mut colvals: Vec<String> = Vec::new();

        for i in 0..numcols {
            let ret = row.get_bytes(i);
            let col = if ret.is_some() { parse_result(&row, &coltypes, i) } else { String::from("") };

            if colwidths[i] < col.len() {
                colwidths[i] = col.len();
            }

            colvals.push(col);
        }

        coldata.push(colvals);
    }

    print_header(&colwidths, &colnames);
    for rowdata in coldata {
        print_row(&coltypes, &colwidths, &rowdata);
    }
}
<commit_msg>make the code pass the tests :)<commit_after>extern crate postgres;
extern crate chrono;

#[cfg(test)]
mod tests;

use postgres::{Connection, SslMode, types};
use std::io::{self, Read};

#[derive(PartialEq, Debug)]
pub enum Align {
    Left,
    Right,
    Center,
}

#[allow(dead_code)]
#[derive(PartialEq, Debug)]
pub enum Color {
    White,
    BoldWhite,
    BoldRed,
    BoldGreen,
    BoldBlue,
}

pub fn color_text(text: &str, color: Color) -> String {
    let clrstr = match color {
        Color::White       => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[37m", text)        },
        Color::BoldWhite   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[37m", text) },
        Color::BoldRed     => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[31m", text) },
        Color::BoldGreen   => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[32m", text) },
        Color::BoldBlue    => { format!("{}{}\x1B[33m\x1B[0m", "\x1B[33m\x1B[1m\x1B[33m\x1B[34m", text) },
    };

    clrstr
}

fn parse_result(column: &postgres::rows::Row, coltype: &Vec<types::Type>, colpos: usize) -> String {
    let val: String = match coltype[colpos] {
        types::Type::Text | types::Type::Varchar => column.get(colpos),
        types::Type::Bool => {
            let tmpbool: bool = column.get(colpos);
            match tmpbool {
                true  => String::from("true"),
                false => String::from("false"),
            }
        },
        types::Type::Int2 | types::Type::Int4 => {
            let tmpint: i32 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Int8 => {
            let tmpint: i64 = column.get(colpos);
            tmpint.to_string()
        },
        types::Type::Float4 => {
            let tmpflt: f32 = column.get(colpos);
            tmpflt.to_string()
        },
        types::Type::Float8 => {
            let tmpflt: f64 = column.get(colpos);
            tmpflt.to_string()
        },
        types::Type::Timestamp => {
            let tmpdate: chrono::NaiveDateTime = column.get(colpos);
            tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
        },
        types::Type::TimestampTZ => {
            let tmpdate: chrono::DateTime<chrono::UTC> = column.get(colpos);
            tmpdate.format("%Y-%m-%d %H:%M:%s").to_string()
        },
        types::Type::Date => {
            let tmpdate: chrono::NaiveDate = column.get(colpos);
            tmpdate.format("%Y-%m-%d").to_string()
        },
        _ => String::from(""),
    };

    val
}

pub fn get_alignment(coltype: &types::Type) -> Align {
    match coltype {
        &types::Type::Int2          => Align::Right,
        &types::Type::Int4          => Align::Right,
        &types::Type::Int8          => Align::Right,
        &types::Type::Float4        => Align::Right,
        &types::Type::Float8        => Align::Right,
        &types::Type::Date          => Align::Right,
        &types::Type::Timestamp     => Align::Right,
        &types::Type::TimestampTZ   => Align::Right,
        _                           => Align::Left,
    }
}

pub fn pad_gen(len: usize, pad: &str) -> String {
    let mut padstr = String::from("");

    for _ in 0..len {
        padstr = padstr + pad;
    }

    padstr
}

pub fn format_field(column: &str, width: usize, align: Align) -> String {
    let padlen: usize = width - column.len();
    let extra: usize = padlen % 2;

    let ret: String = match align {
        Align::Center   => { format!("{}{}{}", pad_gen(padlen/2, " "), column, pad_gen((padlen/2)+extra, " ")) },
        Align::Right    => { format!("{}{}", pad_gen(padlen, " "), column) },
        Align::Left     => { format!("{}{}", column, pad_gen(padlen, " ")) },
    };

    ret
}

fn print_row(coltypes: &Vec<types::Type>, colwidths: &Vec<usize>, rowdata: &Vec<String>) {
    for (i, col) in rowdata.iter().enumerate() {
        if i > 0 {
            print!("{}", color_text("|", Color::BoldWhite));
        }

        print!(" {} ", format_field(&col, colwidths[i], get_alignment(&coltypes[i])));
    }

    println!("");
}

fn print_header(colwidths: &Vec<usize>, colnames: &Vec<String>) {
    for (i, name) in colnames.iter().enumerate() {
        if i > 0 {
            print!("{}", color_text("|", Color::BoldWhite));
        }

        print!(" {} ", color_text(&format_field(&name, colwidths[i], Align::Center), Color::BoldWhite));
    }

    println!("");
    for (i, col) in colwidths.iter().enumerate() {
        if i > 0 {
            print!("{}", color_text("|", Color::BoldWhite));
        }

        print!("{}", color_text(&pad_gen(col+2, "-"), Color::BoldWhite));
    }

    println!("");
}

fn main() {
    let mut buf = String::new();
    let mut colnames: Vec<String> = Vec::new();
    let mut coldata: Vec<Vec<String>> = Vec::new();
    let mut colwidths: Vec<usize> = Vec::new();
    let mut coltypes: Vec<types::Type> = Vec::new();

    io::stdin().read_to_string(&mut buf);

    let conn = Connection::connect("postgres://jeff@localhost/feclink", SslMode::None).unwrap();
    let res = &conn.query(&mut buf, &[]).unwrap();
    let numcols = res.columns().len();

    for col in res.columns() {
        let colname = String::from(col.name());
        colwidths.push(colname.len());
        colnames.push(colname);
        coltypes.push(col.type_().clone());
    }

    for row in res.iter() {
        let mut colvals: Vec<String> = Vec::new();

        for i in 0..numcols {
            let ret = row.get_bytes(i);
            let col = if ret.is_some() { parse_result(&row, &coltypes, i) } else { String::from("") };

            if colwidths[i] < col.len() {
                colwidths[i] = col.len();
            }

            colvals.push(col);
        }

        coldata.push(colvals);
    }

    print_header(&colwidths, &colnames);
    for rowdata in coldata {
        print_row(&coltypes, &colwidths, &rowdata);
    }
}
<|endoftext|>


<commit_before>//! Utility wrappers to simplify writing OpenGL code.
//!
//! This crate aspires to provide an abstraction over OpenGL's raw API in order to simplify the
//! task of writing higher-level rendering code for OpenGL. `gl-util` is much in the vein of
//! [glutin](https://github.com/tomaka/glium) and [gfx-rs](https://github.com/gfx-rs/gfx) before
//! it, the main difference being that it is much more poorly constructed and is being developed by
//! someone much less experienced with OpenGL.

extern crate bootstrap_gl as gl;

use gl::{BufferName, BufferTarget, BufferUsage, ClearBufferMask, DrawMode, GlType, VertexArrayName};
use std::mem;

pub use gl::{AttributeLocation};
pub use gl::platform::swap_buffers;

/// Initializes global OpenGL state and creates the OpenGL context needed to perform rendering.
pub fn init() {
    gl::create_context();
}

/// TODO: Take clear mask (and values) as parameters.
pub fn clear() {
    unsafe { gl::clear(ClearBufferMask::Color); }
}

/// Represents a buffer of vertex data and the layout of that data.
///
/// Wraps a vertex buffer object and vertex array object into one struct.
#[derive(Debug)]
pub struct VertexBuffer {
    buffer_name: BufferName,
    vertex_array_name: VertexArrayName,
}

impl VertexBuffer {
    /// Creates a new `VertexBuffer` object.
    pub fn new() -> VertexBuffer {
        let mut buffer_name = BufferName::null();
        let mut vertex_array_name = VertexArrayName::null();
        unsafe {
            gl::gen_buffers(1, &mut buffer_name);
            gl::gen_vertex_arrays(1, &mut vertex_array_name);
        }

        VertexBuffer {
            buffer_name: buffer_name,
            vertex_array_name: vertex_array_name,
        }
    }

    /// Fills the buffer with the contents of the data slice.
    pub fn set_data_f32(&mut self, data: &[f32]) {
        let data_ptr = data.as_ptr() as *const ();
        let byte_count = data.len() * mem::size_of::<f32>();

        unsafe {
            gl::bind_buffer(BufferTarget::Array, self.buffer_name);
            gl::buffer_data(
                BufferTarget::Array,
                byte_count as isize,
                data_ptr,
                BufferUsage::StaticDraw);
            gl::bind_buffer(BufferTarget::Array, BufferName::null());
        }
    }

    /// Specifies how the data for a particular vertex attribute is laid out in the buffer.
    pub fn set_attrib_f32(
        &mut self,
        attrib: AttributeLocation,
        elements: usize,
        stride: usize,
        offset: usize
    ) {
        unsafe {
            gl::bind_buffer(BufferTarget::Array, self.buffer_name);
            gl::bind_vertex_array(self.vertex_array_name);

            gl::enable_vertex_attrib_array(AttributeLocation::from_index(0));
            gl::vertex_attrib_pointer(
                attrib,
                elements as i32,
                GlType::Float,
                false,
                stride as i32,
                offset);

            gl::bind_vertex_array(VertexArrayName::null());
            gl::bind_buffer(BufferTarget::Array, BufferName::null());
        }
    }

    /// Draws the contents of the vertex buffer to the screen.
    pub fn draw(&self) {
        unsafe {
            gl::bind_buffer(BufferTarget::Array, self.buffer_name);
            gl::bind_vertex_array(self.vertex_array_name);

            gl::draw_arrays(DrawMode::Triangles, 0, 3);

            gl::bind_vertex_array(VertexArrayName::null());
            gl::bind_buffer(BufferTarget::Array, BufferName::null());
        }
    }
}

impl Drop for VertexBuffer {
    fn drop(&mut self) {
        unsafe {
            gl::delete_buffers(1, &mut self.buffer_name);
            gl::delete_vertex_arrays(1, &mut self.vertex_array_name);
        }
    }
}
<commit_msg>Add Parameters to VertexBuffer::draw()<commit_after>//! Utility wrappers to simplify writing OpenGL code.
//!
//! This crate aspires to provide an abstraction over OpenGL's raw API in order to simplify the
//! task of writing higher-level rendering code for OpenGL. `gl-util` is much in the vein of
//! [glutin](https://github.com/tomaka/glium) and [gfx-rs](https://github.com/gfx-rs/gfx) before
//! it, the main difference being that it is much more poorly constructed and is being developed by
//! someone much less experienced with OpenGL.

extern crate bootstrap_gl as gl;

use gl::{BufferName, BufferTarget, BufferUsage, ClearBufferMask, GlType, VertexArrayName};
use std::mem;

pub use gl::{AttributeLocation, DrawMode};
pub use gl::platform::swap_buffers;

/// Initializes global OpenGL state and creates the OpenGL context needed to perform rendering.
pub fn init() {
    gl::create_context();
}

/// TODO: Take clear mask (and values) as parameters.
pub fn clear() {
    unsafe { gl::clear(ClearBufferMask::Color); }
}

/// Represents a buffer of vertex data and the layout of that data.
///
/// Wraps a vertex buffer object and vertex array object into one struct.
#[derive(Debug)]
pub struct VertexBuffer {
    buffer_name: BufferName,
    vertex_array_name: VertexArrayName,
}

impl VertexBuffer {
    /// Creates a new `VertexBuffer` object.
    pub fn new() -> VertexBuffer {
        let mut buffer_name = BufferName::null();
        let mut vertex_array_name = VertexArrayName::null();
        unsafe {
            gl::gen_buffers(1, &mut buffer_name);
            gl::gen_vertex_arrays(1, &mut vertex_array_name);
        }

        VertexBuffer {
            buffer_name: buffer_name,
            vertex_array_name: vertex_array_name,
        }
    }

    /// Fills the buffer with the contents of the data slice.
    pub fn set_data_f32(&mut self, data: &[f32]) {
        let data_ptr = data.as_ptr() as *const ();
        let byte_count = data.len() * mem::size_of::<f32>();

        unsafe {
            gl::bind_buffer(BufferTarget::Array, self.buffer_name);
            gl::buffer_data(
                BufferTarget::Array,
                byte_count as isize,
                data_ptr,
                BufferUsage::StaticDraw);
            gl::bind_buffer(BufferTarget::Array, BufferName::null());
        }
    }

    /// Specifies how the data for a particular vertex attribute is laid out in the buffer.
    pub fn set_attrib_f32(
        &mut self,
        attrib: AttributeLocation,
        elements: usize,
        stride: usize,
        offset: usize
    ) {
        unsafe {
            gl::bind_buffer(BufferTarget::Array, self.buffer_name);
            gl::bind_vertex_array(self.vertex_array_name);

            gl::enable_vertex_attrib_array(AttributeLocation::from_index(0));
            gl::vertex_attrib_pointer(
                attrib,
                elements as i32,
                GlType::Float,
                false,
                stride as i32,
                offset);

            gl::bind_vertex_array(VertexArrayName::null());
            gl::bind_buffer(BufferTarget::Array, BufferName::null());
        }
    }

    /// Draws the contents of the vertex buffer to the screen.
    pub fn draw(&self, draw_mode: DrawMode, offset: usize, count: usize) {
        unsafe {
            gl::bind_buffer(BufferTarget::Array, self.buffer_name);
            gl::bind_vertex_array(self.vertex_array_name);

            gl::draw_arrays(draw_mode, offset as i32, count as i32);

            gl::bind_vertex_array(VertexArrayName::null());
            gl::bind_buffer(BufferTarget::Array, BufferName::null());
        }
    }
}

impl Drop for VertexBuffer {
    fn drop(&mut self) {
        unsafe {
            gl::delete_buffers(1, &mut self.buffer_name);
            gl::delete_vertex_arrays(1, &mut self.vertex_array_name);
        }
    }
}
<|endoftext|>