Rust::com Field and Method Rust Design and Example of APIs usage - #818
bharatGoswami8 wants to merge 28 commits into
Conversation
c5cf7de to
0920265
Compare
|
Putting to draft since state is not ready for review. |
2f4596b to
722ccaa
Compare
b7ffe17 to
7e70cbc
Compare
Addressed all the clippy and design comment. |
| interface!( | ||
| interface VehicleMethods { | ||
| Id = "VehicleMethodsInterface", | ||
| update_tire_pressure(Tire) -> (), |
There was a problem hiding this comment.
(Applies to all method declarations) For the sake of symmetry I would vote for a slightly different syntax:
| update_tire_pressure(Tire) -> (), | |
| update_tire_pressure: Method(Tire) -> (), |
This resembles Fn bounds and should be familiar to Rust developers. In addition, this makes the declaration look similar to fields and events.
There was a problem hiding this comment.
Yes agreed, updated macro signature for method.
| Id = "VehicleMethodsInterface", | ||
| update_tire_pressure(Tire) -> (), | ||
| update_front_tires_pressure(Tire, Tire) -> (), | ||
| get_tire_pressure() -> Tire, |
There was a problem hiding this comment.
Imo the examples aren't that compelling as the method calls declared here are very close to similar methods from fields (update_... and get_...). It would be better if there were a method that are quite different (something like calculate_hash_for: Method(&[u8], hash_type: HashType) -> u32).
There was a problem hiding this comment.
Updated example and macro configuration.
| // Allocate return the tuple of uninitialized method argument slots, | ||
| // We need to store in tuple format, or user need to access using uninit1.0.write(...) | ||
| let (uninit1,) = consumer | ||
| .update_tire_pressure |
There was a problem hiding this comment.
How would that work? In line 69 it looks like a callable, but here it looks like an object. Mixing this is afaik only possible by implementing an unstable Fn trait. Or did you find another solution for that?
There was a problem hiding this comment.
We are not using the unstable Fn trait. update_front_tires_pressure is an object (struct field) we get from the consumer struct, and a method with the same name is generated in the consumer's impl block by our interface macro.
And the underlying invocation happens using static dispatch via generic trait bounds (MethodCallInput), compiler generates a separate concrete function per type combination and picks the right one for each call site while compiling, not dynamic (dyn) trait dispatch, as shown in the example.
// A "dispatch" trait
trait CallMethod<Ret> {
fn dispatch(self) -> Ret;
}
// Impl for "copy path"
impl CallMethod<String> for i32 {
fn dispatch(self) -> String {
format!("copy path, value = {}", self)
}
}
// Impl for "zero-copy path"
struct Ptr(i32);
impl CallMethod<String> for Ptr {
fn dispatch(self) -> String {
format!("zero-copy path, ptr value = {}", self.0)
}
}
struct Caller;
struct Consumer {
// field named the same as the method below
my_method: Caller,
}
impl Consumer {
// generic inherent method, same name as the field
fn my_method<A>(&self, arg: A) -> String
where
A: CallMethod<String>,
{
arg.dispatch()
}
}
* Created Method related interface traits * Updated Interface macro * created method related macro
* For generating type state pattern for method and field * Validating offer API call
* Added impl block for method interface
* Added impl block for method interface traits
* Updated import score_com crate
* Added method api usage in example app
* Updated concept crate documentation * Updated interface macro document * Update type state macro document
* Updated return value to MethodReturnSample
* Added design markdown file and diagrams
* Added MethodReturnSample for returning value at consumer side * MethodInArgPtr trait added for argument type
* Created field interface APIs * Updated SampleMut to use in field as well
* Lola Runtime placeholder implementaion for field producer and consumer * Mock Runtime placeholder implementation
* Create proc macro for field init and set handler validation before offer call
* Updated example file with Field APIs usage
* Method and field both code generation added on macros
* Removed the separate set-get method and introduced field method using Method interface
* Added Getter, Setter, Notifier tag for field feature to enable
* Create separate file for Producer and Consumer interface macro
* Updated set and get APIs for registration
* Updated tags for field to generate the field specific methods * Updated intefrca macro as well
* Created trait level document design * document for field desing
* set method returns the value * Method API take the value by reference
c0869c2 to
d787ca5
Compare
* Interface Macro uodated * Updated method example
d787ca5 to
6831b5f
Compare
For Method and Field Design following things added -
Field subscribe/receive (
FieldSubscriber,FieldSubscriptiontraits): a consumer can subscribe to a field, receive value updates.Field publish/update (
FieldPublishertrait): a producer canupdate()a field value, register asethandler (called when a consumer sets the field), and register agethandler.Field get/set on the consumer side reuse Method infrastructure:
get_{name}()/set_{name}()async helpers are generated by theinterface!macro usingMethodCallerthere is no separate field-get/set trait.Method traits (
MethodHandlerfor producer,MethodCallerfor consumer): supports up to 8 arguments via tuple-based arities, with both copy and zero-copy call paths.Type-state derive macro (
#[derive(TypeStateValidator)]): generates compile-time state transitions so a producer struct cannot calloffer()before all fields are initialized and all handlers are registered.Interface macros split into producer and consumer:
interface_producer_macros.rsgenerates the skeleton struct with all fields/methods/events;interface_consumer_macros.rsgenerates the proxy struct.Runtime stub added to build the APIs example usage.
Example app with field_producer.rs,
field_consumer.rs,method_producer.rs,method_consumer.rsmodules showing the API usage end-to-end.Design documents and diagrams for both Field and Method architecture added.
#579