diff --git a/content/chapter 4/4.9-toml.md b/content/chapter 4/4.9-toml.md index df47aa38a..adbaa701b 100644 --- a/content/chapter 4/4.9-toml.md +++ b/content/chapter 4/4.9-toml.md @@ -4,4 +4,167 @@ slug: work-with-toml-file-in-go weight: 7009 --- -آموزش کار با toml... \ No newline at end of file +## 4.9.1 مقدمه +فایل‌های TOML یک نمونه از فایل‌های پیکربندی هستند که در سیستم‌های مدرن مورد استفاده قرار می‌گیرند، این فایل‌ها به صورت متنی و قابل خواندن برای انسان و در عین حال قابل پردازش برای ماشین طراحی شده‌اند. + +TOML مخفف کلمات (Tom's Obvious, Minimal Language) می‌باشد. جمعیت بزرگتری از افراد آن را مفسرند به این شکل که TOML ابزاری ساده برای پیکربندی بسیار درون‌فرمانی است. این فرمت فایل متنی دارای مقادیر شبیه به دیکشنری بوده و در بسیاری از نرم‌افزارها، به‌طور خاص در نرم‌افزارهای ساخته شده با golang بسیار به‌کار می‌رود. + +مثال زیر یک فایل TOML معتبر را نمایش می‌دهد: + +```toml +[database] +server = "localhost" +port = 3306 +user = "username" +password = "password" +database = "myDB" +``` + +در این مثال، تمام اطلاعات پیکربندی مربوط به یک پایگاه‌داده وجود دارد (server، port، user و غیره)، و به صورت مشخصی تعریف شده‌اند، به طوری که برای برنامه‌نویسی با استفاده از این پیکربندی بسیار سرعت‌بخش خواهد بود. از آنجا که فایل TOML قابل‌خواندی و ویرایش توسط انسان است، برنامه‌نویسی با این نوع فایل‌ها آسان و قابل فهم خواهد بود. + +## 4.9.2 کار با marshal و unmarshal پکیج toml + +پکیج `toml` در زبان Go، حاوی توابع `Marshal` و `Unmarshal` برای تبدیل داده‌های Go به فرمت TOML و برعکس می‌باشد. + +### 4.9.2.1 Marshal + +تابع `Marshal` برای تبدیل یک متغیر ساخته شده در Go به فرمت TOML مورد استفاده قرار می‌گیرد. برای استفاده از این تابع، باید داده‌های خود را به یک متغیر با نوع `interface{}` تبدیل کنید و سپس این متغیر را به تابع `Marshal` بدهید. + +به عنوان مثال، برای تبدیل داده‌های `map[string]interface{}` به فرمت TOML، می‌توانید این کد را به کار ببرید: + +```go +package main + +import ( + "github.com/BurntSushi/toml" + "fmt" +) + +func main() { + data := map[string]interface{}{ + "name": "John", + "email": "john@example.com", + "age": 22, + } + tomlData, err := toml.Marshal(data) + if err != nil { + panic(err) + } + fmt.Println(string(tomlData)) +} +``` + +این کد یک دیکشنری ساده را تعریف می‌کند و سپس آن را به فرمت TOML تبدیل می‌کند. خروجی به صورت زیر خواهد بود: + +```shell +$ go run main.go +age = 22 +email = "john@example.com" +name = "John" +``` + +### 4.9.2.2 Unmarshal + +تابع `Unmarshal`، برای تبدیل یک رشته فرمت TOML به داده‌های Go استفاده می‌شود. برای استفاده از این تابع، باید با استفاده از تابع `ioutil.ReadFile`، فایل TOML مورد نظر را بخوانید و سپس رشته خوانده‌شده را به تابع `Unmarshal` بدهید. + +به عنوان مثال، برای خواندن یک فایل TOML و تبدیل آن به یک دیکشنری در Go، می‌توانید این کد را به کار ببرید: + +```go +package main + +import ( + "github.com/BurntSushi/toml" + "fmt" + "io/ioutil" +) + +type Person struct { + Name string + Email string + Age int +} + +func main() { + data, err := ioutil.ReadFile("file.toml") + if err != nil { + panic(err) + } + + var person Person + if _, err := toml.Decode(string(data), &person); err != nil { + panic(err) + } + + fmt.Printf("%#v\n", person) +} +``` + +این کد یک فایل TOML با فرمت زیر را می‌خواند و مقادیر موجود در آن را به داده‌های Go مناسب تبدیل می‌کند: + +```toml +name = "John" +email = "john@example.com" +age = 22 +``` + +خروجی به صورت زیر خواهد بود: + +```shell +$ go run main.go +main.Person{Name:"John", Email:"john@example.com", Age:22} +``` + +## 4.9.3 تبدیل struct به toml و بلعکس + +برای تبدیل یک `struct` به فرمت TOML و بلعکس، می‌توان از تابع‌های `Marshal` و `Unmarshal` پکیج `toml` استفاده کرد. در این روش، فیلدهای `struct` بر اساس نام آن‌ها و به صورت حروف کوچک در فایل TOML با نام فیلد متناظر ذخیره می‌شوند. + +همچنین می‌توان از تگ‌ها در داخل `struct` برای تعیین نام فیلد در فایل TOML استفاده کرد. با استفاده از تگ `toml:"name"` می‌توان نامی دلخواه برای فیلد در فایل TOML مشخص کرد. همچنین می‌توان از تگ‌های دیگری مانند `toml:"omitempty"` برای اجباری نبودن یک فیلد در فایل TOML استفاده کرد. + +به عنوان مثال، فرض کنید یک `struct` به نام `Person` با فیلدهای `Name`، `Email`و `Age` داریم. با استفاده از تگ‌ها، نام فیلدها در فایل TOML و پیش‌فرض برای آن‌ها مشخص می‌شود. + +```go +package main + +import ( + "github.com/BurntSushi/toml" + "fmt" +) + +type Person struct { + Name string `toml:"name"` + Email string `toml:"email,omitempty"` + Age int `toml:"age"` +} + +func main() { + // Marshaling from struct to TOML + person := Person{Name: "John", Age: 30} + tomlData, err := toml.Marshal(person) + if err != nil { + panic(err) + } + fmt.Println(string(tomlData)) + + // Unmarshaling from TOML to struct + var p Person + if _, err := toml.Decode(string(tomlData), &p); err != nil { + panic(err) + } + fmt.Printf("%#v\n", p) +} +``` + +در این مثال، `struct` با نام `Person` تعریف شده و از تگ برای نام‌گذاری فیلدها استفاده شده است. در تابع `main`، ابتدا از متد `Marshal` پکیج `toml` برای تبدیل یک شیء `Person` به فرمت TOML استفاده شده است. سپس با استفاده از متد `Decode` از پکیج `toml`، فایل TOML به داخل شیء `Person` تبدیل می‌شود. + +خروجی کد بالا به صورت زیر است: + +```shell +$ go run main.go +name = "John" +age = 30 + +main.Person{Name:"John", Email:"", Age:30} +``` + +همان‌طور که مشاهده می‌کنید، نام فیلدها در فایل TOML با تگ‏های تعیین‌شده در `struct` مطابقت می‌کند. همچنین با توجه به تگ `omitempty` که در فیلد `Email` وجود دارد، این فیلد در فایل TOML نمایش داده نشده است، چرا که در شی `person` مقداری برای آن تعریف نشده بود. +