tag_set Class

namespace keychainclass tag_set

Overview

The tag_set class provides a key-value metadata storage system for associating custom attributes and information with Keychain objects and operations.

Class Hierarchy

namespace keychain {
    class tag_set : public serializable {
        // Key-value metadata storage
    };
}

Constructor

tag_set();
tag_set(const tag_set& other);
tag_set(std::initializer_list<std::pair<std::string, std::string>> init);

Properties

Size and Capacity

size_t size() const;
bool empty() const;
size_t max_size() const;
void clear();

Basic container properties and management.

Iteration

iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;

Standard iterator support for range-based operations.

Methods

Tag Management

void set_tag(const std::string& key, const std::string& value);
std::string get_tag(const std::string& key) const;
std::string get_tag(const std::string& key, const std::string& default_value) const;

bool has_tag(const std::string& key) const;
bool remove_tag(const std::string& key);

Core tag manipulation operations.

Bulk Operations

void set_tags(const std::map<std::string, std::string>& tags);
void set_tags(const tag_set& other);
std::map<std::string, std::string> get_all_tags() const;

void merge(const tag_set& other, bool overwrite = false);
tag_set filter(const std::vector<std::string>& keys) const;

Operations for working with multiple tags simultaneously.

Query Operations

std::vector<std::string> get_keys() const;
std::vector<std::string> get_values() const;
std::vector<std::pair<std::string, std::string>> get_pairs() const;

std::vector<std::string> find_keys_with_prefix(const std::string& prefix) const;
std::vector<std::string> find_keys_with_value(const std::string& value) const;

Search and retrieval operations.

Validation

bool is_valid() const;
std::vector<std::string> get_validation_errors() const;

static bool is_valid_key(const std::string& key);
static bool is_valid_value(const std::string& value);

Tag validation and constraint checking.

Serialization

std::string to_json() const;
std::string to_xml() const;
std::vector<uint8_t> to_protobuf() const;

static tag_set from_json(const std::string& json);
static tag_set from_xml(const std::string& xml);
static tag_set from_protobuf(const std::vector<uint8_t>& data);

Usage Examples

Basic Tag Operations

#include <keychain/keychain.h>

// Create and populate tag set
keychain::tag_set metadata;
metadata.set_tag("author", "alice");
metadata.set_tag("version", "1.0");
metadata.set_tag("classification", "confidential");
metadata.set_tag("department", "finance");

// Check for tags
if (metadata.has_tag("classification")) {
    std::string level = metadata.get_tag("classification");
    std::cout << "Classification: " << level << std::endl;
}

// Get tag with default value
std::string priority = metadata.get_tag("priority", "normal");
std::cout << "Priority: " << priority << std::endl;

// Iterate through all tags
for (const auto& [key, value] : metadata.get_pairs()) {
    std::cout << key << ": " << value << std::endl;
}

Initialization and Bulk Operations

// Initialize with values
keychain::tag_set document_tags{
    {"title", "Quarterly Report"},
    {"quarter", "Q4 2024"},
    {"status", "draft"},
    {"reviewer", "bob.smith"}
};

// Bulk tag setting
std::map<std::string, std::string> additional_tags = {
    {"approval_date", "2024-01-15"},
    {"retention_years", "7"},
    {"encryption_required", "true"}
};
document_tags.set_tags(additional_tags);

// Merge tag sets
keychain::tag_set compliance_tags{
    {"regulation", "SOX"},
    {"retention_years", "10"},  // Will overwrite previous value
    {"audit_trail", "required"}
};
document_tags.merge(compliance_tags, true);  // Allow overwrite

std::cout << "Total tags: " << document_tags.size() << std::endl;

Search and Filtering

// Search operations
keychain::tag_set system_metadata{
    {"sys.created_by", "application"},
    {"sys.created_at", "2024-01-15T10:30:00Z"},
    {"sys.modified_by", "user123"},
    {"sys.version", "3.0"},
    {"user.department", "engineering"},
    {"user.project", "keychain-core"}
};

// Find system tags
auto system_keys = system_metadata.find_keys_with_prefix("sys.");
for (const auto& key : system_keys) {
    std::cout << "System tag: " << key << " = "
             << system_metadata.get_tag(key) << std::endl;
}

// Filter to user tags only
auto user_keys = system_metadata.find_keys_with_prefix("user.");
keychain::tag_set user_tags = system_metadata.filter(user_keys);

// Find all tags with specific value
auto version_keys = system_metadata.find_keys_with_value("3.0");
for (const auto& key : version_keys) {
    std::cout << "Version 3.0 tag: " << key << std::endl;
}

Validation and Constraints

// Tag validation
bool validate_metadata_tags(const keychain::tag_set& tags) {
    // Check required tags
    std::vector<std::string> required_tags = {
        "author", "created_date", "classification"
    };

    for (const auto& required : required_tags) {
        if (!tags.has_tag(required)) {
            std::cerr << "Missing required tag: " << required << std::endl;
            return false;
        }
    }

    // Validate classification levels
    std::string classification = tags.get_tag("classification");
    std::vector<std::string> valid_levels = {
        "public", "internal", "confidential", "secret"
    };

    if (std::find(valid_levels.begin(), valid_levels.end(), classification) == valid_levels.end()) {
        std::cerr << "Invalid classification level: " << classification << std::endl;
        return false;
    }

    // Check tag format validity
    if (!tags.is_valid()) {
        auto errors = tags.get_validation_errors();
        for (const auto& error : errors) {
            std::cerr << "Validation error: " << error << std::endl;
        }
        return false;
    }

    return true;
}

// Custom validation rules
bool validate_tag_constraints(const std::string& key, const std::string& value) {
    // Key constraints
    if (key.length() > 64) return false;
    if (key.find(' ') != std::string::npos) return false;  // No spaces in keys

    // Value constraints
    if (value.length() > 256) return false;

    // Special validations
    if (key == "email" && value.find('@') == std::string::npos) return false;
    if (key == "date" && !is_valid_iso8601_date(value)) return false;

    return true;
}

Integration with Keychain Objects

// Use tags with different Keychain objects
void demonstrate_tag_integration() {
    keychain::tag_set common_tags{
        {"project", "secure-messaging"},
        {"environment", "production"},
        {"owner", "alice.smith"}
    };

    // Tags with personas
    keychain::persona alice = gateway.create_persona("alice", "messaging",
                                                   keychain::security_level::HIGH);
    alice.set_metadata(common_tags);

    // Tags with verifiable data
    keychain::verifiable_data signed_document = gateway.sign(alice, "Contract v1.0");
    keychain::tag_set doc_tags = common_tags;
    doc_tags.set_tag("document_type", "contract");
    doc_tags.set_tag("version", "1.0");
    signed_document.set_metadata(doc_tags);

    // Tags with credentials
    keychain::credential identity_credential = gateway.create_credential(alice, credential_data);
    keychain::tag_set cred_tags = common_tags;
    cred_tags.set_tag("credential_type", "identity");
    cred_tags.set_tag("validity_period", "1_year");
    identity_credential.set_metadata(cred_tags);

    // Query objects by tags
    auto project_objects = gateway.find_objects_by_tag("project", "secure-messaging");
    std::cout << "Found " << project_objects.size() << " objects for project" << std::endl;
}

Serialization and Persistence

// Serialize tag sets for storage
void persist_metadata(const keychain::tag_set& tags, const std::string& filename) {
    // JSON format for human readability
    std::string json_data = tags.to_json();

    std::ofstream file(filename);
    file << json_data;
    file.close();

    std::cout << "Metadata saved to " << filename << std::endl;
}

// Load and deserialize tag sets
keychain::tag_set load_metadata(const std::string& filename) {
    std::ifstream file(filename);
    std::string json_data((std::istreambuf_iterator<char>(file)),
                         std::istreambuf_iterator<char>());
    file.close();

    return keychain::tag_set::from_json(json_data);
}

// Binary serialization for performance
std::vector<uint8_t> serialize_for_network(const keychain::tag_set& tags) {
    // Use Protocol Buffers for efficient network transmission
    return tags.to_protobuf();
}

JSON Structure

{
  "tags": {
    "author": "alice.smith",
    "classification": "confidential",
    "department": "finance",
    "created_date": "2024-01-15T10:30:00Z",
    "version": "1.0",
    "project": "quarterly-report"
  },
  "metadata": {
    "tag_count": 6,
    "created": "2024-01-15T10:30:00Z",
    "format_version": "3.0"
  }
}

Best Practices

Tag Key Conventions

// Recommended tag key patterns
namespace tag_conventions {
    // System tags (prefix with sys.)
    const std::string CREATED_BY = "sys.created_by";
    const std::string CREATED_AT = "sys.created_at";
    const std::string VERSION = "sys.version";

    // User tags (prefix with user.)
    const std::string USER_DEPARTMENT = "user.department";
    const std::string USER_PROJECT = "user.project";

    // Application tags (prefix with app.)
    const std::string APP_COMPONENT = "app.component";
    const std::string APP_BUILD = "app.build";

    // Security tags (prefix with sec.)
    const std::string CLASSIFICATION = "sec.classification";
    const std::string RETENTION = "sec.retention_years";
}

Performance Considerations

  • Keep tag keys and values reasonably short

  • Use consistent naming conventions

  • Avoid excessive tag counts (>100 tags per object)

  • Index frequently queried tags

  • Consider caching for read-heavy workloads

See Also

  • gateway - Metadata operations

  • serialization_format - Serialization options

  • {metadata-best-practices}[Metadata Management Best Practices]

  • {json-spec}[JSON Specification]