v0.2.15
This commit is contained in:
287
annexes/B-unicode-encoding-conversions.md
Normal file
287
annexes/B-unicode-encoding-conversions.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# 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
|
||||
to... uniquement pour une conversion totale et sûre
|
||||
tryFrom... / tryTo... lorsqu'une validation ou une condition peut échouer
|
||||
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::tryFrom(uint8)
|
||||
Utf8Char::tryFrom(StaticArray<uint8, N>)
|
||||
```
|
||||
|
||||
`N` utile : 1 à 4. Le contenu doit représenter exactement un scalar UTF-8 valide.
|
||||
|
||||
UTF-16 :
|
||||
|
||||
```text
|
||||
Utf16Char::tryFrom(uint16)
|
||||
Utf16Char::tryFrom(StaticArray<uint16, 2>)
|
||||
```
|
||||
|
||||
Un surrogate isolé est invalide.
|
||||
|
||||
UTF-32 :
|
||||
|
||||
```text
|
||||
Utf32Char::tryFrom(uint32)
|
||||
```
|
||||
|
||||
La valeur doit être <= `0x10FFFF` et hors de la plage surrogate.
|
||||
|
||||
Le nom de travail de l'erreur est :
|
||||
|
||||
```text
|
||||
UnicodeEncodingError extends ResultError
|
||||
```
|
||||
|
||||
## B.7. `UtfXChar` -> code unit brute
|
||||
|
||||
| Source | Destination | Opération | Raison |
|
||||
|---|---|---|---|
|
||||
| `Utf8Char` | `uint8` | `tryToUint8()` | 1 à 4 unités possibles |
|
||||
| `Utf16Char` | `uint16` | `tryToUint16()` | 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::tryFrom(Array<uint8>)
|
||||
Utf16String::tryFrom(Array<uint16>)
|
||||
Utf32String::tryFrom(Array<uint32>)
|
||||
```
|
||||
|
||||
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 `UnicodeEncodingError` ;
|
||||
7. localisation Core/SDK des opérations Unicode avancées : graphemes, normalisation, case folding, collation.
|
||||
Reference in New Issue
Block a user