|
1 | 1 | use core::convert::{TryFrom, TryInto}; |
2 | | -use std::collections::HashSet; |
| 2 | +use std::collections::{HashMap, HashSet}; |
3 | 3 | use std::io::Cursor; |
4 | 4 |
|
5 | 5 | use deku::prelude::*; |
@@ -406,3 +406,60 @@ fn test_interior_mutability_for_context_read_until_with_ctx_hashset() { |
406 | 406 | let check_data = A::from_bytes((&[8, 9, 0, 1, 7, 9, 1, 0], 0)).unwrap().1; |
407 | 407 | assert_eq!(check_data.items.len(), 2); |
408 | 408 | } |
| 409 | + |
| 410 | +#[test] |
| 411 | +fn test_interior_mutability_for_context_read_until_with_ctx_hashmap() { |
| 412 | + #[derive(Debug, Clone)] |
| 413 | + struct IndexContext { |
| 414 | + idx: std::rc::Rc<std::cell::Cell<usize>>, |
| 415 | + n: usize, |
| 416 | + fx: std::rc::Rc<std::cell::Cell<bool>>, |
| 417 | + } |
| 418 | + #[deku_derive(DekuRead, DekuWrite)] |
| 419 | + #[derive(PartialEq, Debug, Clone)] |
| 420 | + struct A { |
| 421 | + #[deku( |
| 422 | + until_with_ctx = "|x:&(B,B),ctx:IndexContext| !ctx.fx.get()", |
| 423 | + ctx = "IndexContext { idx: std::rc::Rc::new(std::cell::Cell::new(0)), n: 0, fx: std::rc::Rc::new(std::cell::Cell::new(false))}", |
| 424 | + 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)) }" |
| 425 | + )] |
| 426 | + items: HashMap<B, B>, |
| 427 | + } |
| 428 | + |
| 429 | + #[deku_derive(DekuRead, DekuWrite)] |
| 430 | + #[derive(PartialEq, Debug, Clone, Eq, Hash)] |
| 431 | + #[deku( |
| 432 | + ctx = "ctx: IndexContext", |
| 433 | + ctx_default = "IndexContext{idx: std::rc::Rc::new(std::cell::Cell::new(0)), n: 0, fx: std::rc::Rc::new(std::cell::Cell::new(false))}" |
| 434 | + )] // this struct uses a context for serialization. For deserialization it also works with the default context. |
| 435 | + struct B { |
| 436 | + x: u8, |
| 437 | + y: u8, |
| 438 | + #[deku( |
| 439 | + temp, |
| 440 | + temp_value = "{let ret = ctx.idx.get() as u8; ctx.idx.set(ctx.idx.get()+1); ret}" |
| 441 | + )] |
| 442 | + idx_automatically_filled: u8, |
| 443 | + #[deku( |
| 444 | + read_post_processing = "ctx.fx.set(*auto_fx!=0);", |
| 445 | + temp, |
| 446 | + temp_value = "if ctx.idx.get() < ctx.n {1} else {0}" |
| 447 | + )] |
| 448 | + auto_fx: u8, |
| 449 | + } |
| 450 | + |
| 451 | + let test_data = A { |
| 452 | + items: HashMap::from([ |
| 453 | + (B { x: 8, y: 9 }, B { x: 8, y: 9 }), |
| 454 | + (B { x: 8, y: 9 }, B { x: 7, y: 9 }), |
| 455 | + (B { x: 8, y: 9 }, B { x: 6, y: 9 }), |
| 456 | + ]), |
| 457 | + }; |
| 458 | + |
| 459 | + let ret_write: Vec<u8> = test_data.clone().try_into().unwrap(); |
| 460 | + assert_eq!(ret_write.last().unwrap(), &0); |
| 461 | + |
| 462 | + // read the data back |
| 463 | + let check_data = A::from_bytes((&ret_write, 0)).unwrap().1; |
| 464 | + assert_eq!(check_data, test_data); |
| 465 | +} |
0 commit comments