/// String Extension Methods - Plan 025 OOP Migration
///
/// This file extends the str type with utility methods using the ext statement.
/// These methods provide a more object-oriented API compared to the functional API.

ext str {
    // ============================================================================
    // Basic String Operations
    // ============================================================================

    /// Get the length of the string
    /// Example: "hello".len()  // returns 5
    #[vm]
    fn len() int

    /// Check if string is empty
    /// Example: "".is_empty()  // returns true
    #[vm]
    fn is_empty() bool

    /// Check if the string is exactly one ASCII digit character (0-9).
    /// Multi-char or non-digit strings yield false.
    /// Example: "7".is_digit()  // returns true; "12".is_digit() // false
    #[vm]
    fn is_digit() bool

    /// Convert string to uppercase
    /// Example: "hello".upper()  // returns "HELLO"
    #[vm]
    fn upper() str

    /// Convert string to lowercase
    /// Example: "HELLO".lower()  // returns "hello"
    #[vm]
    fn lower() str

    /// Get a substring by [start, end) character range (end exclusive).
    /// str-parity: `.sub`/`.slice` are END-semantics (a2r s[a..b]); `.substr`
    /// is (start, LEN) — three distinct methods, do not mix (Plan 583 T6
    /// 文档对齐:引擎/语料/a2r 三方一直为 END 语义,旧注记 (start,LEN) 为
    /// Plan 446 时代残文,与 native_catalog 的 auto.str.sub→1524(slice) 实现
    /// 不符)。
    /// Indices clamp to char boundaries; out-of-range yields "".
    /// Example: "hello".sub(1, 3)  // returns "el" (chars 1..2)
    #[vm]
    fn sub(start int, end int) str

    // ============================================================================
    // Search Methods
    // ============================================================================

    /// Check if string contains a pattern
    /// Example: "hello world".contains("world")  // returns true
    #[vm]
    fn contains(pattern str) bool

    /// Check if string starts with a prefix
    /// Example: "hello".starts_with("he")  // returns true
    #[vm]
    fn starts_with(prefix str) bool

    /// Check if string ends with a suffix
    /// Example: "hello".ends_with("lo")  // returns true
    #[vm]
    fn ends_with(suffix str) bool

    /// Find the index of a pattern (returns -1 if not found)
    /// Example: "hello world".find("world")  // returns 6
    #[vm]
    fn find(pattern str) int

    // ============================================================================
    // Transform Methods
    // ============================================================================

    /// Trim whitespace from both ends
    /// Example: "  hello  ".trim()  // returns "hello"
    #[vm]
    fn trim() str

    /// Replace all occurrences of a pattern
    /// Example: "hello world".replace("world", "rust")  // returns "hello rust"
    #[vm]
    fn replace(from str, with str) str

    /// Reverse the string
    /// Example: "hello".reverse()  // returns "olleh"
    #[vm]
    fn reverse() str

    // ============================================================================
    // Utility Methods
    // ============================================================================

    /// Repeat the string n times
    /// Example: "ha".repeat(3)  // returns "hahaha"
    #[vm]
    fn repeat(n int) str

    /// Get the character at a specific index (returns single-char string)
    /// Example: "hello".char_at(1)  // returns "e"
    #[vm]
    fn char_at(index int) str

    /// Split string by delimiter into array of strings
    /// Example: "hello world".split(" ")  // returns ["hello", "world"]
    #[vm]
    fn split(delimiter str) []str

    /// Split string into lines (split by newline)
    /// Example: "hello\nworld".lines()  // returns ["hello", "world"]
    #[vm]
    fn lines() []str

    /// Generate a UUID string
    /// Example: str.uuid()  // returns "a1b2c3d4-e5f6-4789-abcd-1234567890ab"
    #[vm]
    fn uuid() str

    /// Convert unsigned integer to string
    /// Example: str.from_uint(42)  // returns "42"
    #[vm]
    fn from_uint(n i64) str

    /// Parse string as unsigned integer
    /// Example: str.to_uint("42")  // returns 42
    #[vm]
    fn to_uint(s str) i64
}