Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ categories = ["network-programming", "web-programming"]
exclude.workspace = true

[workspace.package]
version = "0.30.10"
version = "0.31.1"
readme = "README.md"
edition = "2024"
authors = ["root@ltpp.vip"]
Expand All @@ -38,13 +38,13 @@ resolver = "3"
crate-type = ["rlib"]

[workspace.dependencies]
euv = { path = ".", version = "0.30.10" }
euv-ui = { path = "ui", version = "0.30.10" }
euv-cli = { path = "cli", version = "0.30.10" }
euv-core = { path = "core", version = "0.30.10" }
euv-engine = { path = "engine", version = "0.30.10" }
euv-macros = { path = "macros", version = "0.30.10" }
euv-example = { path = "example", version = "0.30.10" }
euv = { path = ".", version = "0.31.1" }
euv-ui = { path = "ui", version = "0.31.1" }
euv-cli = { path = "cli", version = "0.31.1" }
euv-core = { path = "core", version = "0.31.1" }
euv-engine = { path = "engine", version = "0.31.1" }
euv-macros = { path = "macros", version = "0.31.1" }
euv-example = { path = "example", version = "0.31.1" }

log = "0.4.34"
toml = "0.9.12"
Expand All @@ -57,7 +57,7 @@ hyperlane = "21.12.0"
serde_json = "1.0.151"
color-output = "10.2.3"
proc-macro2 = "1.0.107"
lombok-macros = "10.2.3"
lombok-macros = "10.2.7"
wasm-bindgen = "0.2.129"
alloc-no-stdlib = "3.0.0"
hyperlane-cli = "21.12.0"
Expand Down
26 changes: 23 additions & 3 deletions cli/src/build/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ use super::*;
pub struct Cli {
/// The mode to run in: run (build + server), build (build only), or fmt (format)
#[command(subcommand)]
///
/// Public: `cli/src/main.rs` is the `--bin euv` crate root, a
/// different crate from the `euv_cli` library, so its
/// `cli.get_command()` call cannot see a `pub(crate)` accessor. The
/// field is public to match that getter rather than the getter
/// narrowed to `pub(crate)`, which would fail with E0624 at the bin
/// call site. `get_mut` / `set` stay crate-internal — clap's derive
/// is the only writer and nothing mutates the mode in place.
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) command: Mode,
pub command: Mode,
}

/// euv-specific arguments combined with wasm-pack passthrough.
Expand Down Expand Up @@ -84,14 +92,26 @@ pub struct ModeArgs {
///
/// Formats euv macro invocations (`html!`, `class!`, `vars!`, `watch!`)
/// in Rust source files.
#[derive(Clone, Data, Debug, New, Parser)]
#[derive(Clone, Debug, Getter, New, Parser)]
pub struct FmtArgs {
/// Path to the directory or file to format
#[arg(short, long, default_value = ".")]
///
/// Narrowed to `pub(crate)`: the only getter call sites are in
/// `cli/src/mode/fn.rs`, which is inside this crate. The integration
/// test constructs a `FmtArgs` through `FmtArgs::new` /
/// `FmtArgs::parse_from` but never reads the field, so no public
/// accessor is required. `Getter` does not generate mutators — no
/// caller anywhere mutates the path after parsing.
#[get(pub(crate))]
pub(crate) path: PathBuf,
/// Check if formatting is needed without modifying files
#[arg(long, default_value_t = false)]
#[get(type(copy))]
///
/// Narrowed for the same reason as [`FmtArgs::path`]: the flag is read
/// only by `cli/src/mode/fn.rs`, and clap's derive is what writes it,
/// so `Getter` is the right derive — it generates no mutators.
#[get(pub(crate), type(copy))]
pub(crate) check: bool,
}

Expand Down
8 changes: 1 addition & 7 deletions core/src/event/handler/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ use super::*;
#[new(pub(crate))]
pub struct NativeEventHandler {
/// The name of the event (e.g., "click", "input").
#[get(type(copy))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get(pub(crate))]
#[get(type(copy), pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) event_name: &'static str,
Expand All @@ -24,8 +21,5 @@ pub struct NativeEventHandler {
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) callback: SharedEventCallback,
}
8 changes: 4 additions & 4 deletions core/src/reactive/cache/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ where
///
/// - `bool` - A boolean.
pub fn is_full(&self) -> bool {
self.get_map().len() >= *self.get_capacity()
self.get_map().len() >= self.get_capacity()
}

/// Returns `true` if the cache contains a value for
Expand Down Expand Up @@ -107,7 +107,7 @@ where
/// - `Option<(K, V)>` - `Some(...)` on success, `None` otherwise.
pub fn put(&mut self, key: K, value: V) -> Option<(K, V)> {
// Capacity of 0 — silently drop.
if *self.get_capacity() == 0 {
if self.get_capacity() == 0 {
return None;
}
// Updating an existing key.
Expand All @@ -121,7 +121,7 @@ where
return None;
}
// Inserting a new key. Evict if at capacity.
let evicted: Option<(K, V)> = if self.get_map().len() >= *self.get_capacity() {
let evicted: Option<(K, V)> = if self.get_map().len() >= self.get_capacity() {
let victim_key: K = self.get_mut_order().pop_back()?;
let victim_value: V = self.get_mut_map().remove(&victim_key)?;
Some((victim_key, victim_value))
Expand Down Expand Up @@ -205,7 +205,7 @@ where
/// - `usize` - A non-negative integer (`usize`).
pub fn resize(&mut self, new_capacity: usize) {
self.set_capacity(new_capacity);
while self.get_map().len() > *self.get_capacity() {
while self.get_map().len() > self.get_capacity() {
if let Some(victim_key) = self.get_mut_order().pop_back() {
self.get_mut_map().remove(&victim_key);
} else {
Expand Down
5 changes: 2 additions & 3 deletions core/src/reactive/cache/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ where
{
/// The maximum number of entries before eviction
/// kicks in.
#[get(pub(crate))]
#[get(pub(crate))]
#[get(type(copy), pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) capacity: usize,
pub capacity: usize,
/// The current entries, keyed by K. Default-initialised
/// via `#[new(skip)]` (`HashMap::new()`).
#[new(skip)]
Expand Down
3 changes: 1 addition & 2 deletions core/src/reactive/hook/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ pub struct HookContext {
#[derive(Clone, Copy, Data, Debug, Default, Eq, Hash, New, Ord, PartialEq, PartialOrd)]
pub struct IntervalHandle {
/// The interval ID assigned by the browser.
#[get(type(copy))]
#[get(pub(crate))]
#[get(type(copy), pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) interval_id: i32,
Expand Down
56 changes: 27 additions & 29 deletions core/src/reactive/signal/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,55 +11,57 @@ where
/// The current value of the signal.
#[debug(skip)]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) value: T,
/// Callbacks to invoke when the value changes, each paired with its
/// subscription id so [`Signal::unsubscribe`] can detach a single
/// listener without disturbing the rest.
#[debug(skip)]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) listeners: Vec<ListenerEntry>,
/// Monotonic counter backing subscription ids for `listeners`.
#[get(type(copy))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[new(skip)]
#[get(pub(crate), type(copy))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) next_listener_id: usize,
/// Ids detached via [`Signal::unsubscribe`] while `update` had the
/// listener list swapped out. Drained by `update`'s merge-back pass so
/// a listener detached mid-notification is not resurrected.
#[debug(skip)]
#[new(skip)]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[new(skip)]
#[get_mut(pub(crate))]
pub(crate) removed_listener_ids: Vec<usize>,
/// `true` while `update` has the listener list swapped out for
/// notification. `unsubscribe` consults this flag to decide between
/// direct removal and deferred removal via `removed_listener_ids`.
#[get(type(copy))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[new(skip)]
#[get(pub(crate), type(copy))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) notifying: bool,
/// Whether this signal is still active. Set to `false` by `deactivate()`
/// (and `clear_signal_listeners`) to make subsequent `set()` calls
/// complete no-ops (no value update, no listener invocation, no
/// dispatch scheduling), ensuring stale closures like orphaned
/// `setInterval` handlers or pending `spawn_local` futures become harmless.
#[get(type(copy))]
#[get_mut(pub(crate))]
#[get(pub(crate), type(copy))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) alive: bool,
/// IDs of dynamic nodes that depend on this signal for precise dirty marking.
/// When this signal changes, only these dynamic nodes are marked dirty
/// instead of broadcasting to all registered dynamic nodes.
#[debug(skip)]
#[get_mut(pub(crate))]
#[new(skip)]
#[get(pub(crate))]
#[set(pub(crate))]
pub(crate) dependents: Vec<usize>,
}

Expand All @@ -78,22 +80,25 @@ where
T: Clone + PartialEq + 'static,
{
/// Slot index of the inner state in the global signal slab.
///
/// The field is public because `get_inner` must stay public:
/// `macros/tests/watch` reads the slot address from outside this
/// crate to prove the signal handle is stable across a panic. A
/// public getter over a `pub(crate)` field is exactly the
/// `public-accessor-leaks-restricted-field` leak, so the field is
/// promoted to match rather than the getter narrowed. `set` /
/// `get_mut` stay crate-internal — the slot never moves.
#[debug(skip)]
#[get(type(copy))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) inner: usize,
pub inner: usize,
/// Marker for the generic type parameter (uses fn pointer to be `Copy`
/// regardless of `T`).
#[debug(skip)]
#[get(type(copy))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) _marker: PhantomData<fn() -> T>,
}

Expand All @@ -111,13 +116,9 @@ where
{
/// Interior-mutable storage for an optional signal handle.
#[debug(skip)]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) inner: UnsafeCell<Option<Signal<T>>>,
pub inner: UnsafeCell<Option<Signal<T>>>,
}

/// Typed slab allocator for `SignalInner<T>`.
Expand All @@ -134,8 +135,8 @@ where
pub(crate) struct SignalSlab {
/// Slot storage. Index 0..len.
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
#[get_mut(pub(crate))]
pub(crate) entries: Vec<Box<dyn AnySignalInner>>,
}

Expand All @@ -155,11 +156,8 @@ pub(crate) struct SignalSlab {
#[derive(Clone, Copy, CustomDebug, Data, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct FireHandle {
/// Address of the leaked `Box<dyn FnMut()>` allocation.
#[get(type(copy))]
#[get_mut(pub(crate))]
#[get(pub(crate), type(copy))]
#[set(pub(crate))]
#[get(pub(crate))]
#[get_mut(pub(crate))]
#[set(pub(crate))]
pub(crate) inner: usize,
}
Loading
Loading