summaryrefslogtreecommitdiffstats
path: root/nws
diff options
context:
space:
mode:
authorsiddharth <s@ricketyspace.net>2022-05-08 22:27:46 -0400
committersiddharth <s@ricketyspace.net>2022-05-08 22:27:46 -0400
commit4ef093d212abb22fbc87a6f9b8a06f5224677658 (patch)
treed13bfc1474ed940deb37aa9793f1e2ce36173b74 /nws
parent12d34c44c96c9289b67bdfbad131edf8f2cd74f8 (diff)
add nws package
Diffstat (limited to 'nws')
-rw-r--r--nws/nws.go72
-rw-r--r--nws/nws_test.go26
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)
+ }
+}