# shared-struct
A procedural macro that transforms a struct into a shared, cheaply-cloneable wrapper with per-field fine-grained locking. Each field gets its own `tokio::sync::Mutex`, so concurrent access to different fields does not block. The wrapper itself is an `Arc` — cloning is cheap and all clones share the same data.
## Usage
```rust
use shared_struct::shared;
#[shared]
pub struct Context {
pub name: String,
count: u32,
#[raw]
pub tag: String,
}
```
### What gets generated
```rust
#[derive(Clone)]
pub struct Context(::std::sync::Arc<ContextInner>);
pub struct ContextInner {
pub name: ::tokio::sync::Mutex<String>,
count: ::tokio::sync::Mutex<u32>,
pub tag: String,
}
impl Context {
pub fn new(name: String, count: u32, tag: String) -> Self {
Self(::std::sync::Arc::new(ContextInner {
name: ::tokio::sync::Mutex::new(name),
count: ::tokio::sync::Mutex::new(count),
tag,
}))
}
pub async fn name(&self) -> ::tokio::sync::MutexGuard<'_, String> {
self.0.name.lock().await
}
async fn count(&self) -> ::tokio::sync::MutexGuard<'_, u32> {
self.0.count.lock().await
}
pub fn tag(&self) -> &String {
&self.0.tag
}
}
```
## Field attributes
| *(default)* | `Mutex<T>` | `async fn field(&self) -> MutexGuard<T>` |
| `#[raw]` | `T` (no lock) | `fn field(&self) -> &T` |
## Clone semantics
`clone()` is `Arc::clone` — all clones share the same data.
```rust
let ctx = Context::new("hello".to_string(), 0, "t".to_string());
let ctx2 = ctx.clone();
*ctx.name().await = "world".to_string();
assert_eq!(*ctx2.name().await, "world"); // same Arc
```
## Visibility
Field visibility is preserved on `ContextInner` and all accessors.
```rust
#[shared]
pub struct Foo {
pub public_field: String,
pub(crate) crate_field: u32,
private_field: bool,
}
```
## Dependencies
Runtime crate requires `tokio` with the `sync` feature.