Menu
Coddy logo textTech

Récapitulatif - File Parser

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 58 sur 107.

challenge icon

Défi

Facile

Construisons un analyseur de fichier de configuration qui regroupe toutes les techniques de gestion d'erreurs de ce chapitre. Votre analyseur gérera plusieurs scénarios d'échec avec des types d'erreurs personnalisés, des erreurs sentinelles, l'emballage d'erreurs (error wrapping) et un nettoyage approprié à l'aide de defer.

Vous organiserez votre code sur trois fichiers :

  • errors.go : Définissez votre infrastructure d'erreurs pour l'analyseur.

    Créez deux erreurs sentinelles :

    • ErrEmptyContent avec le message "file content is empty"
    • ErrInvalidFormat avec le message "invalid configuration format"

    Créez un type d'erreur personnalisé ParseError avec les champs Line (int) et Message (string). Sa méthode Error() doit retourner : parse error at line [Line]: [Message]

  • parser.go : Construisez l'analyseur de configuration avec une gestion d'erreurs par couches.

    Créez une structure ConfigParser avec un champ booléen parsed pour suivre si l'analyse s'est terminée avec succès.

    Implémentez ces méthodes :

    • NewConfigParser() *ConfigParser - crée un nouvel analyseur avec parsed défini sur false
    • ParseLine(lineNum int, line string) error - valide une seule ligne. Si la ligne ne contient pas de caractère =, retournez un *ParseError avec le numéro de ligne et le message "missing key-value separator". Sinon, retournez nil.
    • Parse(content string) error - la méthode d'analyse principale qui :
      • Retourne ErrEmptyContent si le contenu est vide
      • Retourne ErrInvalidFormat si le contenu ne contient pas au moins un caractère de saut de ligne
      • Divise le contenu par sauts de ligne et appelle ParseLine pour chaque ligne (les numéros de ligne commencent à 1)
      • Si ParseLine retourne une erreur, emballez-la avec "parsing configuration: %w" et retournez-la
      • Définit parsed sur true en cas de succès et retourne nil
    • Status() string - retourne "ready" si parsed est vrai, sinon "not parsed"
  • main.go : Lisez le contenu de la configuration et démontrez une inspection complète des erreurs.

    Lisez deux lignes d'entrée qui forment ensemble le contenu de la configuration (joignez-les avec un saut de ligne). Utilisez defer pour toujours afficher le statut de l'analyseur à la fin, quel que soit le succès ou l'échec.

    Après avoir tenté l'analyse, inspectez toute erreur en utilisant à la fois errors.Is() et errors.As() pour fournir un retour spécifique basé sur ce qui s'est mal passé.

Les entrées suivantes seront fournies :

  • Ligne 1 : Première ligne du contenu de la configuration
  • Ligne 2 : Deuxième ligne du contenu de la configuration

Gérez les erreurs avec des messages spécifiques :

  • Si errors.Is() trouve ErrEmptyContent : affichez Error: No configuration provided
  • Si errors.Is() trouve ErrInvalidFormat : affichez Error: Configuration must have multiple lines
  • Si errors.As() trouve un *ParseError : affichez l'erreur emballée complète, puis sur une nouvelle ligne affichez Fix line [Line]: [Message]
  • Si l'analyse réussit : affichez Configuration parsed successfully

Après avoir traité le résultat (succès ou erreur), le statut différé doit s'afficher sur une nouvelle ligne : Parser status: [status]

Par exemple, avec host=localhost et port=8080, votre sortie devrait être :

Configuration parsed successfully
Parser status: ready

Et avec host=localhost et invalid line, votre sortie devrait être :

parsing configuration: parse error at line 2: missing key-value separator
Fix line 2: missing key-value separator
Parser status: not parsed

Essayez vous-même

package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// Lire la première ligne de configuration
	line1, _ := reader.ReadString('\n')
	line1 = line1[:len(line1)-1] // Supprimer le saut de ligne final
	
	// Lire la deuxième ligne de configuration
	line2, _ := reader.ReadString('\n')
	if len(line2) > 0 && line2[len(line2)-1] == '\n' {
		line2 = line2[:len(line2)-1]
	}
	
	// Joindre les deux lignes avec un saut de ligne pour former le contenu de la configuration
	content := line1 + "\n" + line2
	
	// Créer un nouveau parseur
	parser := NewConfigParser()
	
	// TODO: Utiliser defer pour toujours afficher le statut du parseur à la fin
	// Format: "Parser status: [status]"
	
	// TODO: Tenter d'analyser le contenu
	
	// TODO: Gérer les erreurs en utilisant errors.Is() et errors.As()
	// - Si errors.Is() trouve ErrEmptyContent: afficher "Error: No configuration provided"
	// - Si errors.Is() trouve ErrInvalidFormat: afficher "Error: Configuration must have multiple lines"
	// - Si errors.As() trouve un *ParseError: afficher l'erreur complète enveloppée,
	//   puis sur une nouvelle ligne afficher "Fix line [Line]: [Message]"
	// - Si l'analyse réussit: afficher "Configuration parsed successfully"
	
	_ = errors.Is // indice: utiliser errors.Is pour les erreurs sentinelles
	_ = errors.As // indice: utiliser errors.As pour les types d'erreurs personnalisés
	_ = fmt.Println
}

Toutes les leçons de Programmation Orientée Objet