- La version 0.15 de Zig a introduit la nouvelle interface IO (
std.Io.Reader, std.Io.Writer)
- Objectif : améliorer la complexité et les problèmes de performance de l’ancien modèle IO, mais cela a entraîné une confusion sur l’usage réel
- L’utilisation de
tls.Client et des buffers ajoute à la confusion en raison d’un mode de passage des paramètres incohérent
- Même dans des exemples d’utilisation basiques, il faut gérer des exigences complexes comme la taille de plusieurs buffers et des champs d’options
- Faute de documentation officielle, d’exemples de code et de fonctions utilitaires, l’ensemble est peu intuitif pour les débutants
La nouvelle interface IO introduite dans Zig 0.15 et son contexte
- La version 0.15 de Zig a introduit de nouveaux types IO :
std.Io.Reader et std.Io.Writer
- L’ancienne interface IO entraînait de la complexité à cause de problèmes de performance, du mélange des types et d’un usage excessif de
anytype
- Le but principal de la nouvelle structure IO est de clarifier la séparation des types entre interfaces et d’améliorer les performances
Les problèmes concrets lors de l’utilisation de tls.Client et de l’interface IO
- Lors de la mise à jour d’une bibliothèque SMTP existante, de la confusion est apparue autour de l’utilisation de la fonction
tls.Client.init
- D’après la documentation, la fonction
init reçoit en arguments des pointeurs vers Reader et Writer, ainsi qu’un ensemble d’options
- Dans Zig,
net.Stream renvoie respectivement Stream.Reader et Stream.Writer via les méthodes reader() et writer()
- Mais
Stream.Reader/Writer et std.Io.Reader/Writer ne sont pas exactement les mêmes types, ce qui impose une conversion
- Pour
Reader, il faut appeler la méthode interface(), tandis que pour Writer, il faut utiliser le champ &interface, ce qui manque de cohérence
Le problème de configuration des buffers et des champs d’options
stream.writer et stream.reader prennent chacun un buffer en argument
- Le buffer est ainsi présenté comme un élément essentiel de la nouvelle interface IO
- Lors de l’appel à
tls.Client.init, quatre champs d’options sont requis : ca_bundle, host, write_buffer et read_buffer
- La logique de séparation entre les valeurs passées dans les options et celles passées directement en argument semble peu claire
var tls_client = try std.crypto.tls.Client.init(
reader.interface(),
&writer.interface,
.{
.ca = .{.bundle = bundle},
.host = .{ .explicit = "www.openmymind.net" } ,
.read_buffer = &read_buf2,
.write_buffer = &write_buf2,
},
)
- En pratique, si les pointeurs de buffer ne sont pas correctement fournis, le programme peut mal fonctionner, se bloquer ou planter
Le manque d’intuitivité lors de l’utilisation de Reader
- Bien que le champ
reader de tls.Client soit lui-même un « flux déchiffré », std.Io.Reader ne propose pas de méthode read classique
- À la place, on ne trouve que des méthodes moins intuitives comme
peek, takeByteSigned ou readSliceShort
- L’API la plus proche d’un usage courant consiste à utiliser la méthode
stream pour lire les données dans un buffer
var buf: [1024]u8 = undefined;
var w: std.Io.Writer = .fixed(&buf);
const n = try tls_client.reader.stream(&w, .limited(buf.len));
Exemple de code complet et difficultés en pratique
- Même pour produire un exemple minimal entièrement fonctionnel, il faut gérer de nombreux détails : options, taille des buffers, conversions de type, etc.
- Le manque de tests, de documentation et d’exemples augmente la difficulté d’apprentissage et la barrière à l’entrée
- Sans une bonne compréhension de la cohérence interne du langage Zig ou de son design sous-jacent, de nombreux aspects peuvent sembler étranges
- Même dans la bibliothèque standard, cette approche est encore peu utilisée, ce qui limite les références pratiques
Retour d’expérience et conclusion
- Avec des changements comme le renommage de
std.fmt.printInt, les évolutions de design d’API, etc., la migration elle-même n’est pas simple
- L’auteur a rencontré de manière répétée plusieurs difficultés :
reader.interface(), la forme &writer.interface, le passage des options, ou encore la nécessité de plusieurs buffers
- Lorsqu’on n’est pas familier avec les protocoles réseau ou de sécurité comme TLS, il est encore plus difficile de comprendre les exigences
- Globalement, il reste de nombreuses insuffisances en matière de clarté, de documentation et de confort d’utilisation par rapport à l’existant
Aucun commentaire pour le moment.