Skip to content

AppThere/appthere-dcmetadata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

appthere-dcmetadata

A production-ready Rust library for manipulating metadata conforming to the DCMI (Dublin Core Metadata Initiative) Element Set and DCMI Terms standards.

Features

  • 📋 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

Installation

Add this to your Cargo.toml:

[dependencies]
appthere-dcmetadata = "0.1.0"

Quick Start

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

Supported Elements

DCMI Element Set (15 Core Elements)

  • title - Name given to the resource
  • creator - Entity primarily responsible for making the resource
  • subject - Topic of the resource
  • description - Account of the resource
  • publisher - Entity responsible for making the resource available
  • contributor - Entity responsible for making contributions
  • date - Point or period of time associated with the resource
  • type - Nature or genre of the resource
  • format - File format or physical medium
  • identifier - Unambiguous reference to the resource
  • source - Related resource from which it is derived
  • language - Language of the resource
  • relation - Related resource
  • coverage - Spatial or temporal topic
  • rights - Information about rights held in and over the resource

DCMI Terms (Extended Vocabulary)

Includes additional terms like abstract, accessRights, created, modified, license, bibliographicCitation, and many more. See elements.rs:39 for the complete list.

CRUD Operations

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

Validation

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

Serialization Formats

XML Example

<?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>

JSON Example

{
  "dc:title": [
    {
      "value": "Rust Programming Guide",
      "lang": "en"
    }
  ],
  "dc:creator": [
    {
      "value": "Jane Doe"
    }
  ]
}

JSON-LD Example

{
  "@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"
  }
}

Advanced Features

Language Qualifiers

let lang = Language::new("en-GB").unwrap();
let element = Element::new("Colour").with_language(lang);

Scheme Qualifiers

let element = Element::new("978-0-13-110362-7").with_scheme("ISBN");

Text Search

let results = collection.find_by_text("Rust");
for (id, element_type, element) in results {
    println!("Found: {}", element.value.as_text().unwrap());
}

Multiple Values per Element Type

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

Building and Testing

# 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 fmt

License

This project is licensed under the MIT License - see the LICENSE file for details.

References

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

About

A production-ready Rust library for manipulating DCMI (Dublin Core) metadata with support for XML, JSON, and JSON-LD serialization

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages