pub struct SyncItem {Show 13 fields
pub object_id: String,
pub version: u64,
pub updated_at: i64,
pub content_type: ContentType,
pub batch_id: Option<String>,
pub trace_parent: Option<String>,
pub trace_state: Option<String>,
pub content_hash: String,
pub last_accessed: u64,
pub access_count: u64,
pub content: Vec<u8>,
pub home_instance_id: Option<String>,
pub state: String,
/* private fields */
}Expand description
A wrapper struct that separates metadata from content.
§Binary-First Design
sync-engine is a dumb storage layer - it stores your bytes and routes
them to L1/L2/L3 based on SubmitOptions. The
content field is opaque Vec<u8> that we never interpret.
§Example
use sync_engine::SyncItem;
use serde_json::json;
// JSON content (serialize to bytes yourself)
let json_bytes = serde_json::to_vec(&json!({"name": "John Doe"})).unwrap();
let item = SyncItem::new("uk.nhs.patient.12345".into(), json_bytes);
assert_eq!(item.object_id, "uk.nhs.patient.12345");
assert_eq!(item.version, 1);Fields§
§object_id: StringReverse DNS style ID (e.g., uk.nhs.patient.record.1234567890)
version: u64Version number (monotonically increasing within this item)
updated_at: i64Last update timestamp (epoch millis)
content_type: ContentTypeContent type (json or binary) - determines storage format JSON → Redis HSET (searchable), SQL JSON column Binary → Redis SET, SQL BLOB column
batch_id: Option<String>Batch ID for tracking batch writes (UUID, set during batch flush)
trace_parent: Option<String>W3C Trace Context traceparent header (for cross-item trace linking) Format: “00-{trace_id}-{span_id}-{flags}” This is NOT for in-process tracing (that flows via Span::current()), but for linking related operations across items/time.
trace_state: Option<String>W3C Trace Context tracestate header (optional vendor-specific data)
content_hash: StringSHA256 hash of the content (hex-encoded). Computed eagerly on creation for CDC dedup and integrity checks.
last_accessed: u64Timestamp of last access (epoch millis)
access_count: u64Number of times accessed
content: Vec<u8>The actual payload (opaque binary, caller handles serialization)
home_instance_id: Option<String>Optional guest data owner ID (for routing engine)
state: StringArbitrary state tag for caller-defined grouping (e.g., “delta”, “base”, “pending”). Indexed in SQL and tracked via Redis SETs for fast state-based queries. Default: “default”
Implementations§
Source§impl SyncItem
impl SyncItem
Sourcepub fn new(object_id: String, content: Vec<u8>) -> Self
pub fn new(object_id: String, content: Vec<u8>) -> Self
Create a new SyncItem with binary content.
The content type is auto-detected: if the bytes are valid JSON,
content_type will be Json, otherwise Binary. This enables
intelligent storage routing (HSET vs SET in Redis, JSON vs BLOB in SQL).
§Example
use sync_engine::{SyncItem, ContentType};
// From raw bytes (detected as Binary)
let item = SyncItem::new("id".into(), vec![1, 2, 3]);
assert_eq!(item.content_type, ContentType::Binary);
// From JSON bytes (detected as Json)
let json = serde_json::to_vec(&serde_json::json!({"key": "value"})).unwrap();
let item = SyncItem::new("id".into(), json);
assert_eq!(item.content_type, ContentType::Json);Sourcepub fn from_json(object_id: String, value: Value) -> Self
pub fn from_json(object_id: String, value: Value) -> Self
Create a new SyncItem from a JSON value (convenience method).
This serializes the JSON to bytes and sets content_type to Json.
For binary formats (MessagePack, Cap’n Proto), use new.
Sourcepub fn from_serializable<T: Serialize>(
object_id: String,
value: &T,
) -> Result<Self, Error>
pub fn from_serializable<T: Serialize>( object_id: String, value: &T, ) -> Result<Self, Error>
Create a new SyncItem from any serializable type.
This avoids creating an intermediate serde_json::Value if you have a struct.
This is more efficient than from_json if you already have a typed object.
Sourcepub fn with_options(self, options: SubmitOptions) -> Self
pub fn with_options(self, options: SubmitOptions) -> Self
Set submit options for this item (builder pattern).
These options control where the item is stored (Redis, SQL) and how it’s compressed. Options travel with the item through the batch pipeline.
§Example
use sync_engine::{SyncItem, SubmitOptions, CacheTtl};
let item = SyncItem::new("cache.key".into(), b"data".to_vec())
.with_options(SubmitOptions::cache(CacheTtl::Minute));Sourcepub fn with_state(self, state: impl Into<String>) -> Self
pub fn with_state(self, state: impl Into<String>) -> Self
Set state tag for this item (builder pattern).
State is an arbitrary string for caller-defined grouping. Common uses: “delta”/“base” for CRDTs, “pending”/“approved” for workflows.
§Example
use sync_engine::SyncItem;
let item = SyncItem::new("crdt.123".into(), b"data".to_vec())
.with_state("delta");Sourcepub fn effective_options(&self) -> SubmitOptions
pub fn effective_options(&self) -> SubmitOptions
Get the effective submit options (returns default if not set).
Sourcepub fn content_as_json(&self) -> Option<Value>
pub fn content_as_json(&self) -> Option<Value>
Try to parse content as JSON.
Returns None if content is not valid JSON.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for SyncItem
impl<'de> Deserialize<'de> for SyncItem
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl !Freeze for SyncItem
impl RefUnwindSafe for SyncItem
impl Send for SyncItem
impl Sync for SyncItem
impl Unpin for SyncItem
impl UnwindSafe for SyncItem
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more