---
to: "src/models/{{name}}.rs"
vars:
  - name: string
  - email: string
  - role: string
rdf: |
  @prefix ex: <http://example.org/> .
  @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
  @prefix owl: <http://www.w3.org/2002/07/owl#> .
  
  ex:User a owl:Class ;
    rdfs:label "User" ;
    rdfs:comment "A user in the system" .
  
  ex:name a owl:DatatypeProperty ;
    rdfs:domain ex:User ;
    rdfs:range xsd:string ;
    rdfs:label "name" .
  
  ex:email a owl:DatatypeProperty ;
    rdfs:domain ex:User ;
    rdfs:range xsd:string ;
    rdfs:label "email" .
  
  ex:role a owl:DatatypeProperty ;
    rdfs:domain ex:User ;
    rdfs:range xsd:string ;
    rdfs:label "role" .
sparql: |
  SELECT ?name ?email ?role WHERE {
    ?user a ex:User ;
      ex:name ?name ;
      ex:email ?email ;
      ex:role ?role .
  }
determinism: true
---

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// User model generated from RDF ontology
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {{name | title}} {
    pub name: String,
    pub email: String,
    pub role: String,
    pub metadata: HashMap<String, String>,
}

impl {{name | title}} {
    /// Create a new user instance
    pub fn new(name: String, email: String, role: String) -> Self {
        Self {
            name,
            email,
            role,
            metadata: HashMap::new(),
        }
    }
    
    /// Validate user data
    pub fn validate(&self) -> Result<(), String> {
        if self.name.is_empty() {
            return Err("Name cannot be empty".to_string());
        }
        
        if !self.email.contains('@') {
            return Err("Invalid email format".to_string());
        }
        
        if self.role.is_empty() {
            return Err("Role cannot be empty".to_string());
        }
        
        Ok(())
    }
    
    /// Get user display name
    pub fn display_name(&self) -> String {
        format!("{} ({})", self.name, self.role)
    }
    
    /// Check if user has specific role
    pub fn has_role(&self, role: &str) -> bool {
        self.role == role
    }
    
    /// Add metadata
    pub fn add_metadata(&mut self, key: String, value: String) {
        self.metadata.insert(key, value);
    }
    
    /// Get metadata value
    pub fn get_metadata(&self, key: &str) -> Option<&String> {
        self.metadata.get(key)
    }
}

impl Default for {{name | title}} {
    fn default() -> Self {
        Self {
            name: "Anonymous".to_string(),
            email: "anonymous@example.com".to_string(),
            role: "user".to_string(),
            metadata: HashMap::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_user_creation() {
        let user = {{name | title}}::new(
            "John Doe".to_string(),
            "john@example.com".to_string(),
            "admin".to_string(),
        );
        
        assert_eq!(user.name, "John Doe");
        assert_eq!(user.email, "john@example.com");
        assert_eq!(user.role, "admin");
    }
    
    #[test]
    fn test_user_validation() {
        let valid_user = {{name | title}}::new(
            "Jane Doe".to_string(),
            "jane@example.com".to_string(),
            "user".to_string(),
        );
        assert!(valid_user.validate().is_ok());
        
        let invalid_user = {{name | title}}::new(
            "".to_string(),
            "invalid-email".to_string(),
            "".to_string(),
        );
        assert!(invalid_user.validate().is_err());
    }
    
    #[test]
    fn test_role_checking() {
        let admin = {{name | title}}::new(
            "Admin User".to_string(),
            "admin@example.com".to_string(),
            "admin".to_string(),
        );
        
        assert!(admin.has_role("admin"));
        assert!(!admin.has_role("user"));
    }
    
    #[test]
    fn test_metadata_operations() {
        let mut user = {{name | title}}::default();
        
        user.add_metadata("department".to_string(), "Engineering".to_string());
        assert_eq!(user.get_metadata("department"), Some(&"Engineering".to_string()));
        assert_eq!(user.get_metadata("nonexistent"), None);
    }
}

