A production-ready Rust library for manipulating metadata conforming to the DCMI (Dublin Core Metadata Initiative) Element Set and DCMI Terms standards.
- 📋 Standards Compliant: Full support for DCMI Element Set (15 core elements) and DCMI Terms (38+ extended terms)
- 🔒 Type-Safe: Validated data types for URIs, language tags (BCP 47), and date/time values
- 🔄 Multiple Formats: Serialize and deserialize metadata in XML, JSON, and JSON-LD
- ✨ Full CRUD API: Create, read, update, and delete metadata elements with ease
- ✅ Comprehensive Tests: 38+ tests covering all functionality
- 📝 Well Documented: Extensive documentation and examples
Add this to your Cargo.toml:
[dependencies]
appthere-dcmetadata = "0.1.0"use appthere_dcmetadata::{
MetadataCollection, Element, MetadataType, ElementName,
Language, Uri, DateTimeValue,
};
// Create a new metadata collection
let mut collection = MetadataCollection::new();
// Add a title
collection.add(
MetadataType::ElementSet(ElementName::Title),
Element::new("Rust Programming Guide"),
);
// Add a creator
collection.add(
MetadataType::ElementSet(ElementName::Creator),
Element::new("Jane Doe"),
);
// Add a description with language tag
let lang = Language::new("en").unwrap();
collection.add(
MetadataType::ElementSet(ElementName::Description),
Element::new("A comprehensive guide to Rust").with_language(lang),
);
// Add an identifier with URI
let uri = Uri::new("https://example.com/rust-guide").unwrap();
collection.add(
MetadataType::ElementSet(ElementName::Identifier),
Element::new(uri),
);
// Serialize to different formats
let xml = collection.to_xml().unwrap();
let json = collection.to_json().unwrap();
let jsonld = collection.to_jsonld().unwrap();
// Deserialize from formats
let from_xml = MetadataCollection::from_xml(&xml).unwrap();
let from_json = MetadataCollection::from_json(&json).unwrap();
let from_jsonld = MetadataCollection::from_jsonld(&jsonld).unwrap();title- Name given to the resourcecreator- Entity primarily responsible for making the resourcesubject- Topic of the resourcedescription- Account of the resourcepublisher- Entity responsible for making the resource availablecontributor- Entity responsible for making contributionsdate- Point or period of time associated with the resourcetype- Nature or genre of the resourceformat- File format or physical mediumidentifier- Unambiguous reference to the resourcesource- Related resource from which it is derivedlanguage- Language of the resourcerelation- Related resourcecoverage- Spatial or temporal topicrights- Information about rights held in and over the resource
Includes additional terms like abstract, accessRights, created, modified, license, bibliographicCitation, and many more. See elements.rs:39 for the complete list.
use appthere_dcmetadata::{MetadataCollection, Element, MetadataType, ElementName};
let mut collection = MetadataCollection::new();
// Create
let id = collection.add(
MetadataType::ElementSet(ElementName::Title),
Element::new("Original Title"),
);
// Read
let (element_type, element) = collection.get_by_id(id).unwrap();
println!("Title: {}", element.value.as_text().unwrap());
// Update
collection.update(id, Element::new("Updated Title")).unwrap();
// Delete
let deleted = collection.delete(id).unwrap();All data types are validated at construction time:
use appthere_dcmetadata::{Language, Uri, DateTimeValue};
// Valid language tags (BCP 47)
let en = Language::new("en").unwrap();
let en_us = Language::new("en-US").unwrap();
assert!(Language::new("invalid_tag").is_err());
// Valid URIs
let uri = Uri::new("https://example.com").unwrap();
assert!(Uri::new("not a uri").is_err());
// Valid date/time values
let date = DateTimeValue::parse("2024-01-15").unwrap();
let datetime = DateTimeValue::parse("2024-01-15T10:30:00Z").unwrap();
assert!(DateTimeValue::parse("invalid").is_err());<?xml version="1.0" encoding="UTF-8"?>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace">
<dc:title xml:lang="en">Rust Programming Guide</dc:title>
<dc:creator>Jane Doe</dc:creator>
<dc:identifier>https://example.com/rust-guide</dc:identifier>
</metadata>{
"dc:title": [
{
"value": "Rust Programming Guide",
"lang": "en"
}
],
"dc:creator": [
{
"value": "Jane Doe"
}
]
}{
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
"dcterms": "http://purl.org/dc/terms/"
},
"dc:title": {
"@value": "Rust Programming Guide",
"@language": "en"
},
"dc:creator": {
"@value": "Jane Doe"
},
"dc:identifier": {
"@id": "https://example.com/rust-guide"
}
}let lang = Language::new("en-GB").unwrap();
let element = Element::new("Colour").with_language(lang);let element = Element::new("978-0-13-110362-7").with_scheme("ISBN");let results = collection.find_by_text("Rust");
for (id, element_type, element) in results {
println!("Found: {}", element.value.as_text().unwrap());
}collection.add(
MetadataType::ElementSet(ElementName::Creator),
Element::new("Jane Doe"),
);
collection.add(
MetadataType::ElementSet(ElementName::Creator),
Element::new("John Smith"),
);
let creators = collection.get(&MetadataType::ElementSet(ElementName::Creator));
assert_eq!(creators.len(), 2);# Build the library
cargo build
# Run all tests
cargo test
# Run with optimizations
cargo build --release
# Check for linting issues
cargo clippy
# Format code
cargo fmtThis project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit issues or pull requests.