Repository: diesel-rs/diesel
File: diesel/src/query_builder/update_statement/changeset.rs (Rust)

Code before:
    DB: Backend,
    T: QueryFragment<DB>,
    U: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&self.target, out.reborrow())?;
        out.push_sql(" = ");
        QueryFragment::walk_ast(&self.expr, out.reborrow())
    }
}

/// Represents the left hand side of an assignment expression for an
/// assignment in [AsChangeset]. The vast majority of the time, this will
/// be a [Column]. However, in certain database backends, it's possible to
/// assign to an expression. For example, in Postgres, it's possible to
/// "UPDATE TABLE SET array_column\[1\] = 'foo'".
///
/// You shouldn't have to implement this trait. Expressions can be made
/// assignable with [AssignableExpression].
pub trait AssignmentTarget {
    /// Table the assignment is to
    type Table: Table;
    /// A wrapper around a type to assign to (this wrapper should implement
    /// [QueryFragment]).
    type QueryAstNode;

    /// Move this in to the AST node which should implement [QueryFragment].
    fn into_target(self) -> Self::QueryAstNode;
}

/// Represents a `Column` as an `AssignmentTarget`. The vast majority of
/// targets in an update statement will be `Column`s.
#[derive(Debug, Clone, Copy)]
pub struct ColumnWrapperForUpdate<C>(pub C);

impl<DB, C> QueryFragment<DB> for ColumnWrapperForUpdate<C>
where
    DB: Backend + DieselReserveSpecialization,
    C: Column,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.push_identifier(C::NAME)
    }
}

/// Trait to indicate that this type is valid to be the assignment
/// of an update statement.
pub trait AssignableExpression {
    /// An assignable expression is effectively operating on a transformation
    /// of a single column signified by this type.
    type Column: Column;

Review comment (suggestion):
This likely should be defined in a `mod private {}` + then be rexported as `pub(crate)` item from this module to make this diesel private.

See here: https://github.com/diesel-rs/diesel/blob/c237a74b63900b734c659a201fc1d6b87108033b/diesel/src/backend.rs#L390 for an example of this strategy.

Code after:
    DB: Backend,
    T: QueryFragment<DB>,
    U: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&self.target, out.reborrow())?;
        out.push_sql(" = ");
        QueryFragment::walk_ast(&self.expr, out.reborrow())
    }
}

/// Represents the left hand side of an assignment expression for an
/// assignment in [AsChangeset]. The vast majority of the time, this will
/// be a [Column]. However, in certain database backends, it's possible to
/// assign to an expression. For example, in Postgres, it's possible to
/// "UPDATE TABLE SET array_column\[1\] = 'foo'".
pub trait AssignmentTarget {
    /// Table the assignment is to
    type Table: Table;
    /// A wrapper around a type to assign to (this wrapper should implement
    /// [QueryFragment]).
    type QueryAstNode;

    /// Move this in to the AST node which should implement [QueryFragment].
    fn into_target(self) -> Self::QueryAstNode;
}

/// Represents a `Column` as an `AssignmentTarget`. The vast majority of
/// targets in an update statement will be `Column`s.
#[derive(Debug, Clone, Copy)]
pub struct ColumnWrapperForUpdate<C>(pub C);

impl<DB, C> QueryFragment<DB> for ColumnWrapperForUpdate<C>
where
    DB: Backend + DieselReserveSpecialization,
    C: Column,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.push_identifier(C::NAME)
    }
}

impl<C> AssignmentTarget for C
where
    C: Column,
{
    type Table = C::Table;
    type QueryAstNode = ColumnWrapperForUpdate<C>;

    fn into_target(self) -> Self::QueryAstNode {
        ColumnWrapperForUpdate(self)