کتابخانه‌ی استاندارد · کدگذاری و داده

تامل encoding/toml

خواندن و نوشتن پرونده‌های پیکربندی TOML.

واردسازی کدگذاری.تامل

TOML قالب پیکربندی‌ای است با جدول‌های [بخش] و سطرهای کلید = مقدار که در Cargo.toml، pyproject.toml و پیکربندی بسیاری از سرورها به کار می‌رود. این بسته متن TOML را به یک مقدار پویا تبدیل می‌کند و مقدار را دوباره به TOML می‌نویسد. پنج تابع دارد: کدگشایی سخت گیرانه، کدگشایی و معتبر برای خواندن، و کدگذاری سخت گیرانه و کدگذاری برای نوشتن.

TOML برای پرونده‌هایی مناسب است که آدم‌ها با دست ویرایش می‌کنند. برای داده‌ای که برنامه‌ها با هم رد و بدل می‌کنند جیسون بهتر است، برای پرونده‌های YAML مثل پیکربندی CI یا کوبرنتیز یامل، و برای پرونده‌های رمز به شکل KEY=value بسته‌ی پرونده محیط. اگر فقط می‌خواهید تنظیم‌ها را با مقدار پیش‌فرض و جایگزینی از متغیرهای محیطی بخوانید، شاید بسته‌ی پیکربندی همین کار را انجام دهد.

هر بخش TOML به چه مقداری تبدیل می‌شود

TOMLمقدار
[table]، [a.b]، جدول درون‌خطی { k = v }، کلید نقطه‌دار a.b = 1شیء (تودرتو)
[[name]]آرایه‌ای از شیء‌ها
"basic" با نویسه‌های گریز، 'literal'رشته
42، -7، 1_000، 0x1F، 0o17، 0b101صحیح (۶۴ بیتی)
3.5، 1e6، inf، nanاعشاری
true، falseمنطقی
تاریخ و زمان، مثل 1979-05-27T07:32:00Zرشته، بدون تغییر

اشتباه‌های رایج

  • برای پرونده‌هایی که آدم‌ها ویرایش می‌کنند کدگشایی سخت گیرانه را به کار ببرید، نه کدگشایی. کدگشایی هیچ خطایی گزارش نمی‌کند و روی ورودی خراب فقط آنچه را تا پیش از اشتباه خوانده برمی‌گرداند؛ یعنی یک غلط تایپی بی‌صدا بقیه‌ی پرونده را حذف می‌کند.
  • تجزیه‌گر سخت‌گیر نیست. نحو را بررسی می‌کند، نه همه‌ی قاعده‌های مشخصات TOML را. کلید یا [جدول]ی که دو بار تعریف شود پذیرفته می‌شود (جدول‌ها با هم ادغام می‌شوند و کلید دوم برنده است)، و واژه‌ی بی‌نقل‌قولی مثل mode = fast به جای رد شدن، رشته‌ی "fast" خوانده می‌شود.
  • بخشی از نحو پشتیبانی نمی‌شود. رشته‌ی چندخطی با سه نقل‌قول (""" یا ''') سند را نامعتبر می‌کند و نویسه‌ی گریز هشت‌رقمی \U کدگشایی نمی‌شود. تاریخ‌ها رشته می‌مانند؛ اگر لازمشان دارید با بسته‌ی زمان تجزیه‌شان کنید.
  • نوشتن، قالب‌بندی نیست. کدگذاری کلیدها را به ترتیب ثابتی نمی‌نویسد، کلیدهای تهی را کنار می‌گذارد و آرایه‌ی شیء‌ها را به شکل آرایه‌ی درون‌خطی [{...}, {...}] می‌نویسد، نه بلوک‌های [[table]]. خروجی TOML درستی است و دوباره به همان داده خوانده می‌شود، ولی توضیح‌ها و چینش پرونده‌ی اصلی از دست می‌روند.

راهنما: خواندن مانیفست یک پروژه

پرونده‌های پروژه مثل Cargo.toml یا pyproject.toml جدول ساده، جدول درون‌خطی و آرایه‌ی جدول را با هم دارند. کدگشایی سخت گیرانه کل پرونده را در یک مقدار می‌خواند و با ok می‌گوید معتبر بوده یا نه؛ از آن به بعد تابع‌های بسته‌ی مقدار آن را می‌پیمایند.

encoding-toml-guide-manifest.salam
واردسازی کدگذاری.تامل
واردسازی کدگذاری.مقدار
واردسازی مرتب سازی

تابع ریشه:
    متن := `[package]
name = "shop"
version = "1.4.0"
authors = ["Sara", "Reza"]

[dependencies]
http = "2.1"
json = { version = "1.0", optional = true }
log = "0.9"

[[bin]]
name = "shop"
path = "src/main.salam"

[[bin]]
name = "shop-admin"
path = "src/admin.salam"
`
    ناپایا سالم := نادرست
    سند := تامل.کدگشایی سخت گیرانه(متن، سالم)
    اگر وارونه سالم:
        سرچاپ "تامل معتبر نیست"
        برگشت ۱
    پایان
    مشخصات := مقدار.مقدار کلید(سند، "package")
    سرچاپ مقدار.به رشته(مقدار.مقدار کلید(مشخصات، "name"))، مقدار.به رشته(مقدار.مقدار کلید(مشخصات، "version"))
    سرچاپ "نویسندگان:"، مقدار.طول آرایه(مقدار.مقدار کلید(مشخصات، "authors"))

    وابستگی‌ها := مقدار.مقدار کلید(سند، "dependencies")
    نام‌ها := مقدار.کلیدهای شیء(وابستگی‌ها)
    مرتب سازی.مرتب سازی سریع(نام‌ها)
    هر نام در نام‌ها:
        وابستگی := مقدار.مقدار کلید(وابستگی‌ها، نام)
        اگر مقدار.رشته است(وابستگی):
            سرچاپ "وابستگی"، نام، مقدار.به رشته(وابستگی)
        وگرنه:
            سرچاپ "وابستگی"، نام، مقدار.به رشته(مقدار.مقدار کلید(وابستگی، "version"))، "(اختیاری)"
        پایان
    پایان

    برنامه‌ها := مقدار.مقدار کلید(سند، "bin")
    تکرار مقدار.طول آرایه(برنامه‌ها) در ای:
        ب := مقدار.عضو آرایه(برنامه‌ها، ای)
        سرچاپ "برنامه"، مقدار.به رشته(مقدار.مقدار کلید(ب، "name"))، "از"، مقدار.به رشته(مقدار.مقدار کلید(ب، "path"))
    پایان
پایان
خروجیshop 1.4.0 نویسندگان: 2 وابستگی http 2.1 وابستگی json 1.0 (اختیاری) وابستگی log 0.9 برنامه shop از src/main.salam برنامه shop-admin از src/admin.salam

یک وابستگی ممکن است رشته‌ی ساده‌ی نسخه باشد یا جدولی درون‌خطی با جزئیات بیشتر، پس برنامه پیش از خواندن با رشته است می‌پرسد. شیء‌ها ترتیب کلیدهایشان را نگه نمی‌دارند؛ مرتب کردن کلیدهای شیء با مرتب سازی.مرتب سازی سریع فهرستی پایدار می‌دهد.

راهنما: تامل در یک ساختار

تنظیم‌هایی را که در همه‌جای برنامه به کار می‌برید یک بار در یک ساختار بارگذاری کنید. مقدار کدگشایی‌شده را با جیسون.کدگذاری پیش فرض به جیسون تبدیل کنید و بگذارید جیسون.واسریال سازی آسان گیر ساختار را پر کند: کلیدهایی که پرونده ندارد پیش‌فرض ساختار را نگه می‌دارند و جدول [server] یک ساختار تودرتو را پر می‌کند.

encoding-toml-guide-struct.salam
واردسازی کدگذاری.تامل
واردسازی کدگذاری.جیسون
واردسازی کدگذاری.خطای کدگذاری

ساختار کارساز:
    @جیسون "host"
    همگانی میزبان: رشته = "127.0.0.1"
    @جیسون "port"
    همگانی درگاه: صحیح = ۸۰۰۰
پایان

ساختار تنظیمات:
    @جیسون "title"
    همگانی عنوان: رشته = ""
    @جیسون "debug"
    همگانی اشکال زدایی: منطقی = نادرست
    @جیسون "server"
    همگانی کارساز اصلی: کارساز = کارساز {}
    @جیسون "allowed"
    همگانی مجاز: وکتور<رشته> = وکتور {}
پایان

تابع ریشه:
    متن := `title = "Shop admin"
allowed = ["10.0.0.0/8", "192.168.1.0/24"]

[server]
port = 9090
`
    ناپایا سالم := نادرست
    سند := تامل.کدگشایی سخت گیرانه(متن، سالم)
    ناپایا ت := تنظیمات {}
    ناپایا خطا := خطای کدگذاری.بدون خطا()
    اگر وارونه سالم یا وارونه جیسون.واسریال سازی آسان گیر(جیسون.کدگذاری پیش فرض(سند)، ت، خطا):
        سرچاپ "تنظیمات خراب است"
        برگشت ۱
    پایان
    سرچاپ ت.عنوان، "اشکال‌زدایی:"، ت.اشکال زدایی
    سرچاپ "گوش دادن روی"، ت.کارساز اصلی.میزبان، ت.کارساز اصلی.درگاه
    سرچاپ "شبکه‌های مجاز:"، ت.مجاز.طول()، ت.مجاز.بگیر(۰)
پایان
خروجیShop admin اشکال‌زدایی: false گوش دادن روی 127.0.0.1 9090 شبکه‌های مجاز: 2 10.0.0.0/8

راهنما: نوشتن پرونده‌ی تامل

برای نوشتن تامل، یک شیء مقدار بسازید و به کدگذاری یا کدگذاری سخت گیرانه بدهید. شیء تودرتو یک [جدول] می‌شود. بالاترین سطح باید شیء باشد، چون سند تامل همیشه یک جدول است؛ کدگذاری سخت گیرانه برای هر چیز دیگری نادرست گزارش می‌کند.

encoding-toml-guide-write.salam
واردسازی کدگذاری.تامل
واردسازی کدگذاری.مقدار

تابع نسخه پشتیبان(میزبان: رشته، وزن: صحیح): مقدار.مقدار:
    ناپایا نسخه := مقدار.شیء جدید()
    مقدار.تنظیم کلید(نسخه، "host"، مقدار.مقدار رشته(میزبان))
    مقدار.تنظیم کلید(نسخه، "weight"، مقدار.مقدار صحیح(وزن))
    برگشت نسخه
پایان

تابع ریشه:
    ناپایا پایگاه := مقدار.شیء جدید()
    مقدار.تنظیم کلید(پایگاه، "url"، مقدار.مقدار رشته("postgres://localhost/shop"))
    مقدار.تنظیم کلید(پایگاه، "pool"، مقدار.مقدار صحیح(۸))
    مقدار.تنظیم کلید(پایگاه، "timeout"، مقدار.مقدار اعشاری(۳۰.۰))
    مقدار.تنظیم کلید(پایگاه، "password"، مقدار.مقدار تهی())

    ناپایا نسخه‌ها := مقدار.آرایه جدید()
    مقدار.افزودن به آرایه(نسخه‌ها، نسخه پشتیبان("10.0.0.2"، ۲))
    مقدار.افزودن به آرایه(نسخه‌ها، نسخه پشتیبان("10.0.0.3"، ۱))
    مقدار.تنظیم کلید(پایگاه، "replicas"، نسخه‌ها)

    ناپایا ریشه داده := مقدار.شیء جدید()
    مقدار.تنظیم کلید(ریشه داده، "database"، پایگاه)

    ناپایا شد := نادرست
    متن := تامل.کدگذاری سخت گیرانه(ریشه داده، شد)
    سرچاپ "کدگذاری شد:"، شد
    چاپ متن

    برگشتی := مقدار.مقدار کلید(تامل.کدگشایی(متن)، "database")
    سرچاپ "timeout هنوز اعشاری است:"، مقدار.اعشاری است(مقدار.مقدار کلید(برگشتی، "timeout"))
    سرچاپ "password نوشته شد:"، مقدار.شیء دارد(برگشتی، "password")
    سرچاپ "نسخه‌های پشتیبان خوانده‌شده:"، مقدار.طول آرایه(مقدار.مقدار کلید(برگشتی، "replicas"))
پایان
خروجیکدگذاری شد: true [database] url = "postgres://localhost/shop" pool = 8 timeout = 30.0 replicas = [{host = "10.0.0.2", weight = 2}, {host = "10.0.0.3", weight = 1}] timeout هنوز اعشاری است: true password نوشته شد: false نسخه‌های پشتیبان خوانده‌شده: 2

در خروجی سه چیز دیده می‌شود. password که تهی است نوشته نشده، چون TOML مقدار تهی ندارد. آرایه‌ی شیء‌های نسخه‌ی پشتیبان در یک سطر و درون‌خطی نوشته شده است. عدد اعشاری 30.0 رقم .0 خود را نگه داشته، پس دوباره اعشاری خوانده می‌شود و نه عدد صحیح 30. کلیدها به ترتیب مشخصی نوشته نمی‌شوند، پس هرگز متن را با یک رشته‌ی ثابت مقایسه نکنید؛ داده را مقایسه کنید، مثلاً با مقدار.یکسان است پس از کدگشایی دوباره‌ی متن.

راهنما: گرفتن اشتباه‌ها

روی هر پرونده‌ای که آدم‌ها ویرایش می‌کنند کدگشایی سخت گیرانه یا معتبر را به کار ببرید. این دو نحو خراب را می‌گیرند: کلید بی‌مقدار، رشته یا آرایه یا سرجدولی که بسته نشده است.

encoding-toml-guide-errors.salam
واردسازی کدگذاری.تامل

تابع بررسی(برچسب: رشته، متن: رشته):
    ناپایا سالم := نادرست
    _ := تامل.کدگشایی سخت گیرانه(متن، سالم)
    سرچاپ برچسب، سالم
پایان

تابع ریشه:
    بررسی("درست:              "، "a = 1\nb = 'two'\n")
    بررسی("بی مقدار:          "، "a = \n")
    بررسی("رشته‌ی بسته‌نشده:  "، "a = \"open\n")
    بررسی("آرایه‌ی بسته‌نشده: "، "a = [1, 2\n")
    بررسی("جدول بسته‌نشده:    "، "[server\nport = 1\n")
    بررسی("متن چندخطی:        "، "a = \"\"\"x\"\"\"\n")
    بررسی("کلید تکراری:       "، "a = 1\na = 2\n")
    بررسی("رشته‌ی بی‌نقل‌قول:  "، "mode = fast\n")
    سرچاپ "معتبر هم همین را می‌گوید:"، تامل.معتبر("a = 1")، تامل.معتبر("a = ")
پایان
خروجیدرست: true بی مقدار: false رشته‌ی بسته‌نشده: false آرایه‌ی بسته‌نشده: false جدول بسته‌نشده: false متن چندخطی: false کلید تکراری: true رشته‌ی بی‌نقل‌قول: true معتبر هم همین را می‌گوید: true false

دو سطر آخر همان سهل‌گیری‌ای است که بالاتر گفته شد: کلید تکراری پذیرفته می‌شود و مقدار دوم برنده است، و mode = fast به شکل رشته‌ی "fast" قبول می‌شود، در حالی که TOML واقعی نقل‌قول می‌خواهد. اگر هر کدام از این‌ها ممکن است اشتباه واقعی‌ای را در پرونده‌های شما پنهان کند، پس از کدگشایی کلیدهای مهم را خودتان بررسی کنید، مثلاً با مقدار.رشته است و فهرستی از مقدارهای مجاز.

تابع‌ها

کدگشایی سخت گیرانه DecodeStrict

تابع کدگشایی سخت گیرانه(text: رشته، ok &: منطقی): value.Value
TOML را می‌خواند؛ اگر متن نادرست باشد، ok را نادرست می‌کند.
encoding-toml-Decode.salam
واردسازی کدگذاری.تامل
واردسازی کدگذاری.مقدار

تابع ریشه:
    متن := "title = \"سلام\"\n\n[server]\nhost = \"localhost\"\nport = 8080\ntags = [\"a\", \"b\"]\n"
    سرچاپ تامل.معتبر(متن)، تامل.معتبر("= بدون کلید")
    م := تامل.کدگشایی(متن)
    س := مقدار.مقدار کلید(م، "server")
    سرچاپ مقدار.به رشته(مقدار.مقدار کلید(م، "title"))، مقدار.به صحیح(مقدار.مقدار کلید(س، "port"))
    سرچاپ تامل.کدگذاری(م)
    ناپایا خوانده شد := نادرست
    _ := تامل.کدگشایی سخت گیرانه("a = \n"، خوانده شد)
    سرچاپ خوانده شد
    ناپایا نوشت := نادرست
    سرچاپ تامل.کدگذاری سخت گیرانه(مقدار.مقدار صحیح(۱)، نوشت)، نوشت
پایان
خروجیtrue false سلام 8080 title = "سلام" [server] host = "localhost" port = 8080 tags = ["a", "b"] false false

کدگشایی Decode

تابع کدگشایی(text: رشته): value.Value
TOML را بدون گزارش خطا به مقدار تبدیل می‌کند: روی متن نادرست آنچه را تا پیش از خطا خوانده شده برمی‌گرداند، پس برای پرونده‌هایی که آدم‌ها ویرایش می‌کنند کدگشایی سخت گیرانه بهتر است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: encoding-toml-Decode.salam

معتبر Valid

تابع معتبر(text: رشته): منطقی
اگر متن TOML درستی باشد، درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: encoding-toml-Decode.salam

کدگذاری سخت گیرانه EncodeStrict

تابع کدگذاری سخت گیرانه(v: value.Value، ok &: منطقی): رشته
مقدار را به TOML تبدیل می‌کند. اگر سطح بالا شیء نباشد یا آرایه‌ای مقدار تهی داشته باشد، ok نادرست می‌شود؛ کلیدهای تهی در جدول کنار گذاشته می‌شوند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: encoding-toml-Decode.salam

کدگذاری Encode

تابع کدگذاری(v: value.Value): رشته
مقدار را بی‌توجه به مشکل‌ها به TOML تبدیل می‌کند؛ اگر سطح بالا شیء نباشد، رشته‌ی خالی برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: encoding-toml-Decode.salam