Files
saselang-bible/annexes/B-unicode-encoding-conversions.md
2026-09-13 10:20:16 +02:00

291 lines
7.7 KiB
Markdown

# Annexe B — Matrice des conversions Unicode et encodages
## B.1. Principes normatifs
Cette annexe inventorie les conversions entre les représentations textuelles fondamentales de Saselang et les unités brutes d'encodage.
Elle applique les mêmes principes que la matrice numérique :
```text
aucune conversion implicite
aucun mélange de types dans les opérations textuelles
conversion directe vers la valeur attendue
faults UnicodeEncodingFault lorsqu'une validation runtime peut échouer
aucune variante try... parallèle si elle ne change que le canal d'échec
aucun alias redondant
conversion explicite d'abord, opération ensuite
```
## B.2. Types concernés
### B.2.1. Niveau Unicode sémantique
```text
char
exactement un Unicode scalar
String
séquence Unicode sémantique de char
encodage physique non observable
```
### B.2.2. Niveau Unicode encodé
```text
Utf8Char
encodage UTF-8 valide d'exactement un Unicode scalar
1 à 4 uint8
Utf16Char
encodage UTF-16 valide d'exactement un Unicode scalar
1 à 2 uint16
Utf32Char
encodage UTF-32 valide d'exactement un Unicode scalar
exactement 1 uint32
```
```text
Utf8String
séquence UTF-8 valide
Utf16String
séquence UTF-16 valide
Utf32String
séquence UTF-32 valide
```
### B.2.3. Code units brutes
```text
UTF-8 code unit = uint8
UTF-16 code unit = uint16
UTF-32 code unit = uint32
```
Aucun type `UtfXCodeUnit` distinct n'est défini sans besoin sémantique supplémentaire.
## B.3. Invariants
Toute valeur `UtfXChar` et `UtfXString` est valide pour son encodage.
Ces types peuvent être mutables via leurs méthodes contrôlées, mais aucune API ne peut laisser leur valeur dans un état d'encodage invalide.
Une mutation brute de code unit n'est donc pas exposée.
Un accès `const` interdit les mutations via cet accès selon les règles générales du langage.
## B.4. `char` <-> `UtfXChar`
| Source | Destination | Opération |
|---|---|---|
| `char` | `Utf8Char` | `toUtf8Char()` |
| `char` | `Utf16Char` | `toUtf16Char()` |
| `char` | `Utf32Char` | `toUtf32Char()` |
| `Utf8Char` | `char` | `toChar()` |
| `Utf16Char` | `char` | `toChar()` |
| `Utf32Char` | `char` | `toChar()` |
Toutes ces conversions sont totales.
## B.5. `UtfXChar` <-> `UtfYChar`
| Source | Destination | Opération |
|---|---|---|
| `Utf8Char` | `Utf16Char` | `toUtf16Char()` |
| `Utf8Char` | `Utf32Char` | `toUtf32Char()` |
| `Utf16Char` | `Utf8Char` | `toUtf8Char()` |
| `Utf16Char` | `Utf32Char` | `toUtf32Char()` |
| `Utf32Char` | `Utf8Char` | `toUtf8Char()` |
| `Utf32Char` | `Utf16Char` | `toUtf16Char()` |
Ces transcodages sont totaux.
## B.6. Code unit brute -> `UtfXChar`
UTF-8 :
```text
Utf8Char::from(uint8) faults UnicodeEncodingFault
Utf8Char::from(StaticArray<uint8, N>) faults UnicodeEncodingFault
```
`N` utile : 1 à 4. Le contenu doit représenter exactement un scalar UTF-8 valide.
UTF-16 :
```text
Utf16Char::from(uint16) faults UnicodeEncodingFault
Utf16Char::from(StaticArray<uint16, 2>) faults UnicodeEncodingFault
```
Un surrogate isolé est invalide.
UTF-32 :
```text
Utf32Char::from(uint32) faults UnicodeEncodingFault
```
La valeur doit être <= `0x10FFFF` et hors de la plage surrogate.
Le nom de travail de l'erreur est :
```text
UnicodeEncodingFault extends Fault
```
Le Core ne fournit pas simultanément une variante `tryFrom... -> Result` ayant exactement la même validation. Si un domaine applicatif souhaite transporter l'échec comme valeur, il peut encapsuler explicitement la construction dans son propre `Result`.
## B.7. `UtfXChar` -> code unit brute
| Source | Destination | Opération | Raison |
|---|---|---|---|
| `Utf8Char` | `uint8` | `toUint8() faults UnicodeEncodingFault` | 1 à 4 unités possibles |
| `Utf16Char` | `uint16` | `toUint16() faults UnicodeEncodingFault` | 1 ou 2 unités possibles |
| `Utf32Char` | `uint32` | `toUint32()` | exactement 1 unité |
Les séquences complètes de code units sont accessibles via `codeUnits()`. Le type concret de vue retourné sera fixé avec les collections/slices.
## B.8. `String` <-> `UtfXString`
| Source | Destination | Opération |
|---|---|---|
| `String` | `Utf8String` | `toUtf8String()` |
| `String` | `Utf16String` | `toUtf16String()` |
| `String` | `Utf32String` | `toUtf32String()` |
| `Utf8String` | `String` | `toString()` |
| `Utf16String` | `String` | `toString()` |
| `Utf32String` | `String` | `toString()` |
Toutes ces conversions sont totales.
## B.9. `UtfXString` <-> `UtfYString`
| Source | Destination | Opération |
|---|---|---|
| `Utf8String` | `Utf16String` | `toUtf16String()` |
| `Utf8String` | `Utf32String` | `toUtf32String()` |
| `Utf16String` | `Utf8String` | `toUtf8String()` |
| `Utf16String` | `Utf32String` | `toUtf32String()` |
| `Utf32String` | `Utf8String` | `toUtf8String()` |
| `Utf32String` | `Utf16String` | `toUtf16String()` |
Tous ces transcodages sont explicites et totaux.
## B.10. Données brutes -> `UtfXString`
Conceptuellement :
```text
Utf8String::from(Array<uint8>) faults UnicodeEncodingFault
Utf16String::from(Array<uint16>) faults UnicodeEncodingFault
Utf32String::from(Array<uint32>) faults UnicodeEncodingFault
```
Le type exact accepté pourra inclure des slices/vues lors de leur définition.
La construction valide l'intégralité de la séquence. Une valeur `UtfXString` invalide ne peut jamais être produite.
## B.11. Indexation et accès nommés
```text
String
pas de OpIndex
scalarAt(uint64) -> char
```
```text
Utf8String[index] -> uint8
Utf16String[index] -> uint16
Utf32String[index] -> uint32
```
Ces indexations sont read-only.
Accès par scalar ordinal :
```text
Utf8String::encodedCharAt(uint64) -> Utf8Char
Utf16String::encodedCharAt(uint64) -> Utf16Char
Utf32String::encodedCharAt(uint64) -> Utf32Char
```
et :
```text
Utf8String::scalarAt(uint64) -> char
Utf16String::scalarAt(uint64) -> char
Utf32String::scalarAt(uint64) -> char
```
## B.12. Itérations/vues explicites
```text
codeUnits()
encodedChars()
scalars()
```
Les strings encodées n'imposent pas un `Iterable<T>` direct unique, car ces trois unités sont légitimes et différentes.
`String`, dont l'unité sémantique est non ambiguë, implémente `Iterable<char>`.
## B.13. Interaction `UtfXString` / `UtfXChar`
Une `UtfXString` accepte directement uniquement les caractères et strings du même encodage dans ses opérations typées.
```text
Utf8String text = ...;
Utf8Char c = ...;
Utf16Char d = ...;
text::append(c); // OK
text::append(d); // ERROR
text::append(d::toUtf8Char()); // OK
```
Même règle pour concaténation, insertion, remplacement et autres opérations.
Aucun transcodage n'est déclenché implicitement par la méthode appelée.
## B.14. Mutabilité et `const`
`String` et `UtfXString` peuvent exposer des méthodes mutantes.
```text
String text = "abc";
text::append("def");
```
`text` est modifiée selon le contrat de `append`.
Les `UtfXString` maintiennent leur invariant d'encodage lors de toute mutation contrôlée.
```text
Utf8String text = ...;
Utf8Char c = ...;
text::append(c); // OK
text[index] = 0xFF; // ERROR
```
Avec :
```text
const Utf8String text = ...;
```
les opérations mutantes sont interdites via `text`, mais un autre alias mutable vers le même objet peut continuer à le modifier.
## B.15. Points encore à fermer
1. type exact des vues `codeUnits()`, `encodedChars()` et `scalars()` ;
2. modèle des slices/substrings et frontières de code units ;
3. nom exact de l'API de décodage depuis un offset de code unit ;
4. API précise de concaténation et ses opérateurs ;
5. builders/buffers et leurs relations avec les strings valides ;
6. codes définitifs de `UnicodeEncodingFault` ;
7. localisation Core/SDK des opérations Unicode avancées : graphemes, normalisation, case folding, collation.