diff --git a/wsdlgen/testdata/output/TestElementWisePart.xml.golden b/wsdlgen/testdata/output/TestElementWisePart.xml.golden new file mode 100644 index 0000000..d3b168a --- /dev/null +++ b/wsdlgen/testdata/output/TestElementWisePart.xml.golden @@ -0,0 +1,95 @@ +// Code generated by wsdlgen.test. DO NOT EDIT. + +// Package ws +package ws + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" +) + +type Client struct { + HTTPClient *http.Client + ResponseHook func(*http.Response) *http.Response + RequestHook func(*http.Request) *http.Request +} +type soapEnvelope struct { + XMLName struct{} `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header []byte `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + Body struct { + Message interface{} + Fault *struct { + String string `xml:"faultstring,omitempty"` + Code string `xml:"faultcode,omitempty"` + Detail string `xml:"detail,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` +} + +func (c *Client) do(ctx context.Context, method, uri, action string, in, out interface{}) error { + var body io.Reader + var envelope soapEnvelope + if method == "POST" || method == "PUT" { + var buf bytes.Buffer + envelope.Body.Message = in + enc := xml.NewEncoder(&buf) + if err := enc.Encode(envelope); err != nil { + return err + } + if err := enc.Flush(); err != nil { + return err + } + body = &buf + } + req, err := http.NewRequest(method, uri, body) + if err != nil { + return err + } + req.Header.Set("SOAPAction", action) + req = req.WithContext(ctx) + if c.RequestHook != nil { + req = c.RequestHook(req) + } + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + rsp, err := httpClient.Do(req) + if err != nil { + return err + } + defer rsp.Body.Close() + if c.ResponseHook != nil { + rsp = c.ResponseHook(rsp) + } + dec := xml.NewDecoder(rsp.Body) + envelope.Body.Message = out + if err := dec.Decode(&envelope); err != nil { + return err + } + if envelope.Body.Fault != nil { + return fmt.Errorf("%s: %s", envelope.Body.Fault.Code, envelope.Body.Fault.String) + } + return nil +} +func (c *Client) MyServiceRequest(ctx context.Context, path string) (string, error) { + var input struct { + XMLName struct{} `xml:"tns MyServiceRequest"` + Args struct { + Path string `xml:"tns path"` + } `xml:"tns MyRequest"` + } + input.Args.Path = string(path) + var output struct { + XMLName struct{} `xml:"tns MyServiceRequest"` + Args struct { + Result string `xml:"tns result"` + } `xml:"tns MyResponse"` + } + err := c.do(ctx, "POST", "http://example.net/MyService", "MyServiceRequest", &input, &output) + return string(output.Args.Result), err +} diff --git a/wsdlgen/testdata/output/TestGlobalWeather.xml.golden b/wsdlgen/testdata/output/TestGlobalWeather.xml.golden new file mode 100644 index 0000000..d34f197 --- /dev/null +++ b/wsdlgen/testdata/output/TestGlobalWeather.xml.golden @@ -0,0 +1,250 @@ +// Code generated by wsdlgen.test. DO NOT EDIT. + +// Package ws +package ws + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" +) + +type GetCitiesByCountry struct { + CountryName string `xml:"http://www.webserviceX.NET CountryName,omitempty"` +} + +type GetCitiesByCountryResponse struct { + GetCitiesByCountryResult string `xml:"http://www.webserviceX.NET GetCitiesByCountryResult,omitempty"` +} + +type GetWeather struct { + CityName string `xml:"http://www.webserviceX.NET CityName,omitempty"` + CountryName string `xml:"http://www.webserviceX.NET CountryName,omitempty"` +} + +type GetWeatherResponse struct { + GetWeatherResult string `xml:"http://www.webserviceX.NET GetWeatherResult,omitempty"` +} +type Client struct { + HTTPClient *http.Client + ResponseHook func(*http.Response) *http.Response + RequestHook func(*http.Request) *http.Request +} +type soapEnvelope struct { + XMLName struct{} `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header []byte `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + Body struct { + Message interface{} + Fault *struct { + String string `xml:"faultstring,omitempty"` + Code string `xml:"faultcode,omitempty"` + Detail string `xml:"detail,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` +} + +func (c *Client) do(ctx context.Context, method, uri, action string, in, out interface{}) error { + var body io.Reader + var envelope soapEnvelope + if method == "POST" || method == "PUT" { + var buf bytes.Buffer + envelope.Body.Message = in + enc := xml.NewEncoder(&buf) + if err := enc.Encode(envelope); err != nil { + return err + } + if err := enc.Flush(); err != nil { + return err + } + body = &buf + } + req, err := http.NewRequest(method, uri, body) + if err != nil { + return err + } + req.Header.Set("SOAPAction", action) + req = req.WithContext(ctx) + if c.RequestHook != nil { + req = c.RequestHook(req) + } + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + rsp, err := httpClient.Do(req) + if err != nil { + return err + } + defer rsp.Body.Close() + if c.ResponseHook != nil { + rsp = c.ResponseHook(rsp) + } + dec := xml.NewDecoder(rsp.Body) + envelope.Body.Message = out + if err := dec.Decode(&envelope); err != nil { + return err + } + if envelope.Body.Fault != nil { + return fmt.Errorf("%s: %s", envelope.Body.Fault.Code, envelope.Body.Fault.String) + } + return nil +} + +// Get weather report for all major cities around the world. +func (c *Client) GetWeather(ctx context.Context, parameters GetWeather) (GetWeatherResponse, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Parameters GetWeather `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetWeatherSoapIn"` + } + input.Args.Parameters = GetWeather(parameters) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Parameters GetWeatherResponse `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetWeatherSoapOut"` + } + err := c.do(ctx, "POST", "http://www.webservicex.net/globalweather.asmx", "http://www.webserviceX.NET/GetWeather", &input, &output) + return GetWeatherResponse(output.Args.Parameters), err +} + +// Get all major cities by country name(full / part). +func (c *Client) GetCitiesByCountry(ctx context.Context, parameters GetCitiesByCountry) (GetCitiesByCountryResponse, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Parameters GetCitiesByCountry `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountrySoapIn"` + } + input.Args.Parameters = GetCitiesByCountry(parameters) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Parameters GetCitiesByCountryResponse `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountrySoapOut"` + } + err := c.do(ctx, "POST", "http://www.webservicex.net/globalweather.asmx", "http://www.webserviceX.NET/GetCitiesByCountry", &input, &output) + return GetCitiesByCountryResponse(output.Args.Parameters), err +} + +// Get weather report for all major cities around the world. +func (c *Client) GetWeather(ctx context.Context, parameters GetWeather) (GetWeatherResponse, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Parameters GetWeather `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetWeatherSoapIn"` + } + input.Args.Parameters = GetWeather(parameters) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Parameters GetWeatherResponse `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetWeatherSoapOut"` + } + err := c.do(ctx, "POST", "http://www.webservicex.net/globalweather.asmx", "", &input, &output) + return GetWeatherResponse(output.Args.Parameters), err +} + +// Get all major cities by country name(full / part). +func (c *Client) GetCitiesByCountry(ctx context.Context, parameters GetCitiesByCountry) (GetCitiesByCountryResponse, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Parameters GetCitiesByCountry `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountrySoapIn"` + } + input.Args.Parameters = GetCitiesByCountry(parameters) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Parameters GetCitiesByCountryResponse `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountrySoapOut"` + } + err := c.do(ctx, "POST", "http://www.webservicex.net/globalweather.asmx", "", &input, &output) + return GetCitiesByCountryResponse(output.Args.Parameters), err +} + +// Get weather report for all major cities around the world. +func (c *Client) GetWeather(ctx context.Context, CityName string, CountryName string) (string, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + CityName string `xml:"http://www.webserviceX.NET CityName"` + CountryName string `xml:"http://www.webserviceX.NET CountryName"` + } `xml:"http://www.webserviceX.NET GetWeatherHttpGetIn"` + } + input.Args.CityName = string(CityName) + input.Args.CountryName = string(CountryName) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Body string `xml:"http://www.webserviceX.NET Body"` + } `xml:"http://www.webserviceX.NET GetWeatherHttpGetOut"` + } + err := c.do(ctx, "GET", "", "", &input, &output) + return string(output.Args.Body), err +} + +// Get all major cities by country name(full / part). +func (c *Client) GetCitiesByCountry(ctx context.Context, CountryName string) (string, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + CountryName string `xml:"http://www.webserviceX.NET CountryName"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountryHttpGetIn"` + } + input.Args.CountryName = string(CountryName) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Body string `xml:"http://www.webserviceX.NET Body"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountryHttpGetOut"` + } + err := c.do(ctx, "GET", "", "", &input, &output) + return string(output.Args.Body), err +} + +// Get weather report for all major cities around the world. +func (c *Client) GetWeather(ctx context.Context, CityName string, CountryName string) (string, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + CityName string `xml:"http://www.webserviceX.NET CityName"` + CountryName string `xml:"http://www.webserviceX.NET CountryName"` + } `xml:"http://www.webserviceX.NET GetWeatherHttpPostIn"` + } + input.Args.CityName = string(CityName) + input.Args.CountryName = string(CountryName) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Body string `xml:"http://www.webserviceX.NET Body"` + } `xml:"http://www.webserviceX.NET GetWeatherHttpPostOut"` + } + err := c.do(ctx, "POST", "", "", &input, &output) + return string(output.Args.Body), err +} + +// Get all major cities by country name(full / part). +func (c *Client) GetCitiesByCountry(ctx context.Context, CountryName string) (string, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + CountryName string `xml:"http://www.webserviceX.NET CountryName"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountryHttpPostIn"` + } + input.Args.CountryName = string(CountryName) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Body string `xml:"http://www.webserviceX.NET Body"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountryHttpPostOut"` + } + err := c.do(ctx, "POST", "", "", &input, &output) + return string(output.Args.Body), err +} diff --git a/wsdlgen/testdata/output/TestGlobalWeatherPortFilter.xml.golden b/wsdlgen/testdata/output/TestGlobalWeatherPortFilter.xml.golden new file mode 100644 index 0000000..133f6f9 --- /dev/null +++ b/wsdlgen/testdata/output/TestGlobalWeatherPortFilter.xml.golden @@ -0,0 +1,132 @@ +// Code generated by wsdlgen.test. DO NOT EDIT. + +// Package ws +package ws + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" +) + +type GetCitiesByCountry struct { + CountryName string `xml:"http://www.webserviceX.NET CountryName,omitempty"` +} + +type GetCitiesByCountryResponse struct { + GetCitiesByCountryResult string `xml:"http://www.webserviceX.NET GetCitiesByCountryResult,omitempty"` +} + +type GetWeather struct { + CityName string `xml:"http://www.webserviceX.NET CityName,omitempty"` + CountryName string `xml:"http://www.webserviceX.NET CountryName,omitempty"` +} + +type GetWeatherResponse struct { + GetWeatherResult string `xml:"http://www.webserviceX.NET GetWeatherResult,omitempty"` +} +type Client struct { + HTTPClient *http.Client + ResponseHook func(*http.Response) *http.Response + RequestHook func(*http.Request) *http.Request +} +type soapEnvelope struct { + XMLName struct{} `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header []byte `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + Body struct { + Message interface{} + Fault *struct { + String string `xml:"faultstring,omitempty"` + Code string `xml:"faultcode,omitempty"` + Detail string `xml:"detail,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` +} + +func (c *Client) do(ctx context.Context, method, uri, action string, in, out interface{}) error { + var body io.Reader + var envelope soapEnvelope + if method == "POST" || method == "PUT" { + var buf bytes.Buffer + envelope.Body.Message = in + enc := xml.NewEncoder(&buf) + if err := enc.Encode(envelope); err != nil { + return err + } + if err := enc.Flush(); err != nil { + return err + } + body = &buf + } + req, err := http.NewRequest(method, uri, body) + if err != nil { + return err + } + req.Header.Set("SOAPAction", action) + req = req.WithContext(ctx) + if c.RequestHook != nil { + req = c.RequestHook(req) + } + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + rsp, err := httpClient.Do(req) + if err != nil { + return err + } + defer rsp.Body.Close() + if c.ResponseHook != nil { + rsp = c.ResponseHook(rsp) + } + dec := xml.NewDecoder(rsp.Body) + envelope.Body.Message = out + if err := dec.Decode(&envelope); err != nil { + return err + } + if envelope.Body.Fault != nil { + return fmt.Errorf("%s: %s", envelope.Body.Fault.Code, envelope.Body.Fault.String) + } + return nil +} + +// Get weather report for all major cities around the world. +func (c *Client) GetWeather(ctx context.Context, parameters GetWeather) (GetWeatherResponse, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Parameters GetWeather `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetWeatherSoapIn"` + } + input.Args.Parameters = GetWeather(parameters) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetWeather"` + Args struct { + Parameters GetWeatherResponse `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetWeatherSoapOut"` + } + err := c.do(ctx, "POST", "http://www.webservicex.net/globalweather.asmx", "http://www.webserviceX.NET/GetWeather", &input, &output) + return GetWeatherResponse(output.Args.Parameters), err +} + +// Get all major cities by country name(full / part). +func (c *Client) GetCitiesByCountry(ctx context.Context, parameters GetCitiesByCountry) (GetCitiesByCountryResponse, error) { + var input struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Parameters GetCitiesByCountry `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountrySoapIn"` + } + input.Args.Parameters = GetCitiesByCountry(parameters) + var output struct { + XMLName struct{} `xml:"http://www.webserviceX.NET GetCitiesByCountry"` + Args struct { + Parameters GetCitiesByCountryResponse `xml:"http://www.webserviceX.NET parameters"` + } `xml:"http://www.webserviceX.NET GetCitiesByCountrySoapOut"` + } + err := c.do(ctx, "POST", "http://www.webservicex.net/globalweather.asmx", "http://www.webserviceX.NET/GetCitiesByCountry", &input, &output) + return GetCitiesByCountryResponse(output.Args.Parameters), err +} diff --git a/wsdlgen/testdata/output/TestHello.xml.golden b/wsdlgen/testdata/output/TestHello.xml.golden new file mode 100644 index 0000000..701c4e0 --- /dev/null +++ b/wsdlgen/testdata/output/TestHello.xml.golden @@ -0,0 +1,97 @@ +// Code generated by wsdlgen.test. DO NOT EDIT. + +// Package ws +// +// WSDL File for HelloService +package ws + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" +) + +type Client struct { + HTTPClient *http.Client + ResponseHook func(*http.Response) *http.Response + RequestHook func(*http.Request) *http.Request +} +type soapEnvelope struct { + XMLName struct{} `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header []byte `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + Body struct { + Message interface{} + Fault *struct { + String string `xml:"faultstring,omitempty"` + Code string `xml:"faultcode,omitempty"` + Detail string `xml:"detail,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` +} + +func (c *Client) do(ctx context.Context, method, uri, action string, in, out interface{}) error { + var body io.Reader + var envelope soapEnvelope + if method == "POST" || method == "PUT" { + var buf bytes.Buffer + envelope.Body.Message = in + enc := xml.NewEncoder(&buf) + if err := enc.Encode(envelope); err != nil { + return err + } + if err := enc.Flush(); err != nil { + return err + } + body = &buf + } + req, err := http.NewRequest(method, uri, body) + if err != nil { + return err + } + req.Header.Set("SOAPAction", action) + req = req.WithContext(ctx) + if c.RequestHook != nil { + req = c.RequestHook(req) + } + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + rsp, err := httpClient.Do(req) + if err != nil { + return err + } + defer rsp.Body.Close() + if c.ResponseHook != nil { + rsp = c.ResponseHook(rsp) + } + dec := xml.NewDecoder(rsp.Body) + envelope.Body.Message = out + if err := dec.Decode(&envelope); err != nil { + return err + } + if envelope.Body.Fault != nil { + return fmt.Errorf("%s: %s", envelope.Body.Fault.Code, envelope.Body.Fault.String) + } + return nil +} +func (c *Client) SayHello(ctx context.Context, firstName string) (string, error) { + var input struct { + XMLName struct{} `xml:"http://www.examples.com/wsdl/HelloService.wsdl sayHello"` + Args struct { + FirstName string `xml:"http://www.examples.com/wsdl/HelloService.wsdl firstName"` + } `xml:"http://www.examples.com/wsdl/HelloService.wsdl SayHelloRequest"` + } + input.Args.FirstName = string(firstName) + var output struct { + XMLName struct{} `xml:"http://www.examples.com/wsdl/HelloService.wsdl sayHello"` + Args struct { + Greeting string `xml:"http://www.examples.com/wsdl/HelloService.wsdl greeting"` + } `xml:"http://www.examples.com/wsdl/HelloService.wsdl SayHelloResponse"` + } + err := c.do(ctx, "POST", "http://www.examples.com/SayHello/", "sayHello", &input, &output) + return string(output.Args.Greeting), err +} diff --git a/wsdlgen/testdata/output/TestNationalWeatherForecast.xml.golden b/wsdlgen/testdata/output/TestNationalWeatherForecast.xml.golden new file mode 100644 index 0000000..7d0a311 --- /dev/null +++ b/wsdlgen/testdata/output/TestNationalWeatherForecast.xml.golden @@ -0,0 +1,592 @@ +// Code generated by wsdlgen.test. DO NOT EDIT. + +// Package ws +// +// The service has 12 exposed functions, NDFDgen, NDFDgenLatLonList, NDFDgenByDay, NDFDgenByDayLatLonList, +// LatLonListSubgrid, LatLonListLine, LatLonListZipCode, CornerPoints, LatLonListSquare, GmlLatLonList, GmlTimeSeries, and LatLonListCityNames. +// For the NDFDgen function, the client needs to provide a latitude and longitude pair and the product type. The Unit will default +// to U.S. Standard (english) unless Metric is chosen by client. The client also needs to provide the start and end time (Local) +// of the period that it wants data for (if shorter than the 7 days is wanted). For the time-series product, the client needs to +// provide an array of boolean values corresponding to which NDFD values are desired. +// For the NDFDgenByDay function, the client needs to provide a latitude and longitude pair, the date (Local) it wants to start +// retrieving data for and the number of days worth of data. The Unit will default to U.S. Standard (english) unless Metric is +// chosen by client. The client also needs to provide the format that is desired. +// For the multi point versions, NDFDgenLatLonList and NDFDgenByDayLatLonList a space delimited list of latitude and longitude +// pairs are substituted for the single latitude and longitude input. Each latitude and longitude +// pair is composed of a latitude and longitude delimited by a comma. +// For the LatLonListSubgrid, the user provides a comma delimited latitude and longitude pair for the lower left and for +// the upper right corners of a rectangular subgrid. The function can also take a integer +// resolution to reduce the number of grid points returned. The service then returns a list of +// latitude and longitude pairs for all the grid points contained in the subgrid. +// weather values should appear in the time series product. +// For the LatLonListLine, The inputs are the same as the function NDFDgen except the latitude and longitude pair is +// replaced by two latitude and longitude pairs, one for each end point a line. The two points are delimited with a space. +// The service then returns data for all the NDFD points on the line formed by the two points. +// For the LatLonListZipCode function, the input is the same as the NDFDgen function except the latitude and longitude values +// are relaced by a zip code for the 50 United States and Puerto Rico. +// For the LatLonListSquare function, the input is the same as the NDFDgen function except the latitude and longitude values +// are relaced by a zip code for the 50 United States and Puerto Rico. +// For the CornerPoints function, the service requires a valid NDFD grid name. The function returns a +// list of four latitude and longitude pairs, one for each corner of the NDFD grid. The function +// also returns the minimum resolution required to return the entire grid below the maximum points +// threshold. +// For the GmlLatLonList function, the service requires a list of latitude and longitude pairs, the time (UTC) the user +// wants data for, the GML feature type and the array of boolean values corresponding to which NDFD values are desired. +// For the GmlTimeSeries function, the service requires a list of latitude and longitude pairs, the start and end time (UTC) the user +// wants data for, a comparison type (IsEqual, Between, GreaterThan, GreaterThan, GreaterThanEqualTo, LessThan, and +// LessThanEqualTo), the GML feature type and The input variable "propertyName" contains a comma delimited string of NDFD element to +// indicate which weather parameters are being requested. +// For the LatLonListCityNames function, the services requires a detail level that that ranges from 1 to 4. Level 1 generally represents +// large main cities. Level 2 represents progressively smaller cities or large cities that are close to another even larger city. Levels +// 3 and 4 are part one and two of a list of cities that help increase the areal coverage of the cities dataset. This functions +// returns a list of latitude and longitude values along with a seperate list of city name for those point. +package ws + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" + "time" +) + +// May be one of IsEqual, Between, GreaterThan, GreaterThanEqualTo, LessThan, LessThanEqualTo +type CompTypeType string + +// May be one of 1, 2, 3, 4, 12, 34, 1234 +type DisplayLevelType int + +// May be one of Forecast_Gml2Point, Forecast_Gml2AllWx, Forecast_GmlsfPoint, Forecast_GmlObs, NdfdMultiPointCoverage, Ndfd_KmlPoint +type FeatureTypeType string + +// May be one of 24 hourly, 12 hourly +type FormatType string + +// Must match the pattern [\-]?\d{1,2}\.\d+,[\-]?\d{1,3}\.\d+ +type LatLonPairType string + +// Must match the pattern [a-zA-Z'\-]*( ?[a-zA-Z'\-]*)*,[A-Z][A-Z](\|[a-zA-Z'\-]*( ?[a-zA-Z'\-]*)*,[A-Z][A-Z])* +type ListCityNamesType string + +// Must match the pattern [\-]?\d{1,2}\.\d+,[\-]?\d{1,3}\.\d+( [\-]?\d{1,2}\.\d+,[\-]?\d{1,3}\.\d+)* +type ListLatLonType string + +// May be one of time-series, glance +type ProductType string + +// May be one of conus, nhemi, alaska, guam, hawaii, puertori, npacocn +type SectorType string + +// May be one of e, m +type UnitType string + +type WeatherParametersType struct { + Maxt bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd maxt"` + Mint bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd mint"` + Temp bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd temp"` + Dew bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd dew"` + Pop12 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd pop12"` + Qpf bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd qpf"` + Sky bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd sky"` + Snow bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd snow"` + Wspd bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wspd"` + Wdir bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wdir"` + Wx bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wx"` + Waveh bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd waveh"` + Icons bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd icons"` + Rh bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd rh"` + Appt bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd appt"` + Incw34 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd incw34"` + Incw50 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd incw50"` + Incw64 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd incw64"` + Cumw34 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd cumw34"` + Cumw50 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd cumw50"` + Cumw64 bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd cumw64"` + Critfireo bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd critfireo"` + Dryfireo bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd dryfireo"` + Conhazo bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd conhazo"` + Ptornado bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd ptornado"` + Phail bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd phail"` + Ptstmwinds bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd ptstmwinds"` + Pxtornado bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd pxtornado"` + Pxhail bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd pxhail"` + Pxtstmwinds bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd pxtstmwinds"` + Ptotsvrtstm bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd ptotsvrtstm"` + Pxtotsvrtstm bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd pxtotsvrtstm"` + Tmpabv14d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd tmpabv14d"` + Tmpblw14d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd tmpblw14d"` + Tmpabv30d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd tmpabv30d"` + Tmpblw30d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd tmpblw30d"` + Tmpabv90d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd tmpabv90d"` + Tmpblw90d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd tmpblw90d"` + Prcpabv14d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd prcpabv14d"` + Prcpblw14d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd prcpblw14d"` + Prcpabv30d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd prcpabv30d"` + Prcpblw30d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd prcpblw30d"` + Prcpabv90d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd prcpabv90d"` + Prcpblw90d bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd prcpblw90d"` + Precipar bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd precipa_r"` + Skyr bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd sky_r"` + Tdr bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd td_r"` + Tempr bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd temp_r"` + Wdirr bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wdir_r"` + Wspdr bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wspd_r"` + Wwa bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wwa"` + Wgust bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd wgust"` + Iceaccum bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd iceaccum"` + Maxrh bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd maxrh"` + Minrh bool `xml:"http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd minrh"` +} + +// Must match the pattern \d{5}(\-\d{4})?( \d{5}(\-\d{4})?)* +type ZipCodeListType string + +// Must match the pattern \d{5}(\-\d{4})? +type ZipCodeType string +type Client struct { + HTTPClient *http.Client + ResponseHook func(*http.Response) *http.Response + RequestHook func(*http.Request) *http.Request +} +type soapEnvelope struct { + XMLName struct{} `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header []byte `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + Body struct { + Message interface{} + Fault *struct { + String string `xml:"faultstring,omitempty"` + Code string `xml:"faultcode,omitempty"` + Detail string `xml:"detail,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` + } `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` +} + +func (c *Client) do(ctx context.Context, method, uri, action string, in, out interface{}) error { + var body io.Reader + var envelope soapEnvelope + if method == "POST" || method == "PUT" { + var buf bytes.Buffer + envelope.Body.Message = in + enc := xml.NewEncoder(&buf) + if err := enc.Encode(envelope); err != nil { + return err + } + if err := enc.Flush(); err != nil { + return err + } + body = &buf + } + req, err := http.NewRequest(method, uri, body) + if err != nil { + return err + } + req.Header.Set("SOAPAction", action) + req = req.WithContext(ctx) + if c.RequestHook != nil { + req = c.RequestHook(req) + } + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + rsp, err := httpClient.Do(req) + if err != nil { + return err + } + defer rsp.Body.Close() + if c.ResponseHook != nil { + rsp = c.ResponseHook(rsp) + } + dec := xml.NewDecoder(rsp.Body) + envelope.Body.Message = out + if err := dec.Decode(&envelope); err != nil { + return err + } + if envelope.Body.Fault != nil { + return fmt.Errorf("%s: %s", envelope.Body.Fault.Code, envelope.Body.Fault.String) + } + return nil +} + +type NDFDgenRequest struct { + Latitude float64 + Longitude float64 + Product ProductType + StartTime time.Time + EndTime time.Time + Unit UnitType + WeatherParameters WeatherParametersType +} + +// Returns National Weather Service digital weather forecast data +func (c *Client) NDFDgen(ctx context.Context, v NDFDgenRequest) (string, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgen"` + Args struct { + Latitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl latitude"` + Longitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl longitude"` + Product ProductType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl product"` + StartTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl startTime"` + EndTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endTime"` + Unit UnitType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl Unit"` + WeatherParameters WeatherParametersType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl weatherParameters"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenRequest"` + } + input.Args.Latitude = float64(v.Latitude) + input.Args.Longitude = float64(v.Longitude) + input.Args.Product = ProductType(v.Product) + input.Args.StartTime = time.Time(v.StartTime) + input.Args.EndTime = time.Time(v.EndTime) + input.Args.Unit = UnitType(v.Unit) + input.Args.WeatherParameters = WeatherParametersType(v.WeatherParameters) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgen"` + Args struct { + DwmlOut string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl dwmlOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgen", &input, &output) + return string(output.Args.DwmlOut), err +} + +type NDFDgenByDayRequest struct { + Latitude float64 + Longitude float64 + StartDate time.Time + NumDays int + Unit UnitType + Format FormatType +} + +// Returns National Weather Service digital weather forecast data summarized over either 24- or 12-hourly periods +func (c *Client) NDFDgenByDay(ctx context.Context, v NDFDgenByDayRequest) (string, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDay"` + Args struct { + Latitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl latitude"` + Longitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl longitude"` + StartDate time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl startDate"` + NumDays int `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl numDays"` + Unit UnitType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl Unit"` + Format FormatType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl format"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDayRequest"` + } + input.Args.Latitude = float64(v.Latitude) + input.Args.Longitude = float64(v.Longitude) + input.Args.StartDate = time.Time(v.StartDate) + input.Args.NumDays = int(v.NumDays) + input.Args.Unit = UnitType(v.Unit) + input.Args.Format = FormatType(v.Format) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDay"` + Args struct { + DwmlByDayOut string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl dwmlByDayOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDayResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgenByDay", &input, &output) + return string(output.Args.DwmlByDayOut), err +} + +type NDFDgenLatLonListRequest struct { + ListLatLon ListLatLonType + Product ProductType + StartTime time.Time + EndTime time.Time + Unit UnitType + WeatherParameters WeatherParametersType +} + +// Returns National Weather Service digital weather forecast data +func (c *Client) NDFDgenLatLonList(ctx context.Context, v NDFDgenLatLonListRequest) (string, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenLatLonList"` + Args struct { + ListLatLon ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLon"` + Product ProductType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl product"` + StartTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl startTime"` + EndTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endTime"` + Unit UnitType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl Unit"` + WeatherParameters WeatherParametersType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl weatherParameters"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenLatLonListRequest"` + } + input.Args.ListLatLon = ListLatLonType(v.ListLatLon) + input.Args.Product = ProductType(v.Product) + input.Args.StartTime = time.Time(v.StartTime) + input.Args.EndTime = time.Time(v.EndTime) + input.Args.Unit = UnitType(v.Unit) + input.Args.WeatherParameters = WeatherParametersType(v.WeatherParameters) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenLatLonList"` + Args struct { + DwmlOut string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl dwmlOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenLatLonListResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgenLatLonList", &input, &output) + return string(output.Args.DwmlOut), err +} + +type NDFDgenByDayLatLonListRequest struct { + ListLatLon ListLatLonType + StartDate time.Time + NumDays int + Unit UnitType + Format FormatType +} + +// Returns National Weather Service digital weather forecast data summarized over either 24- or 12-hourly periods +func (c *Client) NDFDgenByDayLatLonList(ctx context.Context, v NDFDgenByDayLatLonListRequest) (string, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDayLatLonList"` + Args struct { + ListLatLon ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLon"` + StartDate time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl startDate"` + NumDays int `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl numDays"` + Unit UnitType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl Unit"` + Format FormatType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl format"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDayLatLonListRequest"` + } + input.Args.ListLatLon = ListLatLonType(v.ListLatLon) + input.Args.StartDate = time.Time(v.StartDate) + input.Args.NumDays = int(v.NumDays) + input.Args.Unit = UnitType(v.Unit) + input.Args.Format = FormatType(v.Format) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDayLatLonList"` + Args struct { + DwmlByDayOut string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl dwmlByDayOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl NDFDgenByDayLatLonListResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#NDFDgenByDayLatLonList", &input, &output) + return string(output.Args.DwmlByDayOut), err +} + +type GmlLatLonListRequest struct { + ListLatLon ListLatLonType + RequestedTime time.Time + FeatureType FeatureTypeType + WeatherParameters WeatherParametersType +} + +// Returns National Weather Service digital weather forecast data encoded in GML for a single time +func (c *Client) GmlLatLonList(ctx context.Context, v GmlLatLonListRequest) (string, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlLatLonList"` + Args struct { + ListLatLon ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLon"` + RequestedTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl requestedTime"` + FeatureType FeatureTypeType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl featureType"` + WeatherParameters WeatherParametersType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl weatherParameters"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlLatLonListRequest"` + } + input.Args.ListLatLon = ListLatLonType(v.ListLatLon) + input.Args.RequestedTime = time.Time(v.RequestedTime) + input.Args.FeatureType = FeatureTypeType(v.FeatureType) + input.Args.WeatherParameters = WeatherParametersType(v.WeatherParameters) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlLatLonList"` + Args struct { + DwGmlOut string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl dwGmlOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlLatLonListResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#GmlLatLonList", &input, &output) + return string(output.Args.DwGmlOut), err +} + +type GmlTimeSeriesRequest struct { + ListLatLon ListLatLonType + StartTime time.Time + EndTime time.Time + CompType CompTypeType + FeatureType FeatureTypeType + PropertyName string +} + +// Returns National Weather Service digital weather forecast data encoded in GML for a time period +func (c *Client) GmlTimeSeries(ctx context.Context, v GmlTimeSeriesRequest) (string, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlTimeSeries"` + Args struct { + ListLatLon ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLon"` + StartTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl startTime"` + EndTime time.Time `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endTime"` + CompType CompTypeType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl compType"` + FeatureType FeatureTypeType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl featureType"` + PropertyName string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl propertyName"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlTimeSeriesRequest"` + } + input.Args.ListLatLon = ListLatLonType(v.ListLatLon) + input.Args.StartTime = time.Time(v.StartTime) + input.Args.EndTime = time.Time(v.EndTime) + input.Args.CompType = CompTypeType(v.CompType) + input.Args.FeatureType = FeatureTypeType(v.FeatureType) + input.Args.PropertyName = string(v.PropertyName) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlTimeSeries"` + Args struct { + DwGmlOut string `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl dwGmlOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl GmlTimeSeriesResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#GmlTimeSeries", &input, &output) + return string(output.Args.DwGmlOut), err +} + +type LatLonListSubgridRequest struct { + LowerLeftLatitude float64 + LowerLeftLongitude float64 + UpperRightLatitude float64 + UpperRightLongitude float64 + Resolution float64 +} + +// Returns a list of latitude and longitude pairs in a rectangular subgrid defined by the lower left and upper right points +func (c *Client) LatLonListSubgrid(ctx context.Context, v LatLonListSubgridRequest) (ListLatLonType, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSubgrid"` + Args struct { + LowerLeftLatitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl lowerLeftLatitude"` + LowerLeftLongitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl lowerLeftLongitude"` + UpperRightLatitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl upperRightLatitude"` + UpperRightLongitude float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl upperRightLongitude"` + Resolution float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl resolution"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSubgridRequest"` + } + input.Args.LowerLeftLatitude = float64(v.LowerLeftLatitude) + input.Args.LowerLeftLongitude = float64(v.LowerLeftLongitude) + input.Args.UpperRightLatitude = float64(v.UpperRightLatitude) + input.Args.UpperRightLongitude = float64(v.UpperRightLongitude) + input.Args.Resolution = float64(v.Resolution) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSubgrid"` + Args struct { + ListLatLonOut ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLonOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSubgridResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListSubgrid", &input, &output) + return ListLatLonType(output.Args.ListLatLonOut), err +} + +type LatLonListLineRequest struct { + EndPoint1Lat float64 + EndPoint1Lon float64 + EndPoint2Lat float64 + EndPoint2Lon float64 +} + +// Returns a list of latitude and longitude pairs along a line defined by the latitude and longitude of the 2 endpoints +func (c *Client) LatLonListLine(ctx context.Context, v LatLonListLineRequest) (ListLatLonType, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListLine"` + Args struct { + EndPoint1Lat float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endPoint1Lat"` + EndPoint1Lon float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endPoint1Lon"` + EndPoint2Lat float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endPoint2Lat"` + EndPoint2Lon float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl endPoint2Lon"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListLineRequest"` + } + input.Args.EndPoint1Lat = float64(v.EndPoint1Lat) + input.Args.EndPoint1Lon = float64(v.EndPoint1Lon) + input.Args.EndPoint2Lat = float64(v.EndPoint2Lat) + input.Args.EndPoint2Lon = float64(v.EndPoint2Lon) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListLine"` + Args struct { + ListLatLonOut ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLonOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListLineResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListLine", &input, &output) + return ListLatLonType(output.Args.ListLatLonOut), err +} + +// Returns a list of latitude and longitude pairs with each pair corresponding to an input zip code. +func (c *Client) LatLonListZipCode(ctx context.Context, zipCodeList ZipCodeListType) (ListLatLonType, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListZipCode"` + Args struct { + ZipCodeList ZipCodeListType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl zipCodeList"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListZipCodeRequest"` + } + input.Args.ZipCodeList = ZipCodeListType(zipCodeList) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListZipCode"` + Args struct { + ListLatLonOut ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLonOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListZipCodeResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListZipCode", &input, &output) + return ListLatLonType(output.Args.ListLatLonOut), err +} + +type LatLonListSquareRequest struct { + CenterPointLat float64 + CenterPointLon float64 + DistanceLat float64 + DistanceLon float64 + Resolution float64 +} + +// Returns a list of latitude and longitude pairs in a rectangle defined by a central point and distance from that point in the latitudinal and longitudinal directions +func (c *Client) LatLonListSquare(ctx context.Context, v LatLonListSquareRequest) (ListLatLonType, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSquare"` + Args struct { + CenterPointLat float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl centerPointLat"` + CenterPointLon float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl centerPointLon"` + DistanceLat float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl distanceLat"` + DistanceLon float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl distanceLon"` + Resolution float64 `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl resolution"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSquareRequest"` + } + input.Args.CenterPointLat = float64(v.CenterPointLat) + input.Args.CenterPointLon = float64(v.CenterPointLon) + input.Args.DistanceLat = float64(v.DistanceLat) + input.Args.DistanceLon = float64(v.DistanceLon) + input.Args.Resolution = float64(v.Resolution) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSquare"` + Args struct { + ListLatLonOut ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLonOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListSquareResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListSquare", &input, &output) + return ListLatLonType(output.Args.ListLatLonOut), err +} + +// Returns four latitude and longitude pairs for corners of an NDFD grid and the minimum resolution that will return the entire grid +func (c *Client) CornerPoints(ctx context.Context, sector SectorType) (ListLatLonType, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl CornerPoints"` + Args struct { + Sector SectorType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl sector"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl CornerPointsRequest"` + } + input.Args.Sector = SectorType(sector) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl CornerPoints"` + Args struct { + ListLatLonOut ListLatLonType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listLatLonOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl CornerPointsResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#CornerPoints", &input, &output) + return ListLatLonType(output.Args.ListLatLonOut), err +} + +// Returns a list of latitude and longitude pairs paired with the city names they correspond to +func (c *Client) LatLonListCityNames(ctx context.Context, displayLevel DisplayLevelType) (ListCityNamesType, error) { + var input struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListCityNames"` + Args struct { + DisplayLevel DisplayLevelType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl displayLevel"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListCityNamesRequest"` + } + input.Args.DisplayLevel = DisplayLevelType(displayLevel) + var output struct { + XMLName struct{} `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListCityNames"` + Args struct { + ListCityNamesOut ListCityNamesType `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl listCityNamesOut"` + } `xml:"http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl LatLonListCityNamesResponse"` + } + err := c.do(ctx, "POST", "http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php", "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListCityNames", &input, &output) + return ListCityNamesType(output.Args.ListCityNamesOut), err +} diff --git a/wsdlgen/wsdlgen.go b/wsdlgen/wsdlgen.go index 2dc8b2d..6024069 100644 --- a/wsdlgen/wsdlgen.go +++ b/wsdlgen/wsdlgen.go @@ -142,6 +142,9 @@ func (cfg *Config) genAST(def *wsdl.Definition, code *xsdgen.Code) (*ast.File, e func (p *printer) genAST() (*ast.File, error) { p.addHelpers() for _, port := range p.wsdl.Ports { + if p.portFilter != nil && !p.portFilter(port) { + continue + } if err := p.port(port); err != nil { return nil, err } diff --git a/wsdlgen/wsdlgen_test.go b/wsdlgen/wsdlgen_test.go index 00e155c..a754546 100644 --- a/wsdlgen/wsdlgen_test.go +++ b/wsdlgen/wsdlgen_test.go @@ -1,8 +1,9 @@ package wsdlgen import ( - "io/ioutil" + "errors" "os" + "path" "testing" "aqwari.net/xml/xsdgen" @@ -15,7 +16,7 @@ type testLogger struct { func (t testLogger) Printf(format string, args ...interface{}) { t.Logf(format, args...) } func testGen(t *testing.T, files ...string) { - output_file, err := ioutil.TempFile("", "wsdlgen") + output_file, err := os.CreateTemp("", "wsdlgen") if err != nil { t.Fatal(err) } @@ -33,10 +34,32 @@ func testGen(t *testing.T, files ...string) { t.Error(err) return } - if data, err := ioutil.ReadFile(output_file.Name()); err != nil { + data, err := os.ReadFile(output_file.Name()) + if err != nil { t.Error(err) } else { - t.Logf("\n%s\n", data) + compareToGolden(t, data) + } +} + +func compareToGolden(t *testing.T, data []byte) { + goldenPath := path.Join("testdata/output/", t.Name()+".xml.golden") + expected, err := os.ReadFile(goldenPath) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + err := os.WriteFile(goldenPath, data, 0644) + if err != nil { + t.Errorf("could not create golden file, %v", err) + } + } else { + t.Errorf("could not read golden file, %v", err) + } + return + } + expectedString := string(expected) + actualString := string(data) + if expectedString != actualString { + t.Error("output does not match golden file") } } @@ -48,6 +71,10 @@ func TestGlobalWeather(t *testing.T) { testGen(t, "../testdata/webservicex-globalweather-ws.wsdl") } +func TestGlobalWeatherPortFilter(t *testing.T) { + testGen(t, "-port", "GlobalWeatherSoap", "../testdata/webservicex-globalweather-ws.wsdl") +} + func TestHello(t *testing.T) { testGen(t, "../testdata/hello.wsdl") }