@yxckjhasdkjh I had the same problem to solve. My expressions are SQL expressions. And I want to let the user mix and match custom expressions with regular Swift values:
Player.select(Column("score") * 2)
Note that I don't use ExpressibleBy...Literal protocols. Instead, I use raw Int, String values, etc.
My solution was to define two protocols. One for specific expressions (columns, etc.), and one for expressions in general:
protocol SQLExpressible { ... }
protocol SpecificSQLExpressible: SQLExpressible { ... }
"Pure" sql types adopt SpecificSQLExpressible:
struct Column: SpecificSQLExpressible { ... }
struct Product: SpecificSQLExpressible { ... }
Regular Swift values adopt SQLExpressible:
extension Int: SQLExpressible { ... }
extension String: SQLExpressible { ... }
When I want to derive an expression from two other ones, I define three variants:
func * (lhs: SpecificSQLExpressible, rhs: SpecificSQLExpressible) -> Product {
return Product(lhs, rhs)
}
func * (lhs: SpecificSQLExpressible, rhs: SQLExpressible) -> Product {
return Product(lhs, rhs)
}
func * (lhs: SQLExpressible, rhs: SpecificSQLExpressible) -> Product {
return Product(lhs, rhs)
}
Note that the (SQLExpressible, SQLExpressible) is avoided, because it would pollute the API of regular types (Int, String, etc.)
You get:
Column("score") * 2 // Product
2 * Column("score") // Product
Column("score") * Column("multipliier") // Product
2 * 2 // 4
Maybe this could help you,