bindings: what a closed subject scheme says about a heading

book-pipeline held its own copy of the scheme operations bibclean already
had. The scheme itself — which headings a collection uses, their aliases,
their parents — stays with the collection, because that is the most
collection-specific thing there is. What a scheme *means* is the same
question everywhere, and this answers it: `canonical_subject`,
`compose_subjects`, `needs_subject`.

Checked against the Python over the library's 228 distinct tags and all
5,385 books: identical on every one.
This commit is contained in:
funkpower
2026-09-20 15:15:48 -04:00
parent 7a08ed953d
commit b28e272506
5 changed files with 70 additions and 0 deletions
+24
View File
@@ -215,6 +215,30 @@ pub fn parse_identifier(text: &str) -> Option<idnorm::Identifier> {
idnorm::parse(text)
}
/// What a closed subject scheme says about a set of headings.
///
/// The scheme is supplied rather than built in — which subjects a collection
/// uses is the most collection-specific thing there is. These take it as the
/// record `bibclean` reads from a file.
pub fn canonical_subject(scheme: &bibclean::scheme::Scheme, name: &str) -> Option<String> {
scheme.canonical(name).map(str::to_string)
}
/// The subjects a book should carry: the chosen ones, their parents, and
/// nothing the title rules out.
pub fn compose_subjects(
scheme: &bibclean::scheme::Scheme,
subjects: &[String],
title: Option<&str>,
) -> Vec<String> {
scheme.compose(subjects, title)
}
/// Whether a book has no heading the scheme recognises.
pub fn needs_subject(scheme: &bibclean::scheme::Scheme, existing: &[String]) -> bool {
scheme.needs_subject(existing)
}
/// The best author a record's own title and front matter can offer.
///
/// `None` when neither says anything that reads as a person's name, which is