[بازوها در *بله*](https://devbale.ir/) برای این که بتوانند درخواستهایشان را مطرح کنند از *JSON* استفاده میکنند، اما درخواستهایشان از قاعدهی خاصی پیروی نمیکند. *بله* که از این وضعیت خسته شده، از شما خواسته تا این درخواستها را برایش ترجمه کنید و در قالب یک ساختار مشخص به او بدهید.
# جزئیات پروژه
پروژهی اولیه را از [این لینک](/contest/assignments/31741/download_problem_initial_project/104104/) دانلود کنید.
در این سؤال شما باید یک فایل *JSON* را که در کنار فایل اجرایی قرار دارد بخوانید و آن را تبدیل به ساختار `SendMessage` کنید.
فیلدهای *JSON* ورودی بهشرح زیر هستند:
+ **فیلد** `chat_id` : این فیلد یک عدد صحیح ۶۴ بیتی است که در ورودی میتواند بهصورت **عدد** یا **رشته** داده شود. در ساختار خروجی، این فیلد باید دارای نوع **رشته** باشد. برای مثال در ورودی، این فیلد میتواند به صورت `123` و یا `"123"` داده شود، و مقداری که در ساختار برای این فیلد ذخیره میشود بهصورت `"123"` است. این فیلد حتماً باید در فایل ورودی وجود داشته باشد و در غیر اینصورت، باید ارور با پیام `chat_id is empty` برگردانید.
+ **فیلد** `text`: این فیلد مشخصکنندهی متن پیام بوده و از نوع **رشته** است. این فیلد نیز حتماً باید در ورودی وجود داشته باشد و رشتهی خالی نباشد. در غیر اینصورت، باید ارور با پیام `text is empty` را برگردانید.
+ **فیلد** `parse_mode`: این فیلد از نوع رشته است، اما میتواند در *JSON* ورودی نباشد (فیلدی ضروری نیست).
+ **فیلد** `reply_markup`: این فیلد از نوع `ReplyMarkup` بوده و فیلدی ضروری نیست و میتواند در ورودی نباشد. مقدار این فیلد، خود یک *object* است که حالتهای زیر را میتواند داشته باشد:
```json
{
"keyboard" : [[{"text" : string, "request_contact" : bool, "request_location" : bool}]]
"resize_keyboard" : bool
"one_time_keyboard" : bool
"selective" : bool
}
```
در این حالت، سه مقدار `resize_keyboard` و `one_time_keyboard` و `selective` از نوع *bool* هستند و فیلدهای ضروری نیستند. `keyboard` در این حالت فیلدی ضروری است و مقدار آن آرایهای از آرایههایی است که هر عنصر آن یک *object* با سه فیلد `text` و `request_contact` و `request_location` است. فیلدهای `request_location` و `request_contact` از نوع *bool* بوده و اجباری نیستند.
```json
{
"keyboard" : [[string, string]]
"resize_keyboard" : bool
"one_time_keyboard" : bool
"selective" : bool
}
```
تفاوت این حالت با حالت قبلی، تنها در این است که در این حالت، مقدار `keyboard` به صورت آرایهای از آرایههایی است که هر عنصر آن یک رشته است. در این حالت، هر رشته باید بهعنوان مقدار برای کلید `text` درنظر گرفته شود.
```json
{
"inline_keyboard" : [[{"text" : string, "callback_data" : string, "url" : string}]]
}
```
در این حالت، یک فیلد ضروری `inline_keyboard` داده میشود که آرایهای از آرایههایی است که هر عنصر آن یک *object* است که در آن سه فیلد `text` و `callback_data` و `url` قرار دارد. دو فیلد `callback_data` و `url` ضروری نیستند.
```json
{
"inline_keyboard" : [[string, string]]
}
```
تفاوت این حالت با حالت قبلی، تنها در این است که در این حالت، مقدار `inline_keyboard` بهصورت آرایهای از آرایههایی است که هر عنصر آن یک رشته است. در این حالت، هر رشته باید بهعنوان مقدار برای کلید `text` در نظر گرفته شود.
توجه داشته باشید که هر یک از حالتهای بالا میتوانند در *JSON* ورودی به صورت **رشته** باشد. برای مثال، حالت دوم می تواند در فایل ورودی بهصورت زیر باشد:
```json
"{\"keyboard\" : [[\"string\",\"string\"], [\"string\", \"string\"]]}"
```
تابع `ReadSendMessageRequest(fileName string)` را بهگونهای پیاده کنید که نام فایل را بهعنوان ورودی دریافت کرده و *JSON* درون فایل را به ساختار `SendMessage` تبدیل کند. اگر خطایی وجود نداشت (تنها دو خطای گفتهشده با متن خطای مشخصشده ممکن است رخ دهد و خطای دیگری وجود ندارد)، یک اشارهگر به این ساختار برگردانید و مقدار ارور را نیز `nil` برگردانید. در صورت وجود خطا، مقدار اشارهگر را `nil` و مقدار ارور را با خطای مناسب برگردانید.
# آنچه باید آپلود کنید
پس از پیادهسازی موارد خواسته شده، فایل `main.go` را آپلود کنید. در صورتی که از _dependency_ خاصی استفاده کردهاید، فایلهای `go.mod` و `go.sum` را بههمراه فایل `main.go` زیپ کرده و آن را آپلود کنید.