Skip to content

Allow interior mutability for the context, read_until_with_ctx to allow ASTERIX "Extended Length Data Items"#646

Open
goto40 wants to merge 34 commits intosharksforarms:masterfrom
goto40:feature/demo_ctx_with_cloneable_context
Open

Allow interior mutability for the context, read_until_with_ctx to allow ASTERIX "Extended Length Data Items"#646
goto40 wants to merge 34 commits intosharksforarms:masterfrom
goto40:feature/demo_ctx_with_cloneable_context

Conversation

@goto40
Copy link
Contributor

@goto40 goto40 commented Jan 19, 2026

TLDR; --> see "Main Changes"

Motivation: "Extended Length Data Items" consist of Arrays of data element like {x: u32, y: u32, fx: bool}. The fx is the control element which indicates the end of the array (fx==false / fx==0).

struct B {
    x: u8,
    y: u8,
    fx: u8,
}

However, user code shall not be aware of the fx field - it should only be used for I/O and be always correct: for writing this means to set fx=falseonly for the last element. For reading it means to read until fx==false. Importantly, for the programmer/user the data element look like {x: u32, y: u32} and fx is completely temporary (temp and temp_value).

struct B {
    x: u8,
    y: u8,
    #[deku(
        read_post_processing = "ctx.fx.set(*auto_fx!=0);",
        temp,
        temp_value = "if ctx.idx.get() < ctx.n {1} else {0}"
    )]
    auto_fx: u8,
}

Moreover, there may be an array of such elements. In this array we need access to the fx information (read until). If the fx field is completely temporary, you need to pass the info through the context back to the array (see example until_with_ctx) and set it in the inner element (see read_post_processing in the example above). We also need to allow a separate ctx for the read/write case (see ctx and writer_ctx), since the array length is only known in the writer case.

struct A {
    #[deku(
        until_with_ctx = "|_:&B,ctx:IndexContext| !ctx.fx.get()",
        ctx = "IndexContext { idx: std::rc::Rc::new(std::cell::Cell::new(0)), n: 0, fx: std::rc::Rc::new(std::cell::Cell::new(false))}",
        writer_ctx = "IndexContext { idx: std::rc::Rc::new(std::cell::Cell::new(0)), n: items.len(), fx: std::rc::Rc::new(std::cell::Cell::new(false)) }"
    )]
    items: Vec<B>,
}

I made some (non-breaking) changes to deku, which enabled me to implement the above technique (allowing an implementation of "Extended Length Data Items" of ASTERIX EUROCONTOL data structures).

Main changes:

  • Most Important: Changed the requirement that the context (Ctx) must be Copy in some calls.
    It is changed to Clone, this allows to add interior mutability in the context
    (like Rc<Cell<bool>>). This is no breaking change, since Copy implies Clone.
  • Added an attribute until_with_ctx: like until, but it also gets the context.
  • Added writer_ctx for fields: overrides ctx for the writer case - this allows
    a different context value for reader and writer (the reader gets the original
    ctx).
  • Added an attribute read_post_processing: code which is inserted after a field is
    read (including a temp field). You have full context access (and you can modify
    the context there
    ).
  • Added a unittest.
  • Updated docu (table of attributes)
  • Updated changelog

Additional changes:

  • reworked some test cases in order to explicitly name the type of the

@goto40
Copy link
Contributor Author

goto40 commented Jan 19, 2026

Note: I still get a failure (independently of my change?):

[9](https://github.com/sharksforarms/deku/actions/runs/21148115853/job/60818224874?pr=646#step:5:720)
thread 'test_compile::test_compile' (4947) panicked at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/trybuild-1.0.114/src/run.rs:102:13:
1 of 16 tests failed

@goto40 goto40 changed the title Feature/demo ctx with cloneable context Allow interior mutability for the context, read_until_with_ctx to allow ASTERIX "Extended Length Data Items" Jan 19, 2026
@goto40
Copy link
Contributor Author

goto40 commented Jan 19, 2026

Ah. I understand: I changed an error message. That's why the compile error check falls. I will have a look...

@goto40 goto40 force-pushed the feature/demo_ctx_with_cloneable_context branch from 140d973 to 7758a30 Compare January 23, 2026 18:43
@goto40 goto40 force-pushed the feature/demo_ctx_with_cloneable_context branch from ecad1bc to e34d40d Compare January 23, 2026 20:20
@goto40 goto40 force-pushed the feature/demo_ctx_with_cloneable_context branch from 5b57af6 to 148df77 Compare January 23, 2026 21:07
@goto40
Copy link
Contributor Author

goto40 commented Jan 24, 2026

... Still working on the coverage

@sharksforarms
Copy link
Owner

@goto40 thanks for the PR! I haven't gone through it yet - but I'm not too worried about coverage, it's more important to me that the introduced features have tests

@goto40
Copy link
Contributor Author

goto40 commented Jan 24, 2026

Ok. Thank you for the info. Please let me know if I should add more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants