Current section
Files
Jump to
Current section
Files
src/midas/sdk/accu_weather/forecast.gleam
import gleam/bit_array
import gleam/dynamic
import gleam/http/request
import gleam/http/response
import gleam/json
import gleam/result.{try}
import gleam/string
import midas/task as t
import snag
const api_host = "dataservice.accuweather.com"
fn get(api_key, path, params) {
request.new()
|> request.set_host(api_host)
|> request.set_path(path)
|> request.set_query([#("apikey", api_key), ..params])
|> request.set_body(<<>>)
}
pub fn five_day_forecast(api_key, location) {
let request = five_day_forecast_request(api_key, location)
use response <- t.do(t.fetch(request))
use response <- t.try(five_day_forecast_response(response))
t.Done(response)
}
pub fn five_day_forecast_request(api_key, location) {
let path = "/forecasts/v1/daily/5day/" <> location
get(api_key, path, [#("metric", "true"), #("details", "true")])
}
pub fn five_day_forecast_response(response: response.Response(BitArray)) {
use json <- try(
bit_array.to_string(response.body)
|> result.replace_error(snag.new("not utf8 encoded")),
)
let decoder =
dynamic.field("DailyForecasts", dynamic.list(daily_forcast_decoder))
use message <- try(
json.decode_bits(response.body, decoder)
|> result.map_error(fn(reason) {
snag.new(string.inspect(reason))
|> snag.layer("failed to decode message")
}),
)
Ok(message)
}
pub type DailyForecast {
DailyForecast(
date: String,
sunrise: String,
sunset: String,
minimum_temperature: Float,
maximum_temperature: Float,
day: Detail,
night: Detail,
)
}
pub fn daily_forcast_decoder(raw) {
dynamic.decode7(
DailyForecast,
dynamic.field("Date", dynamic.string),
dynamic.field("Sun", dynamic.field("Rise", dynamic.string)),
dynamic.field("Sun", dynamic.field("Set", dynamic.string)),
dynamic.field(
"Temperature",
dynamic.field("Minimum", dynamic.field("Value", dynamic.float)),
),
dynamic.field(
"Temperature",
dynamic.field("Maximum", dynamic.field("Value", dynamic.float)),
),
dynamic.field("Day", detail_decoder),
dynamic.field("Night", detail_decoder),
)(raw)
}
pub type Detail {
Detail(
precipitation_probability: Int,
wind_speed: Float,
wind_direction: String,
)
}
fn detail_decoder(raw) {
dynamic.decode3(
Detail,
dynamic.field("PrecipitationProbability", dynamic.int),
dynamic.field(
"Wind",
dynamic.field("Speed", dynamic.field("Value", dynamic.float)),
),
dynamic.field(
"Wind",
dynamic.field("Direction", dynamic.field("English", dynamic.string)),
),
)(raw)
}