Menu
Coddy logo textTech

Özet - Dosya Ayrıştırıcı

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 58 / 107.

challenge icon

Görev

Kolay

Bu bölümdeki tüm hata işleme tekniklerini bir araya getiren bir yapılandırma dosyası ayrıştırıcısı (parser) oluşturalım. Ayrıştırıcınız; özel hata türleri, sentinel hatalar, hata sarmalama (error wrapping) ve defer kullanarak uygun temizleme işlemleri ile birden fazla başarısızlık senaryosunu yönetecek.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • errors.go: Ayrıştırıcı için hata altyapınızı tanımlayın.

    İki adet sentinel hata oluşturun:

    • "file content is empty" mesajıyla ErrEmptyContent
    • "invalid configuration format" mesajıyla ErrInvalidFormat

    Line (int) ve Message (string) alanlarına sahip özel bir hata türü olan ParseError oluşturun. Bu türün Error() metodu şu sonucu döndürmelidir: parse error at line [Line]: [Message]

  • parser.go: Katmanlı hata işleme özelliğine sahip yapılandırma ayrıştırıcısını oluşturun.

    Ayrıştırmanın başarıyla tamamlanıp tamamlanmadığını takip etmek için parsed adında boolean bir alana sahip ConfigParser struct'ını oluşturun.

    Şu metotları uygulayın:

    • NewConfigParser() *ConfigParser - parsed değeri false olarak ayarlanmış yeni bir ayrıştırıcı oluşturur.
    • ParseLine(lineNum int, line string) error - tek bir satırı doğrular. Eğer satır bir = karakteri içermiyorsa, satır numarasını ve "missing key-value separator" mesajını içeren bir *ParseError döndürün. Aksi takdirde nil döndürün.
    • Parse(content string) error - ana ayrıştırma metodudur ve şunları yapar:
      • İçerik boşsa ErrEmptyContent döndürür
      • İçerik en az bir yeni satır karakteri içermiyorsa ErrInvalidFormat döndürür
      • İçeriği yeni satırlara göre böler ve her satır için ParseLine metodunu çağırır (satır numaraları 1'den başlar)
      • Eğer ParseLine bir hata döndürürse, bunu "parsing configuration: %w" ile sarmalayın ve döndürün
      • Başarı durumunda parsed değerini true yapar ve nil döndürür
    • Status() string - eğer parsed true ise "ready", aksi takdirde "not parsed" döndürür
  • main.go: Yapılandırma içeriğini okuyun ve kapsamlı hata incelemesini gösterin.

    Birlikte yapılandırma içeriğini oluşturan iki satırlık girdi okuyun (bunları bir yeni satır karakteri ile birleştirin). Başarı veya başarısızlık durumuna bakılmaksızın, ayrıştırıcının durumunu sonunda her zaman yazdırmak için defer kullanın.

    Ayrıştırma denemesinden sonra, neyin yanlış gittiğine bağlı olarak özel geri bildirim sağlamak için hem errors.Is() hem de errors.As() kullanarak hataları inceleyin.

Aşağıdaki girdiler sağlanacaktır:

  • Satır 1: Yapılandırma içeriğinin ilk satırı
  • Satır 2: Yapılandırma içeriğinin ikinci satırı

Hataları belirli mesajlarla ele alın:

  • Eğer errors.Is(), ErrEmptyContent bulursa: Error: No configuration provided yazdırın
  • Eğer errors.Is(), ErrInvalidFormat bulursa: Error: Configuration must have multiple lines yazdırın
  • Eğer errors.As(), bir *ParseError bulursa: tam sarmalanmış hatayı yazdırın, ardından yeni bir satırda Fix line [Line]: [Message] yazdırın
  • Ayrıştırma başarılı olursa: Configuration parsed successfully yazdırın

Sonucu (başarı veya hata) işledikten sonra, ertelenmiş (deferred) durum yeni bir satırda yazdırılmalıdır: Parser status: [status]

Örneğin, host=localhost ve port=8080 verildiğinde çıktınız şöyle olmalıdır:

Configuration parsed successfully
Parser status: ready

Ve host=localhost ile invalid line verildiğinde çıktınız şöyle olmalıdır:

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

Kendin dene

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// Yapılandırmanın ilk satırını oku
	line1, _ := reader.ReadString('\n')
	line1 = line1[:len(line1)-1] // Sondaki yeni satır karakterini kaldır
	
	// Yapılandırmanın ikinci satırını oku
	line2, _ := reader.ReadString('\n')
	if len(line2) > 0 && line2[len(line2)-1] == '\n' {
		line2 = line2[:len(line2)-1]
	}
	
	// Yapılandırma içeriğini oluşturmak için iki satırı bir yeni satır karakteriyle birleştir
	content := line1 + "\n" + line2
	
	// Yeni bir ayrıştırıcı (parser) oluştur
	parser := NewConfigParser()
	
	// TODO: Sonunda her zaman ayrıştırıcının durumunu yazdırmak için defer kullanın
	// Biçim: "Parser status: [status]"
	
	// TODO: İçeriği ayrıştırmayı deneyin
	
	// TODO: errors.Is() ve errors.As() kullanarak hataları ele alın
	// - Eğer errors.Is() ErrEmptyContent bulursa: "Error: No configuration provided" yazdırın
	// - Eğer errors.Is() ErrInvalidFormat bulursa: "Error: Configuration must have multiple lines" yazdırın
	// - Eğer errors.As() bir *ParseError bulursa: sarmalanmış hatanın tamamını yazdırın,
	//   ardından yeni bir satırda "Fix line [Line]: [Message]" yazdırın
	// - Eğer ayrıştırma başarılı olursa: "Configuration parsed successfully" yazdırın
	
	_ = errors.Is // ipucu: sentinel hatalar için errors.Is kullanın
	_ = errors.As // ipucu: özel hata türleri için errors.As kullanın
	_ = fmt.Println
}

Nesne Yönelimli Programlama bölümündeki tüm dersler