pub struct Record {
pub leader: Leader,
pub control_fields: IndexMap<String, String>,
pub fields: IndexMap<String, Vec<Field>>,
}Expand description
A MARC bibliographic record
Fields are stored in insertion order using IndexMap, preserving the order
in which fields were added to the record. This ensures round-trip fidelity
when serializing and deserializing records.
Fields§
§leader: LeaderRecord leader (24 bytes)
control_fields: IndexMap<String, String>Control fields (000-009) - tag -> value, preserves insertion order
fields: IndexMap<String, Vec<Field>>Data fields (010+) - tag -> fields, preserves insertion order
Implementations§
Source§impl Record
impl Record
Sourcepub fn builder(leader: Leader) -> RecordBuilder
pub fn builder(leader: Leader) -> RecordBuilder
Create a builder for fluently constructing MARC records
§Examples
use mrrc::{Record, Leader, Field};
let leader = Leader {
record_length: 0,
record_status: 'n',
record_type: 'a',
bibliographic_level: 'm',
control_record_type: 'a',
character_coding: ' ',
indicator_count: 2,
subfield_code_count: 2,
data_base_address: 0,
encoding_level: ' ',
cataloging_form: ' ',
multipart_level: ' ',
reserved: "4500".to_string(),
};
let record = Record::builder(leader)
.control_field_str("001", "12345")
.field(Field::builder("245".to_string(), '1', '0')
.subfield_str('a', "Title")
.build())
.build();Sourcepub fn add_control_field(&mut self, tag: String, value: String)
pub fn add_control_field(&mut self, tag: String, value: String)
Add a control field (000-009)
Sourcepub fn add_control_field_str(&mut self, tag: &str, value: &str)
pub fn add_control_field_str(&mut self, tag: &str, value: &str)
Add a control field using string slices
Convenience method that converts &str arguments to String automatically.
Sourcepub fn get_control_field(&self, tag: &str) -> Option<&str>
pub fn get_control_field(&self, tag: &str) -> Option<&str>
Get a control field value
Sourcepub fn get_fields(&self, tag: &str) -> Option<&[Field]>
pub fn get_fields(&self, tag: &str) -> Option<&[Field]>
Get all fields with a given tag
Sourcepub fn fields_by_tag(&self, tag: &str) -> impl Iterator<Item = &Field>
pub fn fields_by_tag(&self, tag: &str) -> impl Iterator<Item = &Field>
Sourcepub fn control_fields_iter(&self) -> impl Iterator<Item = (&str, &str)>
pub fn control_fields_iter(&self) -> impl Iterator<Item = (&str, &str)>
Iterate over all control fields
Returns an iterator of (tag, value) tuples.
Sourcepub fn fields_by_indicator(
&self,
tag: &str,
indicator1: Option<char>,
indicator2: Option<char>,
) -> impl Iterator<Item = &Field>
pub fn fields_by_indicator( &self, tag: &str, indicator1: Option<char>, indicator2: Option<char>, ) -> impl Iterator<Item = &Field>
Iterate over fields matching a specific indicator pattern.
§Arguments
tag- The field tag to searchindicator1- First indicator value, orNoneto match anyindicator2- Second indicator value, orNoneto match any
§Examples
// Find all 650 fields with indicator2='0' (LCSH)
for field in record.fields_by_indicator("650", None, Some('0')) {
println!("LCSH: {:?}", field);
}Sourcepub fn fields_in_range(
&self,
start_tag: &str,
end_tag: &str,
) -> impl Iterator<Item = &Field>
pub fn fields_in_range( &self, start_tag: &str, end_tag: &str, ) -> impl Iterator<Item = &Field>
Sourcepub fn fields_with_subfields<'a>(
&'a self,
tag: &'a str,
codes: &'a [char],
) -> impl Iterator<Item = &'a Field> + 'a
pub fn fields_with_subfields<'a>( &'a self, tag: &'a str, codes: &'a [char], ) -> impl Iterator<Item = &'a Field> + 'a
Sourcepub fn fields_matching<'a>(
&'a self,
query: &'a FieldQuery,
) -> impl Iterator<Item = &'a Field> + 'a
pub fn fields_matching<'a>( &'a self, query: &'a FieldQuery, ) -> impl Iterator<Item = &'a Field> + 'a
Sourcepub fn fields_matching_range<'a>(
&'a self,
query: &'a TagRangeQuery,
) -> impl Iterator<Item = &'a Field> + 'a
pub fn fields_matching_range<'a>( &'a self, query: &'a TagRangeQuery, ) -> impl Iterator<Item = &'a Field> + 'a
Iterate over fields matching a tag range query.
§Examples
use mrrc::TagRangeQuery;
let query = TagRangeQuery {
start_tag: "600".to_string(),
end_tag: "699".to_string(),
indicator1: None,
indicator2: Some('0'),
required_subfields: vec!['a'],
};
for field in record.fields_matching_range(&query) {
println!("Subject: {:?}", field);
}Sourcepub fn fields_matching_pattern<'a>(
&'a self,
query: &'a SubfieldPatternQuery,
) -> impl Iterator<Item = &'a Field> + 'a
pub fn fields_matching_pattern<'a>( &'a self, query: &'a SubfieldPatternQuery, ) -> impl Iterator<Item = &'a Field> + 'a
Find all fields where a subfield value matches a regex pattern.
§Arguments
query- ASubfieldPatternQuerydefining tag, subfield code, and regex pattern
§Examples
use mrrc::field_query::SubfieldPatternQuery;
// Find all ISBNs starting with 978
let query = SubfieldPatternQuery::new("020", 'a', r"^978-.*")?;
for field in record.fields_matching_pattern(&query) {
println!("ISBN: {:?}", field);
}Sourcepub fn fields_matching_value<'a>(
&'a self,
query: &'a SubfieldValueQuery,
) -> impl Iterator<Item = &'a Field> + 'a
pub fn fields_matching_value<'a>( &'a self, query: &'a SubfieldValueQuery, ) -> impl Iterator<Item = &'a Field> + 'a
Find all fields where a subfield value matches a specific string.
§Arguments
query- ASubfieldValueQuerydefining tag, subfield code, and value to match
§Examples
use mrrc::field_query::SubfieldValueQuery;
// Find exact match
let query = SubfieldValueQuery::new("650", 'a', "History");
for field in record.fields_matching_value(&query) {
println!("Subject: {:?}", field);
}
// Find partial match
let query = SubfieldValueQuery::partial("650", 'a', "History");
for field in record.fields_matching_value(&query) {
println!("Subject: {:?}", field);
}Sourcepub fn get_linked_field(&self, field: &Field) -> Option<&Field>
pub fn get_linked_field(&self, field: &Field) -> Option<&Field>
Find the 880 field linked to a given original field.
In MARC records, 880 fields provide alternate graphical representations (e.g., romanized text paired with original script). The linkage is established via subfield 6 which contains an occurrence number.
§Arguments
field- The original field to find the linked 880 for
§Returns
The linked 880 field if found, or None if:
- Field has no subfield 6
- Subfield 6 is malformed
- No matching 880 field exists
§Examples
let field_100 = record.get_field("100").unwrap();
if let Some(field_880) = record.get_linked_field(field_100) {
println!("Original: {}", field_100.get_subfield('a').unwrap());
println!("Romanized: {}", field_880.get_subfield('a').unwrap());
}Sourcepub fn get_linked_fields(&self, field: &Field) -> Vec<&Field>
pub fn get_linked_fields(&self, field: &Field) -> Vec<&Field>
Find all 880 fields linked to a given original field (pymarc-compatible).
Like Self::get_linked_field but returns all matching 880 fields
rather than just the first. In practice MARC records typically have one
880 per occurrence, but the spec allows multiple.
Returns an empty Vec when the field has no subfield 6 or no matching
880 fields exist.
Sourcepub fn get_original_field(&self, field_880: &Field) -> Option<&Field>
pub fn get_original_field(&self, field_880: &Field) -> Option<&Field>
Find the original field linked from a given 880 field.
If an 880 field is provided, finds its linked original field.
This is the reverse of Self::get_linked_field.
§Arguments
field_880- An 880 field
§Returns
The linked original field if found, or None if:
- Field is not an 880
- 880 has no subfield 6
- Subfield 6 is malformed
- No matching original field exists
Sourcepub fn get_all_880_fields(&self) -> Vec<&Field>
pub fn get_all_880_fields(&self) -> Vec<&Field>
Sourcepub fn get_field_pairs(&self, tag: &str) -> Vec<(&Field, Option<&Field>)>
pub fn get_field_pairs(&self, tag: &str) -> Vec<(&Field, Option<&Field>)>
Get field pairs of original fields with their linked 880 counterparts.
For a given tag, returns tuples of (original_field, Option<linked_880>).
The Option will be None if the original field has no linked 880.
§Arguments
tag- The original field tag to pair with 880s
§Examples
for (orig, linked_880) in record.get_field_pairs("100") {
let name = orig.get_subfield('a').unwrap_or("unknown");
if let Some(field_880) = linked_880 {
let romanized = field_880.get_subfield('a').unwrap_or("unknown");
println!("Name: {} (romanized: {})", name, romanized);
} else {
println!("Name: {} (no alternate form)", name);
}
}Sourcepub fn find_linked_by_occurrence(&self, occurrence: &str) -> Vec<&Field>
pub fn find_linked_by_occurrence(&self, occurrence: &str) -> Vec<&Field>
Find all fields linked by a specific occurrence number.
§Arguments
occurrence- The occurrence number to search for (e.g., “01”)
§Returns
Vector of all fields (original and 880) with matching occurrence in subfield 6
§Examples
let fields = record.find_linked_by_occurrence("01");
// Returns both original field and its 880 counterpart, if both existSourcepub fn get_field_mut(&mut self, tag: &str) -> Option<&mut Field>
pub fn get_field_mut(&mut self, tag: &str) -> Option<&mut Field>
Get mutable reference to first field with a given tag
Sourcepub fn get_fields_mut(&mut self, tag: &str) -> Option<&mut [Field]>
pub fn get_fields_mut(&mut self, tag: &str) -> Option<&mut [Field]>
Get mutable slice of fields with a given tag
Sourcepub fn fields_mut(&mut self) -> impl Iterator<Item = &mut Field>
pub fn fields_mut(&mut self) -> impl Iterator<Item = &mut Field>
Iterate mutably over all fields
Sourcepub fn fields_by_tag_mut(
&mut self,
tag: &str,
) -> impl Iterator<Item = &mut Field>
pub fn fields_by_tag_mut( &mut self, tag: &str, ) -> impl Iterator<Item = &mut Field>
Sourcepub fn remove_fields_by_tag(&mut self, tag: &str) -> Vec<Field>
pub fn remove_fields_by_tag(&mut self, tag: &str) -> Vec<Field>
Sourcepub fn remove_fields_where<F>(&mut self, predicate: F) -> Vec<Field>
pub fn remove_fields_where<F>(&mut self, predicate: F) -> Vec<Field>
Sourcepub fn update_fields_where<F, G>(&mut self, predicate: F, operation: G)
pub fn update_fields_where<F, G>(&mut self, predicate: F, operation: G)
Sourcepub fn update_subfield_values(
&mut self,
tag: &str,
subfield_code: char,
new_value: &str,
)
pub fn update_subfield_values( &mut self, tag: &str, subfield_code: char, new_value: &str, )
Sourcepub fn update_subfields_where<F>(
&mut self,
field_pred: F,
subfield_code: char,
new_value: &str,
)
pub fn update_subfields_where<F>( &mut self, field_pred: F, subfield_code: char, new_value: &str, )
Sourcepub fn clear_fields(&mut self)
pub fn clear_fields(&mut self)
Remove all fields from the record
Sourcepub fn clear_control_fields(&mut self)
pub fn clear_control_fields(&mut self)
Clear all control fields from the record
Trait Implementations§
Source§impl BibliographicQueries for Record
impl BibliographicQueries for Record
Source§fn get_titles(&self) -> Vec<&Field>
fn get_titles(&self) -> Vec<&Field>
Source§fn get_topical_subjects(&self) -> Vec<&Field>
fn get_topical_subjects(&self) -> Vec<&Field>
Source§fn get_geographic_subjects(&self) -> Vec<&Field>
fn get_geographic_subjects(&self) -> Vec<&Field>
Source§fn get_all_names(&self) -> Vec<&Field>
fn get_all_names(&self) -> Vec<&Field>
Source§impl<'de> Deserialize<'de> for Record
impl<'de> Deserialize<'de> for Record
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>,
Source§impl FieldQueryHelpers for Record
impl FieldQueryHelpers for Record
Source§fn fields_matching_pattern(&self, query: &SubfieldPatternQuery) -> Vec<&Field>
fn fields_matching_pattern(&self, query: &SubfieldPatternQuery) -> Vec<&Field>
Source§fn fields_matching_value(&self, query: &SubfieldValueQuery) -> Vec<&Field>
fn fields_matching_value(&self, query: &SubfieldValueQuery) -> Vec<&Field>
Source§fn names_in_range(&self, start_tag: &str, end_tag: &str) -> Vec<&Field>
fn names_in_range(&self, start_tag: &str, end_tag: &str) -> Vec<&Field>
Source§fn subjects_with_subdivision(&self, code: char, value: &str) -> Vec<&Field>
fn subjects_with_subdivision(&self, code: char, value: &str) -> Vec<&Field>
Source§impl Index<&str> for Record
Enable dictionary-like access to Record fields using record["245"].
impl Index<&str> for Record
Enable dictionary-like access to Record fields using record["245"].
Source§impl MarcRecord for Record
impl MarcRecord for Record
Source§fn leader_mut(&mut self) -> &mut Leader
fn leader_mut(&mut self) -> &mut Leader
Source§fn add_control_field(
&mut self,
tag: impl Into<String>,
value: impl Into<String>,
)
fn add_control_field( &mut self, tag: impl Into<String>, value: impl Into<String>, )
Source§fn get_control_field(&self, tag: &str) -> Option<&str>
fn get_control_field(&self, tag: &str) -> Option<&str>
Source§fn control_fields_iter(&self) -> Box<dyn Iterator<Item = (&str, &str)> + '_>
fn control_fields_iter(&self) -> Box<dyn Iterator<Item = (&str, &str)> + '_>
Auto Trait Implementations§
impl Freeze for Record
impl RefUnwindSafe for Record
impl Send for Record
impl Sync for Record
impl Unpin for Record
impl UnsafeUnpin for Record
impl UnwindSafe for Record
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> 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