weather.ry
module weather
purpose: Show the current temperature for Berlin using the Open-Meteo API.
import std.console
import std.http exposing Url, HttpError
import std.json exposing JsonError
type CurrentWeather
has temperature_2m: Decimal
has wind_speed_10m: Decimal
can FromJson
end
type Forecast
has current: CurrentWeather
can FromJson
end
public type WeatherError is one of
purpose: Why a forecast could not be shown.
Unreachable(detail: Text)
BadResponse(detail: Text)
end
public function fetch_forecast(latitude: Decimal, longitude: Decimal)
returns Forecast
or fails with HttpError or JsonError
needs network.http("api.open-meteo.com")
purpose: Download the current weather for one coordinate.
tags: weather, http, json
let base be "https://api.open-meteo.com/v1/forecast"
let query be "latitude={latitude}&longitude={longitude}¤t=temperature_2m,wind_speed_10m"
let url be Url("{base}?{query}")
let response be http.get(url) otherwise fail
let forecast: Forecast be json.parse(response.body) otherwise fail
return forecast
end
public function main() or fails with WeatherError needs console, network.http
purpose: Print the temperature and wind speed in Berlin.
let forecast be
match fetch_forecast(latitude: 52.52, longitude: 13.41)
when success(result) then result
when failure(error: HttpError) then fail with Unreachable(detail: error.to_text())
when failure(error: JsonError) then fail with BadResponse(detail: error.to_text())
end
let current be forecast.current
console.print("Berlin: {current.temperature_2m} C, wind {current.wind_speed_10m} km/h")
end
test "Berlin is read" needs network.http("api.open-meteo.com") replays "fixtures/weather.json"
let forecast be fetch_forecast(latitude: 52.52, longitude: 13.41) otherwise fail
check forecast.current.temperature_2m is 14.0
check forecast.current.wind_speed_10m is 5.5
end