Skip to content
3 changes: 2 additions & 1 deletion documentation/server.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from http.server import HTTPServer, SimpleHTTPRequestHandler
from os import chdir
from typing import override


class RequestHandler(SimpleHTTPRequestHandler):
@override
def end_headers(self):
# Add custom headers here
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
super().end_headers()
Expand Down
32 changes: 32 additions & 0 deletions documentation/source/field-attributes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Field Attributes

To ignore a field or variant, annotate it with `#[serde(skip)]`. This is useful when transferring partially private data because it allows you to specify which data is exposed to Dart. See Serde's documentation on [variant](https://serde.rs/variant-attrs.html) and [field](https://serde.rs/field-attrs.html) attributes for more information on how Serde handles this attribute.

```{code-block} rust
:caption: Rust
#[derive(Serialize, RustSignal)]
struct UpdateMessage {
event: String,
struct_data: StructData,
enum_data: EnumData,
}

#[derive(Serialize, SignalPiece)]
struct StructData {
my_public_field: bool,
#[serde(skip)]
my_private_field: bool,
}

#[derive(Serialize, SignalPiece)]
enum EnumData {
Variant1(i32, #[serde(skip)] i32),
Variant2 {
my_public_field: bool,
#[serde(skip)]
my_private_field: bool,
},
}
```

Some attributes from Serde are banned at compile-time. This is because `rinf gen` analyzes Rust code statically by reading type annotations, and it cannot infer the type behind special Serde attributes like `#[serde(with = "...")]`. This mechanism ensures that `rinf gen` always produces exactly corresponding Dart code from Rust structs.
1 change: 1 addition & 0 deletions documentation/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
running-and-building.md
messaging.md
field-types.md
field-attributes.md
tutorial.md
state-management.md
error-handling.md
Expand Down
33 changes: 1 addition & 32 deletions documentation/source/messaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ If you add the optional argument `-w` or `--watch` to the `rinf gen` command, th
rinf gen --watch
```

## Channel Signals
## Endpoint Signals

The `RustSignal` trait generates a signal stream from Rust to Dart.[^2] Use the `RustSignalBinary` trait to include binary data without the overhead of serialization.

Expand Down Expand Up @@ -119,34 +119,3 @@ struct Inner {
my_field: bool,
}
```

## Ignoring fields / variants

To ignore a field or variant, annotate it with `#[serde(skip)]`. This is useful when transferring partially private data because it allows you to specify which data is exposed to Dart. See Serde's documentation on [variant](https://serde.rs/variant-attrs.html) and [field](https://serde.rs/field-attrs.html) attributes for more information on how Serde handles this attribute.

```{code-block} rust
:caption: Rust
#[derive(Serialize, RustSignal)]
struct UpdateMessage {
event: String,
struct_data: StructData,
enum_data: EnumData,
}

#[derive(Serialize, SignalPiece)]
struct StructData {
my_public_field: bool,
#[serde(skip)]
my_private_field: bool,
}

#[derive(Serialize, SignalPiece)]
enum EnumData {
Variant1(i32, #[serde(skip)] i32),
Variant2 {
my_public_field: bool,
#[serde(skip)]
my_private_field: bool,
},
}
```
18 changes: 10 additions & 8 deletions rust_crate_cli/src/tool/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ fn trace_struct(traced: &mut Traced, item: &ItemStruct) {
let fields: Vec<Format> = unnamed
.unnamed
.iter()
.filter(is_kept)
.filter(is_exposed)
.map(|field| to_type_format(&field.ty))
.collect();
if fields.is_empty() {
Expand All @@ -240,7 +240,7 @@ fn trace_struct(traced: &mut Traced, item: &ItemStruct) {
let fields = named
.named
.iter()
.filter(is_kept)
.filter(is_exposed)
.filter_map(|field| {
field.ident.as_ref().map(|ident| Named {
name: ident.to_string(),
Expand All @@ -266,7 +266,7 @@ fn trace_enum(traced: &mut Traced, item: &ItemEnum) {
let variants: BTreeMap<u32, Named<VariantFormat>> = item
.variants
.iter()
.filter(is_kept)
.filter(is_exposed)
.map(|variant| {
let name = variant.ident.to_string();
let variant_format = match &variant.fields {
Expand All @@ -275,7 +275,7 @@ fn trace_enum(traced: &mut Traced, item: &ItemEnum) {
let fields = unnamed
.unnamed
.iter()
.filter(is_kept)
.filter(is_exposed)
.map(|field| to_type_format(&field.ty))
.collect::<Vec<_>>();
if fields.is_empty() {
Expand All @@ -290,7 +290,7 @@ fn trace_enum(traced: &mut Traced, item: &ItemEnum) {
let fields = named
.named
.iter()
.filter(is_kept)
.filter(is_exposed)
.filter_map(|field| {
field.ident.as_ref().map(|ident| Named {
name: ident.to_string(),
Expand All @@ -316,8 +316,8 @@ fn trace_enum(traced: &mut Traced, item: &ItemEnum) {
traced.registry.insert(type_name, container);
}

/// Returns `false` if Serde skips `item` during serialization.
fn is_kept<T: GetAttrs>(item: &T) -> bool {
/// Returns `false` if Serde skips the field item during serialization.
fn is_exposed<T: GetAttrs>(item: &T) -> bool {
!item.get_attrs().iter().any(|attr| {
if !attr.path().is_ident("serde") {
return false;
Expand All @@ -333,15 +333,17 @@ fn is_kept<T: GetAttrs>(item: &T) -> bool {
})
}

/// Helper trait required for [`is_kept`].
/// Helper trait required for [`is_exposed`].
trait GetAttrs {
fn get_attrs(&self) -> &Vec<Attribute>;
}

impl GetAttrs for &Field {
fn get_attrs(&self) -> &Vec<Attribute> {
&self.attrs
}
}

impl GetAttrs for &Variant {
fn get_attrs(&self) -> &Vec<Attribute> {
&self.attrs
Expand Down
Loading
Loading