From aa2180e6e99ba98d4b7b87264d6da8d01a063aeb Mon Sep 17 00:00:00 2001 From: Billy Price Date: Thu, 12 Mar 2026 10:25:30 -0700 Subject: [PATCH 1/2] API guideline improvements --- docs/api-guidelines.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/api-guidelines.md b/docs/api-guidelines.md index b6e7e75a..3d89e665 100644 --- a/docs/api-guidelines.md +++ b/docs/api-guidelines.md @@ -94,7 +94,7 @@ struct FooInner<'hw> { /* .. */ } #[derive(Default)] pub struct Resources<'hw> { - inner: Option + inner: Option> } pub struct Foo<'hw> { @@ -146,8 +146,8 @@ pub struct MyRunnableType<'hw> { impl<'hw> MyRunnableType<'hw> { pub fn new(resources: &mut Resources, /* .. */ ) -> Self { - let inner = resources.insert(RunnableTypeInner::new(/* .. */)) - /* .. */ + let inner = resources.insert(RunnableTypeInner::new(/* .. */)); + /* .. */ Self { inner } } } @@ -242,11 +242,13 @@ fn main() { ``` Notice that most of the complexity has been moved into internal implementation details and the client doesn't have to think about it. Also notice that if you want to add a new 'green thread', or change what state is available to which 'green threads' you can do that entirely in private code in the `run()` method, without requiring changes to your client. +Note that this can change the order in which your tasks are scheduled compared to having dedicated tasks for each worker function. If your code was making any assumptions about a specific task scheduling order among these worker functions, this will break those assumptions. Ensure that if you need to emit events from your service that need to be emitted in a specific order, you explicitly enforce that ordering in your code (e.g. via emitting all events from the same task). + ### Use traits for public methods expected to be used at run time whenever possible In most cases, public APIs in this repo should be exposed in terms of traits rather than methods directly on the object, and objects that need to interact with other embedded-services objects should refer to them by trait rather than by name. This does not apply to public methods used to construct or initialize a service, because those generally need to know something about the concrete implementation type to properly initialize it. -These traits should be defined in standalone 'interface' crates (i.e. `battery-service-interface`) alongside any support types needed for the interface (e.g. an Error enum) +These traits should be defined in standalone 'interface' crates (e.g. `battery-service-interface`) alongside any support types needed for the interface (e.g. an Error enum). __Reason__: Improved testability and customizability. Testability - if all our types interact with each other via traits rather than direct dependencies on the type, it makes it much easier to mock out individual components. @@ -280,4 +282,4 @@ impl embedded_services::ExampleService for OdpExampleService { fn bar(&mut self) -> Result<()> { /* .. */ } fn baz(&mut self) -> Result<()> { /* .. */ } } -``` \ No newline at end of file +``` From 29513f0b9523e2ea310800b0766908cb870734c1 Mon Sep 17 00:00:00 2001 From: Billy Price Date: Thu, 12 Mar 2026 10:27:30 -0700 Subject: [PATCH 2/2] fix syntax on some examples --- docs/api-guidelines.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/api-guidelines.md b/docs/api-guidelines.md index 3d89e665..1918abf6 100644 --- a/docs/api-guidelines.md +++ b/docs/api-guidelines.md @@ -98,7 +98,7 @@ pub struct Resources<'hw> { } pub struct Foo<'hw> { - inner: &'hw FooInner + inner: &'hw FooInner<'hw> } impl<'hw> Foo<'hw> { @@ -137,11 +137,11 @@ impl<'hw> MyRunnableTypeInner<'hw> { #[derive(Default)] pub struct Resources<'hw> { - inner: Option + inner: Option> } pub struct MyRunnableType<'hw> { - inner: &'hw MyRunnableTypeInner + inner: &'hw MyRunnableTypeInner<'hw> } impl<'hw> MyRunnableType<'hw> { @@ -195,15 +195,15 @@ impl<'hw> MyRunnableTypeInner<'hw> { #[derive(Default)] pub struct Resources<'hw> { - inner: Option + inner: Option> } pub struct MyRunnableType<'hw> { - inner: &'hw MyRunnableTypeInner + inner: &'hw MyRunnableTypeInner<'hw> } pub struct Runner<'hw> { - inner: &'hw MyRunnableTypeInner, + inner: &'hw MyRunnableTypeInner<'hw>, foo: Foo, bar: Bar, baz: Baz @@ -242,7 +242,7 @@ fn main() { ``` Notice that most of the complexity has been moved into internal implementation details and the client doesn't have to think about it. Also notice that if you want to add a new 'green thread', or change what state is available to which 'green threads' you can do that entirely in private code in the `run()` method, without requiring changes to your client. -Note that this can change the order in which your tasks are scheduled compared to having dedicated tasks for each worker function. If your code was making any assumptions about a specific task scheduling order among these worker functions, this will break those assumptions. Ensure that if you need to emit events from your service that need to be emitted in a specific order, you explicitly enforce that ordering in your code (e.g. via emitting all events from the same task). +Note that this can change the order in which your tasks are scheduled compared to having dedicated tasks for each worker function. If your code was making any assumptions about a specific task scheduling order among these worker functions, this will break those assumptions. Ensure that if you need to emit events from your service that need to be emitted in a specific order, you explicitly enforce that ordering in your code (e.g. via emitting all events from the same task or perhaps coordinating between tasks with channels or queues). ### Use traits for public methods expected to be used at run time whenever possible