summaryrefslogtreecommitdiffstats
path: root/nws/nws.go
diff options
context:
space:
mode:
Diffstat (limited to 'nws/nws.go')
-rw-r--r--nws/nws.go72
1 files changed, 72 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
+}