diff options
Diffstat (limited to 'nws')
-rw-r--r-- | nws/nws.go | 72 | ||||
-rw-r--r-- | nws/nws_test.go | 26 |
2 files changed, 98 insertions, 0 deletions
diff --git a/nws/nws.go b/nws/nws.go new file mode 100644 index 0000000..02b4d75 --- /dev/null +++ b/nws/nws.go @@ -0,0 +1,72 @@ +// Copyright © 2022 siddharth <s@ricketyspace.net> +// SPDX-License-Identifier: ISC + +// Functions for accessing the National Weather Service API. +package nws + +import ( + "encoding/json" + "fmt" + "io" + + "ricketyspace.net/peach/client" +) + +type NWSPointProperties struct { + ForecastLink string `json:"forecast"` + ForecastHourlyLink string `json:"forecastHourly"` +} + +type NWSPoints struct { + Properties NWSPointProperties +} + +type NWSPointsError struct { + Title string + Type string + Status int + Detail string +} + +func (e NWSPointsError) Error() string { + return fmt.Sprintf("%d: %s: %s", e.Status, e.Type, e.Detail) +} + +// NWS API's `/points` endpoint. +func points(lat, lng float32) (*NWSPoints, error) { + url := fmt.Sprintf("https://api.weather.gov/points/%.4f,%.4f", lat, lng) + resp, err := client.Get(url) + if err != nil { + return nil, fmt.Errorf("points: http get: %v", err) + } + + // Parse response body. + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("getting points: body: %v", err) + } + + // Check if the request failed. + if resp.StatusCode != 200 { + perr := new(NWSPointsError) + err := json.Unmarshal(body, perr) + if err != nil { + return nil, fmt.Errorf("points: json: %v", err) + } + return nil, fmt.Errorf("points: %v", perr) + } + + // Unmarshal. + points := new(NWSPoints) + err = json.Unmarshal(body, points) + if err != nil { + return nil, fmt.Errorf("getting points: json decode: %v", err) + } + if points.Properties.ForecastLink == "" { + return nil, fmt.Errorf("points: json: %v", err) + } + if points.Properties.ForecastHourlyLink == "" { + return nil, fmt.Errorf("points: json: %v", err) + } + return points, nil +} diff --git a/nws/nws_test.go b/nws/nws_test.go new file mode 100644 index 0000000..8c52c25 --- /dev/null +++ b/nws/nws_test.go @@ -0,0 +1,26 @@ +// Copyright © 2022 siddharth <s@ricketyspace.net> +// SPDX-License-Identifier: ISC + +package nws + +import "testing" + +func TestPoints(t *testing.T) { + // Test valid lat,lng. + np, err := points(41.115, -83.177) + if err != nil { + t.Errorf("points: %v", err) + } + if np.Properties.ForecastLink != "https://api.weather.gov/gridpoints/CLE/33,42/forecast" { + t.Errorf("points: forcecast link: '%v'", np.Properties.ForecastLink) + } + if np.Properties.ForecastHourlyLink != "https://api.weather.gov/gridpoints/CLE/33,42/forecast/hourly" { + t.Errorf("points: forcecast link: '%v'", np.Properties.ForecastHourlyLink) + } + + // Test invalid lat,lng + np, err = points(115.0, -83.177) + if err == nil { + t.Errorf("points: %v", np) + } +} |