Skip to content

Conversation

@ok-nick
Copy link
Contributor

@ok-nick ok-nick commented Oct 1, 2025

Implements a ReaderBuilder for constructing a Reader with settings and various other options. We may want to consider introducing a similar pattern to the Builder, although that may take additional design consideration.

For some background, we need methods of passing in Settings to a Reader or Builder that are instance-local, rather than thread-local. There are numerous reasons why this is needed that have taken place in other discussions. The reason we decided to introduce a ReaderBuilder is because it's impractical and arguably unidiomatic to create or change ~9 of the Reader constructors. It also offers much more flexibility and enables many new permutations of constructing a Reader.

Note that this is only an investigation, we may consider going the other route of providing an Asset struct to encapsulate assets, allowing us to cache a map of the files internals so we don't need to parse it multiple times.

Blocked by:

@ok-nick ok-nick changed the base branch from main to scouten/settings-not-thread-local October 14, 2025 15:20
@ok-nick
Copy link
Contributor Author

ok-nick commented Oct 15, 2025

Still needs docs and tests but marking as ready for further discussion.

@ok-nick ok-nick marked this pull request as ready for review October 15, 2025 15:29
Base automatically changed from scouten/settings-not-thread-local to main October 15, 2025 16:44
}
}

pub fn external_manifest(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be set_external_manifest(), otherwise it looks like a getter in Rust.

&self,
init_stream: &mut dyn CAIRead,
fragment_paths: &Vec<std::path::PathBuf>,
fragment_paths: &mut [Box<dyn CAIRead>],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are generally moving away from CaiRead and CaiWrite as we don't need them anymore. But since this function already uses CAIRead, I think this is ok here.

Comment on lines +76 to +78
pub struct ReaderBuilder {
settings: Settings,
external_manifest: Option<Box<dyn CAIRead>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be done as a ReaderAsset and include format and stream.

then we can call something like this on Reader

pub fn from_reader_asset(
    settings: &Settings,
    asset: ReaderAsset,
) -> Result<Reader> {
    let format = asset.format;
    let stream = asset.stream;
    if let Some(external_manifest) = asset.external_manifest {
        if let Some(fragments) = asset.fragments {
            Self::from_fragment(
                &format,
                stream,
                external_manifest,
                fragments,
            )
        } else {
            Self::from_manifest_data_and_stream(
                &jumbf_io::read_to_end(external_manifest)?,
                &format,
                stream,
            )
        }
    } else {
        Self::from_stream(&format, stream)
    }
}

@magaylor
Copy link
Contributor

Are there currently plans to expose this object to the c2pa_c_ffi path? I would love to be able to access this from binding code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants