Skip to content

feat: expose tags() and tags_mut() on all profile types#26

Open
harbik wants to merge 2 commits into
mainfrom
feat/tags-read-write-access
Open

feat: expose tags() and tags_mut() on all profile types#26
harbik wants to merge 2 commits into
mainfrom
feat/tags-read-write-access

Conversation

@harbik
Copy link
Copy Markdown
Owner

@harbik harbik commented Apr 25, 2026

Summary

  • Adds tags() returning &IndexMap<TagSignature, ProfileTagRecord> to RawProfile, all eight device-class wrappers, and the Profile enum — callers no longer need to use RawProfile directly just to read tags
  • Adds tags_mut() returning &mut IndexMap<TagSignature, ProfileTagRecord> with the same coverage, enabling removal and direct insertion of tags — operations not currently possible through the builder API
  • Expands the Quick Start section in lib.rs with three new subsections: Read header fields, Read tag values, and a tags_mut() example under Modify an existing profile
  • README regenerated from updated doc comments

Test plan

  • cargo test — all 44 tests pass
  • cargo xtask doc — docs build clean, README up to date

🤖 Generated with Claude Code

Add public tag map accessors to RawProfile, all device-class wrappers
(DisplayProfile, InputProfile, etc.), and the Profile enum, so callers
no longer need to work with RawProfile directly just to read or modify
tags.

- tags() returns &IndexMap<TagSignature, ProfileTagRecord>
- tags_mut() returns &mut IndexMap<TagSignature, ProfileTagRecord>,
  enabling removal and direct insertion of tags — operations not
  possible through the existing builder API
- Update lib.rs Quick Start docs with examples for reading header
  fields, reading tag values, and removing a tag via tags_mut()
- README regenerated from updated doc comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR exposes tag-map accessors (tags() / tags_mut()) across all profile entry points (raw profile, each device-class wrapper, and the Profile enum) so callers can read and directly edit ICC tags without needing to unwrap to RawProfile. It also expands the crate’s Quick Start documentation (and regenerates README.md) to show common header/tag inspection and mutation workflows.

Changes:

  • Add tags() and tags_mut() to RawProfile, Profile, and all device-class wrapper types via delegation.
  • Update crate-level docs in src/lib.rs with new “Read header fields”, “Read tag values”, and a tags_mut() example.
  • Regenerate README.md from the updated doc comments.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/profile/raw_profile.rs Adds tags() / tags_mut() accessors on RawProfile.
src/profile/delegate.rs Delegates tags() / tags_mut() to all device-class wrappers.
src/profile.rs Adds tags() / tags_mut() on the Profile enum forwarding to RawProfile.
src/lib.rs Expands Quick Start docs to demonstrate reading headers/tags and mutating tags.
README.md Regenerated output reflecting the updated crate-level docs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/profile.rs Outdated
Comment on lines +218 to +219
/// Tags are stored in insertion order, which matches the order they appear in the
/// original profile's tag table.
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

Same as RawProfile::tags() docs: stating the order "matches the order they appear in the original profile's tag table" can become false after callers mutate the map via tags_mut(). Consider qualifying this statement (e.g. "for profiles read from disk, before mutation").

Suggested change
/// Tags are stored in insertion order, which matches the order they appear in the
/// original profile's tag table.
/// Tags are stored in insertion order. For profiles read from disk, this initially
/// matches the order they appear in the original profile's tag table, before any
/// mutation via [`Self::tags_mut`].

Copilot uses AI. Check for mistakes.
Comment thread src/profile/raw_profile.rs Outdated

/// Returns a reference to the profile's tag map, keyed by [`TagSignature`].
///
/// Each [`ProfileTagRecord`] holds the tag's offset, size, and parsed [`Tag`] data.
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

Doc comment says ProfileTagRecord holds "parsed" Tag data, but Tag/TagData here is still the typed wrapper around the raw bytes (the fully parsed/serializable representation is ParsedTag via Tag::to_parsed()). Consider rewording to avoid implying the tag payload has already been parsed (e.g. say "typed Tag data" or reference ParsedTag explicitly).

Suggested change
/// Each [`ProfileTagRecord`] holds the tag's offset, size, and parsed [`Tag`] data.
/// Each [`ProfileTagRecord`] holds the tag's offset, size, and typed [`Tag`] data.

Copilot uses AI. Check for mistakes.
Comment thread src/profile/raw_profile.rs Outdated
Comment on lines +455 to +463
/// Tags are stored in insertion order, which matches the order they appear in the
/// original profile's tag table.
pub fn tags(&self) -> &IndexMap<TagSignature, ProfileTagRecord> {
&self.tags
}

/// Returns a mutable reference to the profile's tag map, keyed by [`TagSignature`].
///
/// Allows inserting, replacing, or removing tags directly. Note that removing
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

The docs state the IndexMap insertion order "matches the order they appear in the original profile's tag table"; that’s only guaranteed immediately after reading. Since tags_mut() allows removal/reinsertion, the order can diverge from the original. Consider qualifying the statement (e.g. "when read from disk" / "until modified").

Suggested change
/// Tags are stored in insertion order, which matches the order they appear in the
/// original profile's tag table.
pub fn tags(&self) -> &IndexMap<TagSignature, ProfileTagRecord> {
&self.tags
}
/// Returns a mutable reference to the profile's tag map, keyed by [`TagSignature`].
///
/// Allows inserting, replacing, or removing tags directly. Note that removing
/// Tags are stored in insertion order. Immediately after reading a profile from
/// disk, that order matches the order the tags appear in the original profile's
/// tag table. After modifications via [`Self::tags_mut`], the order may differ.
pub fn tags(&self) -> &IndexMap<TagSignature, ProfileTagRecord> {
&self.tags
}
/// Returns a mutable reference to the profile's tag map, keyed by [`TagSignature`].
///
/// Allows inserting, replacing, or removing tags directly. Removing and
/// reinserting tags may change their iteration order. Note that removing

Copilot uses AI. Check for mistakes.
Comment thread src/profile.rs Outdated
Comment on lines +217 to +219
/// Each [`ProfileTagRecord`] holds the tag's offset, size, and parsed [`crate::tag::Tag`] data.
/// Tags are stored in insertion order, which matches the order they appear in the
/// original profile's tag table.
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

Doc comment says ProfileTagRecord holds "parsed" Tag data, but the fully parsed representation is crate::tag::ParsedTag (via Tag::to_parsed()). Consider rewording to avoid confusion about whether Tag is already parsed vs still a typed wrapper around the raw bytes.

Suggested change
/// Each [`ProfileTagRecord`] holds the tag's offset, size, and parsed [`crate::tag::Tag`] data.
/// Tags are stored in insertion order, which matches the order they appear in the
/// original profile's tag table.
/// Each [`ProfileTagRecord`] holds the tag's offset, size, and [`crate::tag::Tag`] value.
/// Use [`crate::tag::Tag::to_parsed()`] to obtain the fully parsed
/// [`crate::tag::ParsedTag`] representation when needed. Tags are stored in
/// insertion order, which matches the order they appear in the original profile's
/// tag table.

Copilot uses AI. Check for mistakes.
- Replace "parsed Tag data" with "typed Tag value" — Tag/TagData is a
  typed bytes wrapper; ParsedTag (via to_parsed()) is the fully parsed
  form. Add a reference to Tag::to_parsed() and ParsedTag.
- Qualify the insertion-order guarantee: it holds immediately after
  reading from disk, but may change after mutation via tags_mut().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

3 participants