<commit_before>package xero

import (
	"bytes"
	"encoding/xml"
	"io"
	"net/http"
	"net/url"
	"path"
	"time"
)

// Internal interface tyes implemented by the Client type
type (
	// The getter interface is implemented by the Client type and used internally
	getter interface {
		get(string, interface{}) error
	}
	// The poster interface is implemented by the Client type and used internally
	poster interface {
		post(string, io.Reader, interface{}) error
	}
	// The putter interface is implemented by the Client type and used internally
	putter interface {
		put(string, io.Reader, interface{}) error
	}
)

// The Endpoint type defines official Xero API endpoints
type Endpoint string

// String implements the Stringer interface
func (e Endpoint) String() string {
	return string(e)
}

// The Authorizer interface defines  common interface for authorising Xero HTTP
// requests using oAuth. The AuthorizeRequest takes the HTTP request that requires
// authorization.
type Authorizer interface {
	AuthorizeRequest(request *http.Request) error
}

// The Response type defines the XML response body wrapper
//   <Response>
//       <Id>...</Id>
//       <Status>...</Status>
//       <ProviderName>...</ProviderName
//       <DateTimeUTC>...</DateTimeUTC>
//       ...
//   </Response>
type Response struct {
	XMLName      xml.Name  `xml:"Response"`
	Id           string    `xml:"Id"`
	Status       string    `xml:"Status"`
	ProviderName string    `xml:"ProviderName"`
	DateTimeUTC  time.Time `xml:"DateTimeUTC"`
}

// A Client is a Xero API client. It provides methods for calling Xero API endpoints.
// This type should be constructed with the New() method.
type Client struct {
	authorizer Authorizer
	client     *http.Client

	scheme string // Xero API Protocol Scheme (https)
	host   string // Xero API Host (api.xero.com)
	root   string // Xero API Root (/api.xro/2.0)
}

// url constructs a valid Xero API url. The scheme, host and api root are
// automatically appended to the url path
func (c *Client) url(endpoint Endpoint, extra ...string) *url.URL {
	parts := append([]string{endpoint.String()}, extra...)
	return &url.URL{
		Scheme: c.scheme,
		Host:   c.host,
		Path:   path.Join(parts...),
	}
}

// do calls the Xero API
func (c *Client) do(method, urlStr string, body io.Reader) (*http.Response, error) {<commit_msg>New types for handling API exceptions<commit_after>package xero

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"path"
	"time"
)

// Internal interface tyes implemented by the Client type
type (
	// The getter interface is implemented by the Client type and used internally
	getter interface {
		get(string, interface{}) error
	}
	// The poster interface is implemented by the Client type and used internally
	poster interface {
		post(string, io.Reader, interface{}) error
	}
	// The putter interface is implemented by the Client type and used internally
	putter interface {
		put(string, io.Reader, interface{}) error
	}
)

// The Endpoint type defines official Xero API endpoints
type Endpoint string

// String implements the Stringer interface
func (e Endpoint) String() string {
	return string(e)
}

// The Authorizer interface defines  common interface for authorising Xero HTTP
// requests using oAuth. The AuthorizeRequest takes the HTTP request that requires
// authorization.
type Authorizer interface {
	AuthorizeRequest(request *http.Request) error
}

// The Response type defines the XML response body wrapper
//   <Response>
//       <Id>...</Id>
//       <Status>...</Status>
//       <ProviderName>...</ProviderName
//       <DateTimeUTC>...</DateTimeUTC>
//       ...
//   </Response>
type Response struct {
	XMLName      xml.Name  `xml:"Response"`
	Id           string    `xml:"Id"`
	Status       string    `xml:"Status"`
	ProviderName string    `xml:"ProviderName"`
	DateTimeUTC  time.Time `xml:"DateTimeUTC"`
}

// An Exceotion is returned by the API for none 200 responses
// This may contain extra information about the error such as in a 400
// bad request, others may not contain any other information
// This type stores the origional HTTP request and response status code
// as well as the API exception returned by Xero
type Error struct {
	Status       int
	Request      *http.Request
	APIException APIException
}

// Error returns the string representation of the Error
func (e Error) Error() string {
	return fmt.Sprintf(
		"Xero API Exception: [%d] %d: %s",
		e.Status,
		e.APIException.ErrorNumber,
		e.APIException.Message)
}

// An APIException is returned when the API errors
//   <ApiException>
//     <ErrorNumber>10</ErrorNumber>
//     <Type>ValidationException</Type>
//     <Message>A validation exception occurred</Message>
//     <Elements>
//       <DataContractBase xsi:type="Invoice">
//         <ValidationErrors>
//           <ValidationError>
//             <Message>Email address must be valid.</Message>
//           </ValidationError>
//         </ValidationErrors>
//      </DataContractBase>
//     </Elements>
//   </ApiException>
type APIException struct {
	ErrorNumber      int              `xml:"ErrorNumber"`
	Type             string           `xml:"Type"`
	Message          string           `xml:"Message"`
	DataContractBase DataContractBase `xml:"DataContractBase"`
}

// DataContactBase holds the type the API exception was for
// and any ValidationError's that occured that need to be corrected
type DataContractBase struct {
	Type             string            `xml:"xsi:type,attr"`
	ValidationErrors []ValidationError `xml:"ValidationErrors>ValidationError,omitempty"`
}

// A Client is a Xero API client. It provides methods for calling Xero API endpoints.
// This type should be constructed with the New() method.
type Client struct {
	authorizer Authorizer
	client     *http.Client

	scheme string // Xero API Protocol Scheme (https)
	host   string // Xero API Host (api.xero.com)
	root   string // Xero API Root (/api.xro/2.0)
}

// url constructs a valid Xero API url. The scheme, host and api root are
// automatically appended to the url path
func (c *Client) url(endpoint Endpoint, extra ...string) *url.URL {
	parts := append([]string{endpoint.String()}, extra...)
	return &url.URL{
		Scheme: c.scheme,
		Host:   c.host,
		Path:   path.Join(parts...),
	}
}

// do calls the Xero API
func (c *Client) do(method, urlStr string, body io.Reader) (*http.Response, error) {
{'fraction_non_alphanumeric': 0.10975609756097561, 'fraction_numerical': 0.001876172607879925, 'mean_word_length': 3.1138263665594854, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4835254', 'n_tokens_mistral': 1849, 'n_tokens_neox': 1809, 'n_words': 685}