"""TranslationRequest value object for translation service requests.""" from dataclasses import dataclass from typing import Optional import re from .text_content import TextContent @dataclass(frozen=True) class TranslationRequest: """Value object representing a translation request with source and target languages.""" source_text: TextContent target_language: str source_language: Optional[str] = None def __post_init__(self): """Validate translation request after initialization.""" self._validate() def _validate(self): """Validate translation request properties.""" if not isinstance(self.source_text, TextContent): raise TypeError("Source text must be a TextContent instance") if not isinstance(self.target_language, str): raise TypeError("Target language must be a string") if not self.target_language.strip(): raise ValueError("Target language cannot be empty") # Validate target language code format (ISO 639-1 or ISO 639-3) if not re.match(r'^[a-z]{2,3}(-[A-Z]{2})?$', self.target_language): raise ValueError(f"Invalid target language code format: {self.target_language}. Expected format: 'en', 'en-US', etc.") if self.source_language is not None: if not isinstance(self.source_language, str): raise TypeError("Source language must be a string") if not self.source_language.strip(): raise ValueError("Source language cannot be empty string") # Validate source language code format if not re.match(r'^[a-z]{2,3}(-[A-Z]{2})?$', self.source_language): raise ValueError(f"Invalid source language code format: {self.source_language}. Expected format: 'en', 'en-US', etc.") # Check if source and target languages are the same if self.source_language == self.target_language: raise ValueError("Source and target languages cannot be the same") # If source language is not specified, use the language from TextContent if self.source_language is None and self.source_text.language == self.target_language: raise ValueError("Source and target languages cannot be the same") @property def effective_source_language(self) -> str: """Get the effective source language (from parameter or TextContent).""" return self.source_language if self.source_language is not None else self.source_text.language @property def is_auto_detect_source(self) -> bool: """Check if source language should be auto-detected.""" return self.source_language is None @property def text_length(self) -> int: """Get the length of source text.""" return len(self.source_text.text) @property def word_count(self) -> int: """Get the word count of source text.""" return self.source_text.word_count def with_target_language(self, target_language: str) -> 'TranslationRequest': """Create a new TranslationRequest with different target language.""" return TranslationRequest( source_text=self.source_text, target_language=target_language, source_language=self.source_language ) def with_source_language(self, source_language: Optional[str]) -> 'TranslationRequest': """Create a new TranslationRequest with different source language.""" return TranslationRequest( source_text=self.source_text, target_language=self.target_language, source_language=source_language )