Skip to main content

Record

Struct Record 

Source
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: Leader

Record 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

Source

pub fn new(leader: Leader) -> Self

Create a new MARC record with the given leader

Source

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();
Source

pub fn add_control_field(&mut self, tag: String, value: String)

Add a control field (000-009)

Source

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.

Source

pub fn get_control_field(&self, tag: &str) -> Option<&str>

Get a control field value

Source

pub fn add_field(&mut self, field: Field)

Add a data field

Source

pub fn get_fields(&self, tag: &str) -> Option<&[Field]>

Get all fields with a given tag

Source

pub fn get_field(&self, tag: &str) -> Option<&Field>

Get first field with a given tag

Source

pub fn fields(&self) -> impl Iterator<Item = &Field>

Iterate over all fields in tag order

Source

pub fn fields_by_tag(&self, tag: &str) -> impl Iterator<Item = &Field>

Iterate over fields matching a specific tag

Returns an iterator over all fields with the given tag.

§Examples
for field in record.fields_by_tag("650") {
    if let Some(subject) = field.get_subfield('a') {
        println!("Subject: {}", subject);
    }
}
Source

pub fn control_fields_iter(&self) -> impl Iterator<Item = (&str, &str)>

Iterate over all control fields

Returns an iterator of (tag, value) tuples.

Source

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 search
  • indicator1 - First indicator value, or None to match any
  • indicator2 - Second indicator value, or None to 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);
}
Source

pub fn fields_in_range( &self, start_tag: &str, end_tag: &str, ) -> impl Iterator<Item = &Field>

Iterate over fields within a tag range (inclusive).

§Arguments
  • start_tag - Start of range (inclusive)
  • end_tag - End of range (inclusive)
§Examples
// Find all subject-related fields (600-699)
for field in record.fields_in_range("600", "699") {
    println!("Subject field: {}", field.tag);
}
Source

pub fn fields_with_subfield( &self, tag: &str, code: char, ) -> impl Iterator<Item = &Field>

Iterate over fields that have a specific subfield code.

§Examples
// Find all fields with subfield 'a'
for field in record.fields_with_subfield("650", 'a') {
    println!("Field: {}", field.tag);
}
Source

pub fn fields_with_subfields<'a>( &'a self, tag: &'a str, codes: &'a [char], ) -> impl Iterator<Item = &'a Field> + 'a

Iterate over fields that have all of the specified subfield codes.

§Examples
// Find all 650 fields with both 'a' and 'x' subfields
for field in record.fields_with_subfields("650", &['a', 'x']) {
    println!("Subject: {:?}", field);
}
Source

pub fn fields_matching<'a>( &'a self, query: &'a FieldQuery, ) -> impl Iterator<Item = &'a Field> + 'a

Iterate over fields matching a query.

§Examples
use mrrc::FieldQuery;

let query = FieldQuery::new()
    .tag("650")
    .indicator2(Some('0'))
    .has_subfield('a');

for field in record.fields_matching(&query) {
    println!("LCSH: {:?}", field);
}
Source

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);
}
Source

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 - A SubfieldPatternQuery defining 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);
}
Source

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 - A SubfieldValueQuery defining 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);
}
Source

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());
}
Source

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.

Source

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
Source

pub fn get_all_880_fields(&self) -> Vec<&Field>

Get all 880 fields (alternate graphical representations).

§Examples
for field_880 in record.get_all_880_fields() {
    println!("880 field: {:?}", field_880);
}
Source

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);
    }
}
Source

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 exist
Source

pub fn get_field_mut(&mut self, tag: &str) -> Option<&mut Field>

Get mutable reference to first field with a given tag

Source

pub fn get_fields_mut(&mut self, tag: &str) -> Option<&mut [Field]>

Get mutable slice of fields with a given tag

Source

pub fn fields_mut(&mut self) -> impl Iterator<Item = &mut Field>

Iterate mutably over all fields

Source

pub fn fields_by_tag_mut( &mut self, tag: &str, ) -> impl Iterator<Item = &mut Field>

Iterate mutably over fields matching a specific tag

§Examples
for field in record.fields_by_tag_mut("650") {
    field.indicator2 = '0';
}
Source

pub fn remove_fields_by_tag(&mut self, tag: &str) -> Vec<Field>

Remove all fields with a given tag

Returns the removed fields.

§Examples
let removed = record.remove_fields_by_tag("852");  // Remove holdings
Source

pub fn remove_fields_where<F>(&mut self, predicate: F) -> Vec<Field>
where F: Fn(&Field) -> bool,

Remove fields matching a predicate

Returns the removed fields.

§Examples
let removed = record.remove_fields_where(|field| field.tag == "852");
Source

pub fn update_fields_where<F, G>(&mut self, predicate: F, operation: G)
where F: Fn(&Field) -> bool, G: FnMut(&mut Field),

Update fields matching a predicate

Applies the given operation to each matching field.

§Examples
record.update_fields_where(
    |field| field.tag == "245",
    |field| field.indicator2 = '0'
);
Source

pub fn update_subfield_values( &mut self, tag: &str, subfield_code: char, new_value: &str, )

Update all subfield values in fields with a given tag

§Examples
// Update all authority codes in 650 fields
record.update_subfield_values("650", 'd', "updated-value");
Source

pub fn update_subfields_where<F>( &mut self, field_pred: F, subfield_code: char, new_value: &str, )
where F: Fn(&Field) -> bool,

Update subfield values in fields matching a predicate

§Examples
record.update_subfields_where(
    |field| field.tag == "650",
    |subfield| subfield.code == 'd',
    "updated-value"
);
Source

pub fn clear_fields(&mut self)

Remove all fields from the record

Source

pub fn clear_control_fields(&mut self)

Clear all control fields from the record

Trait Implementations§

Source§

impl BibliographicQueries for Record

Source§

fn get_titles(&self) -> Vec<&Field>

Get all main titles and their statement of responsibility (245 fields). Read more
Source§

fn get_all_subjects(&self) -> Vec<&Field>

Get all subject fields (6XX range). Read more
Source§

fn get_topical_subjects(&self) -> Vec<&Field>

Get all topical subjects (650 fields). Read more
Source§

fn get_geographic_subjects(&self) -> Vec<&Field>

Get all geographic subjects (651 fields). Read more
Source§

fn get_all_names(&self) -> Vec<&Field>

Get all name fields (1XX, 6XX name fields, 7XX). Read more
Source§

fn get_linked_field_pairs(&self, tag: &str) -> Vec<(&Field, Option<&Field>)>

Get linked field pairs (original field with optional 880 counterpart). Read more
Source§

fn get_all_880_fields(&self) -> Vec<&Field>

Get all 880 fields (alternate graphical representations). Read more
Source§

impl Clone for Record

Source§

fn clone(&self) -> Record

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Record

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Record

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl FieldQueryHelpers for Record

Source§

fn fields_matching_pattern(&self, query: &SubfieldPatternQuery) -> Vec<&Field>

Get all fields matching a subfield pattern query.
Source§

fn fields_matching_value(&self, query: &SubfieldValueQuery) -> Vec<&Field>

Get all fields matching a subfield value query.
Source§

fn names_in_range(&self, start_tag: &str, end_tag: &str) -> Vec<&Field>

Find all name fields within a tag range. Read more
Source§

fn authors_with_dates(&self) -> Vec<(&str, &str)>

Find all authors and extract their birth/death dates from field 100/700 subfield ‘d’. Read more
Source§

fn subjects_with_subdivision(&self, code: char, value: &str) -> Vec<&Field>

Find all subject headings with a specific subdivision subfield and value. Read more
Source§

fn isbns_matching(&self, pattern: &str) -> Result<Vec<&Field>, Error>

Find all ISBNs matching a regex pattern. Read more
Source§

fn subjects_with_note(&self, subdivision: &str) -> Vec<&Field>

Find all subjects with a particular note in subfield ‘x’ (general subdivision). Read more
Source§

impl Index<&str> for Record

Enable dictionary-like access to Record fields using record["245"].

Returns the first field with the given tag, or panics if not found. For fallible access, use Record::get_field() instead.

§Examples

let field = &record["245"];
Source§

type Output = Field

The returned type after indexing.
Source§

fn index(&self, tag: &str) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl MarcRecord for Record

Source§

fn leader(&self) -> &Leader

Get a reference to the record’s leader (24-byte header).
Source§

fn leader_mut(&mut self) -> &mut Leader

Get a mutable reference to the record’s leader.
Source§

fn add_control_field( &mut self, tag: impl Into<String>, value: impl Into<String>, )

Add or replace a control field (000-009). Read more
Source§

fn get_control_field(&self, tag: &str) -> Option<&str>

Get the value of a control field. Read more
Source§

fn control_fields_iter(&self) -> Box<dyn Iterator<Item = (&str, &str)> + '_>

Iterate over all control fields. Read more
Source§

fn get_fields(&self, tag: &str) -> Option<&[Field]>

Get all fields with a given tag. Read more
Source§

fn get_field(&self, tag: &str) -> Option<&Field>

Get the first field with a given tag. Read more
Source§

impl Serialize for Record

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> RecordHelpers for T
where T: MarcRecord + ?Sized,

Source§

fn title(&self) -> Option<&str>

Get the main title from field 245, subfield ‘a’ Read more
Source§

fn title_with_responsibility(&self) -> (Option<&str>, Option<&str>)

Get the title and statement of responsibility from field 245 Read more
Source§

fn author(&self) -> Option<&str>

Get the primary author from field 100 (personal name), subfield ‘a’ Read more
Source§

fn authors(&self) -> Vec<&str>

Get all authors from field 700 (added entry for personal name), subfield ‘a’ Read more
Source§

fn corporate_author(&self) -> Option<&str>

Get the corporate body (publisher or organization) from field 110, subfield ‘a’
Source§

fn publisher(&self) -> Option<&str>

Get the publisher from field 260 or 264 (RDA), subfield ‘b’ Read more
Source§

fn publication_date(&self) -> Option<&str>

Get the publication date from field 260 or 264 (RDA), subfield ‘c’ Read more
Source§

fn isbn(&self) -> Option<&str>

Get the ISBN from field 020, subfield ‘a’ Read more
Source§

fn isbns(&self) -> Vec<&str>

Get all ISBNs from field 020, subfield ‘a’
Source§

fn issn(&self) -> Option<&str>

Get the ISSN from field 022, subfield ‘a’
Source§

fn subjects(&self) -> Vec<&str>

Get all subject headings from 6XX fields, subfield ‘a’ Read more
Source§

fn language(&self) -> Option<&str>

Get the language code from field 008 (positions 35-37) Read more
Source§

fn control_number(&self) -> Option<&str>

Get the control number (system number) from field 001
Source§

fn lccn(&self) -> Option<&str>

Get the Library of Congress Control Number (LCCN) from field 010, subfield ‘a’
Source§

fn physical_description(&self) -> Option<&str>

Get the physical description from field 300, subfield ‘a’ Read more
Source§

fn series(&self) -> Option<&str>

Get the series statement from field 490, subfield ‘a’
Source§

fn is_book(&self) -> bool

Check if this is a book (leader type ‘a’ for language material and bib level ‘m’ for monograph)
Source§

fn is_serial(&self) -> bool

Check if this is a serial (bib level ‘s’)
Source§

fn is_music(&self) -> bool

Check if this is music (leader type ‘c’ or ‘d’)
Source§

fn is_audiovisual(&self) -> bool

Check if this is audiovisual material (leader type ‘g’)
Source§

fn publication_info(&self) -> Option<PublicationInfo>

Extract publication information from field 260 or 264 (RDA) Read more
Source§

fn publication_year(&self) -> Option<u32>

Get the publication year extracted from field 260$c or field 008 Read more
Source§

fn place_of_publication(&self) -> Option<&str>

Get the place of publication from field 260 or 264 (RDA), subfield ‘a’ Read more
Source§

fn location(&self) -> Vec<&str>

Get all location fields (field 852) Read more
Source§

fn notes(&self) -> Vec<&str>

Get all note fields (all 5xx fields) Read more
Source§

fn uniform_title(&self) -> Option<&str>

Get the uniform title from field 130, subfield ‘a’ Read more
Source§

fn sudoc(&self) -> Option<&str>

Get the government document classification from field 086, subfield ‘a’ Read more
Source§

fn issn_title(&self) -> Option<&str>

Get the key title (ISSN title) from field 222 Read more
Source§

fn issnl(&self) -> Option<&str>

Get the ISSN-L (ISSN Linking number) from field 024, subfield ‘a’ Read more
Source§

fn pubyear(&self) -> Option<u32>

Alias for publication_year() for pymarc compatibility Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,