chore: enums for statement and op types#69
Conversation
src/middleware.rs
Outdated
| args.get(1).cloned(), | ||
| args.get(2).cloned(), | ||
| ); | ||
| Ok(match (op_code, arg_tup) { |
There was a problem hiding this comment.
Maybe we also need to include args.len() in the match to validate the arguments length of each operation
src/middleware.rs
Outdated
| }, | ||
| // TODO: Remaining ops. | ||
| _ => Ok(true) | ||
| pub fn check(&self, output_statement: &Statement) -> Result<bool> { |
There was a problem hiding this comment.
This function looks much cleaner with this refactor.
src/frontend.rs
Outdated
| (lt, $($arg:expr),+) => { Operation(NativeOperation::LtFromEntries, args!($($arg),*)) }; | ||
| (contains, $($arg:expr),+) => { Operation(NativeOperation::ContainsFromEntries, args!($($arg),*)) }; | ||
| (not_contains, $($arg:expr),+) => { Operation(NativeOperation::NotContainsFromEntries, args!($($arg),*)) }; | ||
| (eq, $($arg:expr),+) => { Operation::EqualFromEntries($(OperationArg::try_from($arg).unwrap()),*) }; |
There was a problem hiding this comment.
This is cool, now the compiler will complain when using the macro with the wrong number of arguments because it's building an enum.
src/middleware.rs
Outdated
| pub fn args(&self) -> &[OperationArg] { | ||
| &self.1 | ||
| /// Forms operation from op-code and arguments. | ||
| pub fn op(op_code: NativeOperation, args: &[Statement]) -> Result<Self> { |
There was a problem hiding this comment.
Is this method used anywhere?
|
Here's my summary of the new types for Statement and Operation introduced in this PR: And now some thoughts:
Overall I think there are two important points of discussion for this refactor:
For (i) I don't see any strong advantage on any direction. Compile-time checking is nice, but I don't think it's super useful for us. I think we can get a nice UX with runtime-checks and proper error reporting. Moreover for custom predicates we can't have compile-time checks; and if we want to unify the API for native predicates and custom predicates we may end up having an API that can't do compile-time checks for native predicates. Although I think it's nice that the backend can receive the statements and arguments already type-checked, so that it has less work to do. For (ii) I think having the enums in the middleware has benefits because it serves as spec and also allows us to keep the runtime checks in a single place with clean code. On the other hand, I think having the enums in the frontend may worsen the ergonomics. For (iii) I think this refactor as is would make it more costly to change operations / statements and how their arguments work in the future. For example if we decide to get rid of anchored keys, the current code would make it simpler than the code in this PR. If we decide to allow constants in any statement argument the same reasoning applies. This is another reason why I'm a bit hesitant to have the enum types in the frontend. |
| } | ||
|
|
||
| pub fn tickets_pod_builder(params: &Params, signed_pod: &SignedPod, expected_event_id: i64, expect_consumed: bool, blacklisted_emails: &Value) -> MainPodBuilder { | ||
| pub fn tickets_pod_builder( |
There was a problem hiding this comment.
This is just a formatting change right? Maybe we should include a rustfmt.toml in the repo to have a single formatting style. @arnaucube
|
looking good! |
Towards #65.