<!-- CANARY: REQ=REQ-GQL-UNICODE-012; FEATURE="UTF-8 -> UTF-16 Conversion"; ASPECT=ClientTestZig; STATUS=TESTED; OWNER=clients; UPDATED=2025-09-27 --> <h3 id="overview" class="position-relative d-flex align-items-center group"> <span>Overview</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="overview" aria-haspopup="dialog" aria-label="Share link: Overview"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Geode provides comprehensive Unicode support for international text processing with NFC normalization, case folding, UTF encoding conversions, and robust error handling. The implementation focuses on correctness, performance, and practical use cases for graph database operations.</p> <h4 id="features" class="position-relative d-flex align-items-center group"> <span>Features</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="features" aria-haspopup="dialog" aria-label="Share link: Features"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Core Capabilities</strong>:</p> <ul> <li><strong>NFC Normalization</strong>: Canonical composition for consistent text representation</li> <li><strong>Case Folding</strong>: Locale-independent case-insensitive comparisons</li> <li><strong>UTF-8 ↔ UTF-16</strong>: Bidirectional encoding conversion</li> <li><strong>WTF-8 Lossy Decoding</strong>: Graceful handling of ill-formed UTF-8 sequences</li> <li><strong>Full-Text Search Integration</strong>: Normalized text indexing and search</li> <li><strong>Constraint Normalization</strong>: Consistent unique key enforcement</li> </ul> <h3 id="unicode-fundamentals" class="position-relative d-flex align-items-center group"> <span>Unicode Fundamentals</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="unicode-fundamentals" aria-haspopup="dialog" aria-label="Share link: Unicode Fundamentals"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="what-is-unicode" class="position-relative d-flex align-items-center group"> <span>What is Unicode?</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="what-is-unicode" aria-haspopup="dialog" aria-label="Share link: What is Unicode?"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Unicode</strong> is a universal character encoding standard that provides a unique number (code point) for every character across all writing systems, modern and historic.</p> <p><strong>Key Concepts</strong>:</p> <ul> <li><strong>Code Point</strong>: Numeric value representing a character (U+0041 = &lsquo;A&rsquo;)</li> <li><strong>UTF-8</strong>: Variable-length encoding (1-4 bytes per character)</li> <li><strong>UTF-16</strong>: Variable-length encoding (2 or 4 bytes per character)</li> <li><strong>Normalization</strong>: Converting text to canonical form</li> <li><strong>Case Folding</strong>: Locale-independent case conversion for comparison</li> </ul> <h4 id="why-normalization-matters" class="position-relative d-flex align-items-center group"> <span>Why Normalization Matters</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="why-normalization-matters" aria-haspopup="dialog" aria-label="Share link: Why Normalization Matters"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Problem</strong>: Multiple representations of &ldquo;same&rdquo; text</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-plaintext" data-lang="plaintext"><span class="line"><span class="cl">&#34;café&#34; can be encoded as: </span></span><span class="line"><span class="cl"> 1. U+0063 U+0061 U+0066 U+00E9 (precomposed é) </span></span><span class="line"><span class="cl"> 2. U+0063 U+0061 U+0066 U+0065 U+0301 (e + combining acute) </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Without normalization: These don&#39;t match in string comparison! </span></span><span class="line"><span class="cl">With NFC normalization: Both become the same canonical form </span></span></code></pre></div><p><strong>Impact on Graph Databases</strong>:</p> <ul> <li>Unique constraints may fail incorrectly</li> <li>Full-text search misses matches</li> <li>Case-insensitive comparisons fail</li> <li>Index lookups miss data</li> </ul> <h3 id="nfc-normalization" class="position-relative d-flex align-items-center group"> <span>NFC Normalization</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="nfc-normalization" aria-haspopup="dialog" aria-label="Share link: NFC Normalization"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="overview-1" class="position-relative d-flex align-items-center group"> <span>Overview</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="overview-1" aria-haspopup="dialog" aria-label="Share link: Overview"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>NFC</strong> (Normalization Form C) is a canonical composition that converts decomposed characters to their precomposed equivalents where possible.</p> <h4 id="api" class="position-relative d-flex align-items-center group"> <span>API</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="api" aria-haspopup="dialog" aria-label="Share link: API"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">alloc</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kt">u8</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>alloc</code>: Memory allocator</li> <li><code>s</code>: UTF-8 encoded input string</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li>Normalized UTF-8 string (caller owns memory)</li> <li><code>error.InvalidUtf8</code> if input is not valid UTF-8</li> <li><code>error.OutOfMemory</code> if allocation fails</li> </ul> <h4 id="examples" class="position-relative d-flex align-items-center group"> <span>Examples</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="examples" aria-haspopup="dialog" aria-label="Share link: Examples"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Basic Normalization</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">unicode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">&#34;geode&#34;</span><span class="p">).</span><span class="n">unicode</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">allocator</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">heap</span><span class="p">.</span><span class="n">page_allocator</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Decomposed → Composed </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;café&#34;</span><span class="p">;</span><span class="w"> </span><span class="c1">// e + combining acute (U+0065 U+0301) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">normalized</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Result: &#34;café&#34; with precomposed é (U+00E9) </span></span></span></code></pre></div><p><strong>Full-Text Search</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Normalize before indexing </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;Zürich naïve résumé&#34;</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Index normalized form for consistent search </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">try</span><span class="w"> </span><span class="n">fulltext_index</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">normalized</span><span class="p">);</span><span class="w"> </span></span></span></code></pre></div><p><strong>Unique Constraints</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Normalize before uniqueness check </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">email</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;user@exämple.com&#34;</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized_email</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">email</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Check normalized form prevents duplicate variations </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">isEmailTaken</span><span class="p">(</span><span class="n">normalized_email</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">EmailAlreadyExists</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="use-cases" class="position-relative d-flex align-items-center group"> <span>Use Cases</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="use-cases" aria-haspopup="dialog" aria-label="Share link: Use Cases"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li> <p><strong>Full-Text Search</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Automatic</span><span class="w"> </span><span class="py">normalization</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">search</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">text</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">&#39;</span><span class="py">café</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Matches</span><span class="w"> </span><span class="py">both</span><span class="w"> </span><span class="py">composed</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">decomposed</span><span class="w"> </span><span class="py">forms</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Unique Key Enforcement</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">constraint</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">normalization</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">CONSTRAINT</span><span class="w"> </span><span class="py">unique_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">User</span><span class="w"> </span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="s">&#34;user@exämple.com&#34;</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="s">&#34;user@exa\u0308mple.com&#34;</span><span class="w"> </span><span class="py">treated</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">same</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>ORDER BY Determinism</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Consistent</span><span class="w"> </span><span class="py">ordering</span><span class="w"> </span><span class="py">regardless</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">composition</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span></span></span></code></pre></div></li> </ol> <h3 id="case-folding" class="position-relative d-flex align-items-center group"> <span>Case Folding</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="case-folding" aria-haspopup="dialog" aria-label="Share link: Case Folding"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="overview-2" class="position-relative d-flex align-items-center group"> <span>Overview</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="overview-2" aria-haspopup="dialog" aria-label="Share link: Overview"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Case Folding</strong> provides locale-independent case-insensitive string comparison. Unlike simple lowercase conversion, case folding handles special cases like German ß → ss.</p> <h4 id="api-1" class="position-relative d-flex align-items-center group"> <span>API</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="api-1" aria-haspopup="dialog" aria-label="Share link: API"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">foldCase</span><span class="p">(</span><span class="n">alloc</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kt">u8</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>alloc</code>: Memory allocator</li> <li><code>s</code>: UTF-8 encoded input string</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li>Case-folded UTF-8 string (caller owns memory)</li> <li><code>error.InvalidUtf8</code> if input is not valid UTF-8</li> </ul> <h4 id="mappings" class="position-relative d-flex align-items-center group"> <span>Mappings</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="mappings" aria-haspopup="dialog" aria-label="Share link: Mappings"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Supported Case Foldings</strong>:</p> <ul> <li><strong>German ß</strong>: ß → ss (U+00DF → U+0073 U+0073)</li> <li><strong>Greek Σ</strong>: Σ → σ (uppercase sigma → lowercase sigma)</li> <li><strong>Basic Latin</strong>: A-Z → a-z (U+0041-U+005A → U+0061-U+007A)</li> <li><strong>Latin Accents</strong>: À → à, É → é, etc.</li> </ul> <h4 id="examples-1" class="position-relative d-flex align-items-center group"> <span>Examples</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="examples-1" aria-haspopup="dialog" aria-label="Share link: Examples"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Basic Folding</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">folded</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Straße&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Result: &#34;strasse&#34; (ß → ss) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">greek</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;ΣΕΛΛΑΣ&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Result: &#34;σελλασ&#34; (Σ → σ) </span></span></span></code></pre></div><p><strong>Case-Insensitive Search</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Fold both search term and indexed text </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;CAFÉ&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">document</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;café&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Now: query == document (case-insensitive match) </span></span></span></code></pre></div><p><strong>Username Comparison</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Case-insensitive username lookup </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Müller&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">stored</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;MÜLLER&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">eql</span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">,</span><span class="w"> </span><span class="n">stored</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Usernames match (case-insensitive) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="use-cases-1" class="position-relative d-flex align-items-center group"> <span>Use Cases</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="use-cases-1" aria-haspopup="dialog" aria-label="Share link: Use Cases"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li> <p><strong>Full-Text Search</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Case</span><span class="err">-</span><span class="py">insensitive</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="p">(</span><span class="py">automatic</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">doc_text_idx</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Document</span><span class="w"> </span><span class="p">(</span><span class="py">text</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">fulltext</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">text</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Straße</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Matches</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;straße&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Straße&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;STRASSE&#34;</span><span class="p">,</span><span class="w"> </span><span class="nc">etc</span><span class="err">.</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Case-Insensitive Constraints</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Username</span><span class="w"> </span><span class="py">uniqueness</span><span class="w"> </span><span class="p">(</span><span class="py">case</span><span class="err">-</span><span class="py">insensitive</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">CONSTRAINT</span><span class="w"> </span><span class="py">unique_username</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">User</span><span class="w"> </span><span class="p">(</span><span class="py">username</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="s">&#34;Alice&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;alice&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;ALICE&#34;</span><span class="w"> </span><span class="py">all</span><span class="w"> </span><span class="py">rejected</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">duplicates</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Comparisons</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Case</span><span class="err">-</span><span class="py">insensitive</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">clause</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">lower</span><span class="p">(</span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">lower</span><span class="p">(</span><span class="err">&#39;</span><span class="py">MÜLLER</span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">email</span><span class="w"> </span></span></span></code></pre></div></li> </ol> <h3 id="utf-8--utf-16-conversion" class="position-relative d-flex align-items-center group"> <span>UTF-8 ↔ UTF-16 Conversion</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="utf-8--utf-16-conversion" aria-haspopup="dialog" aria-label="Share link: UTF-8 ↔ UTF-16 Conversion"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="utf-8-to-utf-16" class="position-relative d-flex align-items-center group"> <span>UTF-8 to UTF-16</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="utf-8-to-utf-16" aria-haspopup="dialog" aria-label="Share link: UTF-8 to UTF-16"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>API</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">utf8ToUtf16Alloc</span><span class="p">(</span><span class="n">ally</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kt">u16</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>ally</code>: Memory allocator</li> <li><code>s</code>: UTF-8 encoded string</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li>UTF-16LE encoded string as <code>[]u16</code> (caller owns)</li> <li><code>error.InvalidUtf8</code> if input is invalid</li> </ul> <p><strong>Use Cases</strong>:</p> <ul> <li>Windows API interoperability</li> <li>Java/C# string compatibility</li> <li>UTF-16 based protocols</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">utf8_str</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;Hello 世界&#34;</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">utf16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">utf8ToUtf16Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">utf8_str</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">utf16</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// utf16 now contains UTF-16LE code units </span></span></span></code></pre></div> <h4 id="utf-16-to-utf-8" class="position-relative d-flex align-items-center group"> <span>UTF-16 to UTF-8</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="utf-16-to-utf-8" aria-haspopup="dialog" aria-label="Share link: UTF-16 to UTF-8"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>API</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">utf16ToUtf8Alloc</span><span class="p">(</span><span class="n">ally</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span><span class="n">units</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u16</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kt">u8</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>ally</code>: Memory allocator</li> <li><code>units</code>: UTF-16LE code units</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li>UTF-8 encoded string (caller owns)</li> <li>Allocation errors only (UTF-16 validation handled by stdlib)</li> </ul> <p><strong>Use Cases</strong>:</p> <ul> <li>Processing Windows filenames</li> <li>Importing data from UTF-16 sources</li> <li>Interoperability with .NET applications</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">utf16_data</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">getWindowsString</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">utf8</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">utf16ToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">utf16_data</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">utf8</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// utf8 now contains UTF-8 encoded string </span></span></span></code></pre></div> <h4 id="round-trip-safety" class="position-relative d-flex align-items-center group"> <span>Round-Trip Safety</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="round-trip-safety" aria-haspopup="dialog" aria-label="Share link: Round-Trip Safety"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Guaranteed Properties</strong>:</p> <ul> <li>UTF-8 → UTF-16 → UTF-8 preserves original (if valid UTF-8)</li> <li>UTF-16 → UTF-8 → UTF-16 preserves original (if valid UTF-16)</li> <li>Surrogates handled correctly</li> </ul> <p><strong>Test</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Round-trip test </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">original</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;Hello 世界 🚀&#34;</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">utf16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">utf8ToUtf16Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">original</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">back</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">utf16ToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">utf16</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">assert</span><span class="p">(</span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">eql</span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">original</span><span class="p">,</span><span class="w"> </span><span class="n">back</span><span class="p">));</span><span class="w"> </span><span class="c1">// true </span></span></span></code></pre></div> <h3 id="wtf-8-lossy-decoding" class="position-relative d-flex align-items-center group"> <span>WTF-8 Lossy Decoding</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="wtf-8-lossy-decoding" aria-haspopup="dialog" aria-label="Share link: WTF-8 Lossy Decoding"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="overview-3" class="position-relative d-flex align-items-center group"> <span>Overview</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="overview-3" aria-haspopup="dialog" aria-label="Share link: Overview"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>WTF-8</strong> (Wobbly Transformation Format) is a superset of UTF-8 that allows unpaired surrogates. Lossy decoding converts potentially ill-formed sequences to valid UTF-8 by replacing invalid sequences with U+FFFD (replacement character).</p> <h4 id="api-2" class="position-relative d-flex align-items-center group"> <span>API</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="api-2" aria-haspopup="dialog" aria-label="Share link: API"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">ally</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span><span class="n">bytes</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kt">u8</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>ally</code>: Memory allocator</li> <li><code>bytes</code>: Potentially ill-formed UTF-8/WTF-8 data</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li>Valid UTF-8 string with replacements (caller owns)</li> <li>Only allocation errors (never fails on invalid input)</li> </ul> <h4 id="use-cases-2" class="position-relative d-flex align-items-center group"> <span>Use Cases</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="use-cases-2" aria-haspopup="dialog" aria-label="Share link: Use Cases"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Robust File Processing</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Read file with unknown encoding </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">file_data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">readFile</span><span class="p">(</span><span class="s">&#34;unknown.txt&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">valid_utf8</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">file_data</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// valid_utf8 is guaranteed valid UTF-8 </span></span></span></code></pre></div><p><strong>User Input Sanitization</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Handle potentially malformed user input </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">user_input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">getFormData</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">sanitized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">user_input</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Safe to store and display </span></span></span></code></pre></div><p><strong>Legacy Data Migration</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Import data from legacy system with encoding issues </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">legacy_data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">importFromLegacyDB</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">clean_data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">legacy_data</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Store clean data in Geode </span></span></span></code></pre></div> <h4 id="replacement-character" class="position-relative d-flex align-items-center group"> <span>Replacement Character</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="replacement-character" aria-haspopup="dialog" aria-label="Share link: Replacement Character"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>U+FFFD</strong>: � (Replacement Character)</p> <p><strong>Replacement Rules</strong>:</p> <ul> <li>Invalid UTF-8 sequences → U+FFFD</li> <li>Unpaired surrogates → U+FFFD</li> <li>Overlong encodings → U+FFFD</li> <li>Out-of-range code points → U+FFFD</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">invalid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="n">_</span><span class="p">]</span><span class="kt">u8</span><span class="p">{</span><span class="mh">0xFF</span><span class="p">,</span><span class="w"> </span><span class="mh">0xFE</span><span class="p">,</span><span class="w"> </span><span class="mh">0x41</span><span class="p">};</span><span class="w"> </span><span class="c1">// Invalid bytes + &#39;A&#39; </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">fixed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">invalid</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Result: &#34;��A&#34; (two replacements + valid &#39;A&#39;) </span></span></span></code></pre></div> <h3 id="integration-with-geode-features" class="position-relative d-flex align-items-center group"> <span>Integration with Geode Features</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="integration-with-geode-features" aria-haspopup="dialog" aria-label="Share link: Integration with Geode Features"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="full-text-search" class="position-relative d-flex align-items-center group"> <span>Full-Text Search</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="full-text-search" aria-haspopup="dialog" aria-label="Share link: Full-Text Search"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Automatic Normalization</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Index</span><span class="w"> </span><span class="py">creation</span><span class="w"> </span><span class="py">normalizes</span><span class="w"> </span><span class="py">text</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">article_idx</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Article</span><span class="w"> </span><span class="p">(</span><span class="py">content</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">fulltext</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Automatic</span><span class="w"> </span><span class="py">NFC</span><span class="w"> </span><span class="py">normalization</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">case</span><span class="w"> </span><span class="py">folding</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">INSERT</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Article</span><span class="w"> </span><span class="p">{</span><span class="py">content</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;Zürich café résumé&#34;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="nc">Search</span><span class="w"> </span><span class="py">works</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">any</span><span class="w"> </span><span class="py">variation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Article</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">content</span><span class="w"> </span><span class="py">CONTAINS</span><span class="w"> </span><span class="err">&#39;</span><span class="py">zurich</span><span class="w"> </span><span class="py">cafe</span><span class="w"> </span><span class="py">resume</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">a</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Finds</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">article</span><span class="w"> </span><span class="p">(</span><span class="py">normalized</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">folded</span><span class="p">)</span><span class="w"> </span></span></span></code></pre></div><p><strong>Implementation</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// FTS analyzer pipeline </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">fn</span><span class="w"> </span><span class="n">analyzeText</span><span class="p">(</span><span class="n">text</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="n">Token</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// 1. NFC normalization </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// 2. Case folding </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">folded</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">normalized</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// 3. Tokenization </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">tokenize</span><span class="p">(</span><span class="n">folded</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="unique-constraints" class="position-relative d-flex align-items-center group"> <span>Unique Constraints</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="unique-constraints" aria-haspopup="dialog" aria-label="Share link: Unique Constraints"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Normalized Keys</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">CONSTRAINT</span><span class="w"> </span><span class="py">unique_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">User</span><span class="w"> </span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">These</span><span class="w"> </span><span class="py">are</span><span class="w"> </span><span class="py">treated</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">duplicates</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">INSERT</span><span class="w"> </span><span class="p">(</span><span class="py">u1</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">email</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;user@exämple.com&#34;</span><span class="p">})</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="nc">Composed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">INSERT</span><span class="w"> </span><span class="p">(</span><span class="py">u2</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">email</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;user@exa\u0308mple.com&#34;</span><span class="p">})</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="nc">Decomposed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Second</span><span class="w"> </span><span class="py">INSERT</span><span class="w"> </span><span class="py">fails</span><span class="p">:</span><span class="w"> </span><span class="nc">duplicate</span><span class="w"> </span><span class="py">key</span><span class="w"> </span><span class="p">(</span><span class="py">after</span><span class="w"> </span><span class="py">normalization</span><span class="p">)</span><span class="w"> </span></span></span></code></pre></div><p><strong>Implementation</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="k">fn</span><span class="w"> </span><span class="n">checkUniqueConstraint</span><span class="p">(</span><span class="n">key</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">exists</span><span class="p">(</span><span class="n">normalized</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">UniqueConstraintViolation</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="order-by-determinism" class="position-relative d-flex align-items-center group"> <span>ORDER BY Determinism</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="order-by-determinism" aria-haspopup="dialog" aria-label="Share link: ORDER BY Determinism"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Consistent Ordering</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Results</span><span class="w"> </span><span class="py">ordered</span><span class="w"> </span><span class="py">by</span><span class="w"> </span><span class="py">normalized</span><span class="w"> </span><span class="py">form</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="s">&#34;Müller&#34;</span><span class="w"> </span><span class="p">(</span><span class="nc">composed</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="s">&#34;Müller&#34;</span><span class="w"> </span><span class="p">(</span><span class="py">decomposed</span><span class="p">)</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Same</span><span class="w"> </span><span class="py">position</span><span class="w"> </span><span class="p">(</span><span class="py">normalized</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="s">&#34;Schulz&#34;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="expression-comparison" class="position-relative d-flex align-items-center group"> <span>Expression Comparison</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="expression-comparison" aria-haspopup="dialog" aria-label="Share link: Expression Comparison"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>NFC Comparison</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Müller</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">email</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Matches</span><span class="w"> </span><span class="py">both</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="nc">name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&#34;Müller&#34;</span><span class="w"> </span><span class="p">(</span><span class="py">U</span><span class="err">+</span><span class="py">00FC</span><span class="w"> </span><span class="py">composed</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&#34;Mu\u0308ller&#34;</span><span class="w"> </span><span class="p">(</span><span class="py">U</span><span class="err">+</span><span class="py">0075</span><span class="w"> </span><span class="py">U</span><span class="err">+</span><span class="py">0308</span><span class="w"> </span><span class="py">decomposed</span><span class="p">)</span><span class="w"> </span></span></span></code></pre></div> <h3 id="limitations--future-work" class="position-relative d-flex align-items-center group"> <span>Limitations &amp;amp; Future Work</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="limitations--future-work" aria-haspopup="dialog" aria-label="Share link: Limitations &amp;amp; Future Work"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="current-scope" class="position-relative d-flex align-items-center group"> <span>Current Scope</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="current-scope" aria-haspopup="dialog" aria-label="Share link: Current Scope"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Implemented</strong>:</p> <ul> <li>✅ NFC normalization (subset)</li> <li>✅ Case folding (targeted mappings)</li> <li>✅ UTF-8 ↔ UTF-16 conversion</li> <li>✅ WTF-8 lossy decoding</li> </ul> <p><strong>Not Yet Implemented</strong>:</p> <ul> <li>❌ Full canonical combining class ordering</li> <li>❌ Complete composition table</li> <li>❌ Locale-sensitive collation</li> <li>❌ Grapheme cluster segmentation</li> <li>❌ NFKC/NFKD normalization</li> <li>❌ UTF-32 operations</li> </ul> <h4 id="subset-coverage" class="position-relative d-flex align-items-center group"> <span>Subset Coverage</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="subset-coverage" aria-haspopup="dialog" aria-label="Share link: Subset Coverage"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Normalization</strong>:</p> <ul> <li>Selected decompositions only</li> <li>Common Latin, Greek, Cyrillic characters</li> <li>Full table generation via <code>zig build unicode-gen</code></li> </ul> <p><strong>Case Folding</strong>:</p> <ul> <li>Sharp S (ß → ss)</li> <li>Greek sigma variants (Σ/ς/σ)</li> <li>Basic Latin (A-Z → a-z)</li> <li>Common accented characters</li> </ul> <h4 id="future-enhancements" class="position-relative d-flex align-items-center group"> <span>Future Enhancements</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="future-enhancements" aria-haspopup="dialog" aria-label="Share link: Future Enhancements"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Planned Features</strong>:</p> <ul> <li>Full canonical combining class support</li> <li>Complete composition tables</li> <li>Locale-sensitive collation (ICU integration)</li> <li>Grapheme cluster boundary detection</li> <li>NFKC compatibility normalization</li> <li>Advanced text segmentation</li> </ul> <h3 id="performance" class="position-relative d-flex align-items-center group"> <span>Performance</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance" aria-haspopup="dialog" aria-label="Share link: Performance"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="benchmarks" class="position-relative d-flex align-items-center group"> <span>Benchmarks</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="benchmarks" aria-haspopup="dialog" aria-label="Share link: Benchmarks"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>NFC Normalization</strong>:</p> <ul> <li>ASCII-only text: &lt;100ns (fast path)</li> <li>Optimized for common Latin characters</li> <li>Handles complex scripts</li> <li>Memory overhead varies by input</li> </ul> <p><strong>Case Folding</strong>:</p> <ul> <li>Fast path for ASCII-only strings</li> <li>Handles German ß expansion</li> <li>Correct Greek sigma handling</li> </ul> <p><strong>UTF-8 ↔ UTF-16</strong>:</p> <ul> <li>Efficient ASCII conversion</li> <li>Full multi-byte support</li> <li>Surrogate pair handling for rare characters</li> </ul> <p><strong>WTF-8 Lossy</strong>:</p> <ul> <li>Valid UTF-8: &lt;100ns overhead</li> <li>Invalid sequences: ~500ns per replacement</li> <li>Memory: 1.1x input size</li> </ul> <h4 id="optimization-tips" class="position-relative d-flex align-items-center group"> <span>Optimization Tips</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="optimization-tips" aria-haspopup="dialog" aria-label="Share link: Optimization Tips"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Reuse Allocations</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Use arena allocator for batch processing </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">var</span><span class="w"> </span><span class="n">arena</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">heap</span><span class="p">.</span><span class="n">ArenaAllocator</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="n">std</span><span class="p">.</span><span class="n">heap</span><span class="p">.</span><span class="n">page_allocator</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">defer</span><span class="w"> </span><span class="n">arena</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">allocator</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">arena</span><span class="p">.</span><span class="n">allocator</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">texts</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="n">text</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Process normalized text </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// Memory freed in bulk at arena.deinit() </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div><p><strong>Cache Results</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Cache normalized strings </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">var</span><span class="w"> </span><span class="n">cache</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">StringHashMap</span><span class="p">([]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">).</span><span class="n">init</span><span class="p">(</span><span class="n">allocator</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span><span class="w"> </span><span class="n">getNormalized</span><span class="p">(</span><span class="n">text</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">text</span><span class="p">))</span><span class="w"> </span><span class="o">|</span><span class="n">cached</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">cached</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">cache</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="n">text</span><span class="p">,</span><span class="w"> </span><span class="n">normalized</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">normalized</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h3 id="testing" class="position-relative d-flex align-items-center group"> <span>Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing" aria-haspopup="dialog" aria-label="Share link: Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="test-coverage" class="position-relative d-flex align-items-center group"> <span>Test Coverage</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="test-coverage" aria-haspopup="dialog" aria-label="Share link: Test Coverage"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Unit Tests</strong>: <code>tests/canary_unicode_utf16.zig</code></p> <ul> <li><code>TestCANARY_REQ_GQL_UNICODE_012_Utf8ToUtf16RoundTrip</code></li> <li><code>TestCANARY_REQ_GQL_UNICODE_013_Utf16ToUtf8RoundTrip</code></li> <li><code>TestCANARY_REQ_GQL_UNICODE_014_Wtf8Lossy</code></li> </ul> <p><strong>Test Cases</strong>:</p> <ul> <li>Round-trip conversions</li> <li>Invalid sequence handling</li> <li>Surrogate pair processing</li> <li>Emoji support (🚀, 😀, etc.)</li> <li>CJK characters (Chinese, Japanese, Korean)</li> <li>Combining characters</li> </ul> <h4 id="example-tests" class="position-relative d-flex align-items-center group"> <span>Example Tests</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="example-tests" aria-haspopup="dialog" aria-label="Share link: Example Tests"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="k">test</span><span class="w"> </span><span class="s">&#34;UTF-8 to UTF-16 round-trip&#34;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">original</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;Hello 世界 🚀&#34;</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">utf16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">utf8ToUtf16Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">original</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">utf16</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">back</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">utf16ToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">utf16</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">back</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">testing</span><span class="p">.</span><span class="n">expectEqualSlices</span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">original</span><span class="p">,</span><span class="w"> </span><span class="n">back</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">test</span><span class="w"> </span><span class="s">&#34;WTF-8 lossy decoding&#34;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">invalid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="n">_</span><span class="p">]</span><span class="kt">u8</span><span class="p">{</span><span class="mh">0xFF</span><span class="p">,</span><span class="w"> </span><span class="mh">0xFE</span><span class="p">};</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">valid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">invalid</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">valid</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Should contain replacement characters </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">testing</span><span class="p">.</span><span class="n">expect</span><span class="p">(</span><span class="n">valid</span><span class="p">.</span><span class="n">len</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h3 id="best-practices" class="position-relative d-flex align-items-center group"> <span>Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices" aria-haspopup="dialog" aria-label="Share link: Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="always-normalize-user-input" class="position-relative d-flex align-items-center group"> <span>Always Normalize User Input</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="always-normalize-user-input" aria-haspopup="dialog" aria-label="Share link: Always Normalize User Input"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// ✅ Good: Normalize before storing </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">user_input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">getFormData</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">user_input</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">try</span><span class="w"> </span><span class="n">storeInDatabase</span><span class="p">(</span><span class="n">normalized</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ❌ Bad: Store raw input </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">user_input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">getFormData</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">try</span><span class="w"> </span><span class="n">storeInDatabase</span><span class="p">(</span><span class="n">user_input</span><span class="p">);</span><span class="w"> </span><span class="c1">// May cause duplicate key issues </span></span></span></code></pre></div> <h4 id="use-case-folding-for-search" class="position-relative d-flex align-items-center group"> <span>Use Case Folding for Search</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="use-case-folding-for-search" aria-haspopup="dialog" aria-label="Share link: Use Case Folding for Search"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// ✅ Good: Case-insensitive search </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">foldCase</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">user_query</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">results</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">searchFullText</span><span class="p">(</span><span class="n">query</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ❌ Bad: Case-sensitive (misses matches) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">results</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">searchFullText</span><span class="p">(</span><span class="n">user_query</span><span class="p">);</span><span class="w"> </span></span></span></code></pre></div> <h4 id="handle-errors-gracefully" class="position-relative d-flex align-items-center group"> <span>Handle Errors Gracefully</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="handle-errors-gracefully" aria-haspopup="dialog" aria-label="Share link: Handle Errors Gracefully"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// ✅ Good: Fallback on error </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">err</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Log error, use lossy decoding as fallback </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">log</span><span class="p">.</span><span class="n">warn</span><span class="p">(</span><span class="s">&#34;Normalization failed: {}, using lossy&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">err</span><span class="p">});</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">safe</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">wtf8LossyToUtf8Alloc</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">safe</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ❌ Bad: Crash on invalid input </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span></code></pre></div> <h4 id="free-allocated-memory" class="position-relative d-flex align-items-center group"> <span>Free Allocated Memory</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="free-allocated-memory" aria-haspopup="dialog" aria-label="Share link: Free Allocated Memory"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// ✅ Good: Free allocated strings </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">normalized</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Use normalized... </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ❌ Bad: Memory leak </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">unicode</span><span class="p">.</span><span class="n">nfcNormalize</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">text</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Forgot to free! </span></span></span></code></pre></div> <h3 id="references" class="position-relative d-flex align-items-center group"> <span>References</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="references" aria-haspopup="dialog" aria-label="Share link: References"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="standards" class="position-relative d-flex align-items-center group"> <span>Standards</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="standards" aria-haspopup="dialog" aria-label="Share link: Standards"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li> <p><strong>Unicode Standard 15.0</strong>: Character encoding and normalization</p> <ul> <li><a href="https://unicode.org/versions/Unicode15.0.0/" aria-label="https://unicode.org/versions/Unicode15.0.0/ – opens in new window" target="_blank" rel="noopener noreferrer" >https://unicode.org/versions/Unicode15.0.0/ <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> <li> <p><strong>UAX #15</strong>: Unicode Normalization Forms</p> <ul> <li><a href="https://unicode.org/reports/tr15/" aria-label="https://unicode.org/reports/tr15/ – opens in new window" target="_blank" rel="noopener noreferrer" >https://unicode.org/reports/tr15/ <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> <li> <p><strong>UAX #21</strong>: Case Mappings</p> <ul> <li><a href="https://unicode.org/reports/tr21/" aria-label="https://unicode.org/reports/tr21/ – opens in new window" target="_blank" rel="noopener noreferrer" >https://unicode.org/reports/tr21/ <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> </ul> <h4 id="implementation" class="position-relative d-flex align-items-center group"> <span>Implementation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="implementation" aria-haspopup="dialog" aria-label="Share link: Implementation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><strong>Zig Stdlib</strong>: <code>std.unicode</code> module <ul> <li>UTF-8/UTF-16 conversion functions</li> <li>Validation and error handling</li> </ul> </li> </ul> <h4 id="code-location" class="position-relative d-flex align-items-center group"> <span>Code Location</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="code-location" aria-haspopup="dialog" aria-label="Share link: Code Location"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><strong>Implementation</strong>: <code>src/unicode/geode_unicode.zig</code></li> <li><strong>Tests</strong>: <code>tests/canary_unicode_utf16.zig</code></li> <li><strong>Documentation</strong>: <code>docs/UNICODE.md</code></li> </ul> <h3 id="next-steps" class="position-relative d-flex align-items-center group"> <span>Next Steps</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="next-steps" aria-haspopup="dialog" aria-label="Share link: Next Steps"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p><strong>For New Users</strong>:</p> <ul> <li><a href="/docs/data-types/_index/" >Data Types</a> - String type fundamentals</li> <li><a href="/docs/query/full-text-search/" >Full-Text Search</a> - Search with Unicode</li> <li><a href="/docs/gql/guide/" >GQL Guide</a> - Query language basics</li> </ul> <p><strong>For Developers</strong>:</p> <ul> <li><a href="/docs/reference/type-conversion/" >Type Conversion</a> - String conversions</li> <li><a href="/docs/reference/api-reference-complete/" >API Reference</a> - Complete function list</li> <li><a href="/docs/guides/testing-strategies/" >Testing</a> - Text processing tests</li> </ul> <p><strong>For Advanced Users</strong>:</p> <ul> <li><a href="/docs/query/performance-tuning/" >Performance Tuning</a> - Text query optimization</li> <li><a href="/docs/query/indexing-and-optimization/" >Indexing</a> - Full-text index configuration</li> </ul> <hr> <p><strong>Document Version</strong>: 1.0 <strong>Last Updated</strong>: January 24, 2026 <strong>Status</strong>: Production Ready <strong>Unicode Version</strong>: 15.0 (subset) <strong>CANARY</strong>: REQ-GQL-UNICODE-004 through REQ-GQL-UNICODE-014 (TESTED)</p>