ParcodeVisitor

Trait ParcodeVisitor 

Source
pub trait ParcodeVisitor {
    // Required methods
    fn visit<'a>(
        &'a self,
        graph: &mut TaskGraph<'a>,
        parent_id: Option<ChunkId>,
        config_override: Option<JobConfig>,
    );
    fn create_job<'a>(
        &'a self,
        config_override: Option<JobConfig>,
    ) -> Box<dyn SerializationJob<'a> + 'a>;

    // Provided methods
    fn serialize_shallow<W: Write>(&self, writer: &mut W) -> Result<()>
       where Self: Serialize { ... }
    fn serialize_slice<W: Write>(slice: &[Self], writer: &mut W) -> Result<()>
       where Self: Sized + Serialize { ... }
    fn visit_inlined<'a>(
        &'a self,
        _graph: &mut TaskGraph<'a>,
        _parent_id: ChunkId,
        _config_override: Option<JobConfig>,
    ) { ... }
}
Expand description

A trait for types that can be structurally visited to build a Parcode [TaskGraph].

This trait is the core abstraction for graph construction in Parcode. It allows types to define how they should be decomposed into nodes and how dependencies between nodes should be established.

§Relationship to Other Traits

  • serde::Serialize: Required for actual byte serialization (used by SerializationJob)
  • ParcodeVisitor: Defines graph structure (this trait)
  • SerializationJob: Executes the actual serialization of a node’s payload
  • ParcodeNative: Defines deserialization strategy (reader-side)

§Automatic Implementation

This trait is typically implemented automatically via #[derive(ParcodeObject)]. Manual implementation is only needed for custom serialization strategies.

§Thread Safety

Implementations must be Sync to support parallel graph execution. This is automatically satisfied for most types.

Required Methods§

Source

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Visits the object and populates the graph with nodes and dependencies.

This is the primary method for graph construction. It creates a node for the object, links it to its parent (if any), and recursively visits all remote children.

§Lifetimes
  • 'a: The lifetime of the graph and the data being serialized. The object must outlive 'a to enable zero-copy serialization (the graph holds references to the object’s data).
§Parameters
  • graph: The task graph being constructed. Nodes are added to this graph.
  • parent_id: The ID of the parent node, if this object is a child of another node. None indicates this is the root object.
  • config_override: Optional configuration to override default settings (e.g., compression).
§Behavior
  1. Creates a new node for this object using create_job
  2. Links the new node to the parent (if parent_id is Some)
  3. Recursively calls visit on all remote children (chunkable/map fields)
§Example
use parcode::graph::TaskGraph;
use parcode::visitor::ParcodeVisitor;

let my_object = vec![1, 2, 3];
let mut graph = TaskGraph::new();
my_object.visit(&mut graph, None, None); // Root object, no parent
Source

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Creates the serialization job for this object.

This method returns a boxed SerializationJob that knows how to serialize the object’s local fields (excluding remote children). The job will be executed later during graph execution.

§Parameters
  • config_override: Optional configuration to apply to this job (e.g., compression settings).
§Returns

A boxed SerializationJob with lifetime 'a, allowing it to hold references to self.

§Implementation Note

The derive macro typically implements this by cloning self and wrapping it in a job. For types with large local fields, consider implementing a custom job that holds references instead of cloning.

Provided Methods§

Source

fn serialize_shallow<W: Write>(&self, writer: &mut W) -> Result<()>
where Self: Serialize,

Serializes only the local fields of this object (excluding chunkable/map fields).

This method is used when the object is part of a collection and its local data needs to be serialized inline. Remote children are handled separately via visit_inlined.

§Default Implementation

The default implementation serializes the entire object using bincode. Types with chunkable fields should override this to serialize only local fields.

§Parameters
  • writer: The writer to serialize data into.
§Errors

Returns ParcodeError::Serialization if serialization fails.

§Example
use parcode::error::Result;
use serde::Serialize;

#[derive(Serialize)]
struct MyStruct { local_field: i32 }

impl MyStruct {
    // For a struct with local and remote fields:
    fn serialize_shallow<W: std::io::Write>(&self, writer: &mut W) -> Result<()> {
        // Only serialize local fields
        parcode::internal::bincode::serde::encode_into_std_write(&self.local_field, writer, parcode::internal::bincode::config::standard()).map_err(|e| parcode::ParcodeError::Serialization(e.to_string()))?;
        Ok(())
    }
}
Source

fn serialize_slice<W: Write>(slice: &[Self], writer: &mut W) -> Result<()>
where Self: Sized + Serialize,

Serializes a slice of objects.

This method is used to serialize collections of objects. The default implementation uses bincode to serialize the entire slice, which is efficient for types without chunkable fields.

§Override for Chunkable Types

Types with chunkable fields should override this method to:

  1. Serialize the slice length
  2. Call serialize_shallow for each element

This ensures that only local fields are serialized inline, while remote children are handled via visit_inlined.

§Parameters
  • slice: The slice of objects to serialize.
  • writer: The writer to serialize data into.
§Errors

Returns ParcodeError::Serialization if serialization fails.

Source

fn visit_inlined<'a>( &'a self, _graph: &mut TaskGraph<'a>, _parent_id: ChunkId, _config_override: Option<JobConfig>, )

Visits the object as an inlined item within a container (e.g., Vec).

In this mode, the object does NOT create a new node for itself, as its local data is already serialized in the container’s payload (via serialize_shallow). However, it must still visit its remote children (chunkable fields) and link them to the container’s node.

§When is this called?

This method is called when:

  • The object is an element in a Vec<T> where T has chunkable fields
  • The object is a value in a HashMap<K, V> where V has chunkable fields
§Default Implementation

The default implementation does nothing, which is correct for types without chunkable fields. Types with chunkable fields must override this to visit their remote children.

§Parameters
  • graph: The task graph being constructed.
  • parent_id: The ID of the container node (e.g., the Vec node).
  • config_override: Optional configuration override.
§Example
use parcode::visitor::ParcodeVisitor;
use parcode::graph::{TaskGraph, ChunkId, JobConfig};

struct MyStruct { remote_field: Vec<u8> }

impl MyStruct {
    // For a struct with a chunkable field:
    fn visit_inlined<'a>(&'a self, graph: &mut TaskGraph<'a>, parent_id: ChunkId, config: Option<JobConfig>) {
        // Visit remote children and link them to parent_id
        self.remote_field.visit(graph, Some(parent_id), None);
    }
}

Note: Users deriving ParcodeObject do not need to implement this manually.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl ParcodeVisitor for bool

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for f32

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for f64

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for i8

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for i16

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for i32

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for i64

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for i128

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for u8

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for u16

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for u32

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for u64

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for u128

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl ParcodeVisitor for String

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl<K, V> ParcodeVisitor for HashMap<K, V>
where K: Serialize + DeserializeOwned + Hash + Eq + Send + Sync + Clone + 'static, V: Serialize + DeserializeOwned + Send + Sync + Clone + ParcodeVisitor + 'static,

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl<T> ParcodeVisitor for Vec<T>
where T: ParcodeVisitor + Clone + Send + Sync + 'static + Serialize,

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Source§

impl<T: ParcodeVisitor> ParcodeVisitor for &T

Source§

fn visit<'a>( &'a self, graph: &mut TaskGraph<'a>, parent_id: Option<ChunkId>, config_override: Option<JobConfig>, )

Source§

fn create_job<'a>( &'a self, config_override: Option<JobConfig>, ) -> Box<dyn SerializationJob<'a> + 'a>

Implementors§