<commit_before>package method

import "github.com/qlova/ilang/src"
import "github.com/qlova/ilang/src/modules/function"

var Flag = ilang.NewFlag()
var New = ilang.NewFlag()

func init() {
	ilang.RegisterToken([]string{"method"}, ScanMethod)
	ilang.RegisterListener(New, NewEnd)

	ilang.RegisterDefault(func(ic *ilang.Compiler) bool {
		token := ic.LastToken

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {
				ic.Scan('.')
				ic.ExpressionType = function.Flag
				var name = ic.Scan(ilang.Name)
				ic.Shunt(name+"_m_"+token)
				ic.Scan('(') //BUG I don't know why this has to be here.
				return true
			}
		}

		if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {
			if _, ok := ic.LastDefinedType.Detail.Table[token]; ok {
				ic.NextToken = ic.LastDefinedType.Name
				ic.NextNextToken = "."
				ic.NextNextNextToken = token
				ic.ScanStatement()
				return true
			}
		}

		return false
	})

	ilang.RegisterExpression(func(ic *ilang.Compiler) string {
		token := ic.LastToken

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {
				ic.Scan('.')
				ic.ExpressionType = function.Flag
				var name = ic.Scan(ilang.Name)
				return ic.Shunt(name+"_m_"+ic.DefinedTypes[token].GetComplexName())
			}
		}

		if ic.GetFlag(Flag) {
			if ic.TypeExists(token) && ic.LastDefinedType.Super == token {
	 			ic.ExpressionType = ic.DefinedTypes[ic.LastDefinedType.Super]
				return ic.Shunt(ic.LastDefinedType.Name)
		 	}

			//Scope methods with multiple arguments inside the method.
			//eg. method Package.dosomething(22)
			// in a Package method, dosomething(22) should be local.
			if _, ok  := ic.DefinedFunctions[token+"_m_"+ic.LastDefinedType.Name]; ok {
				var f = token+"_m_"+ic.LastDefinedType.Name

				if !ic.LastDefinedType.Empty() {
					ic.Assembly(ic.LastDefinedType.Push," ", ic.LastDefinedType.Name)
				}

				ic.ExpressionType = function.Flag

				return ic.Shunt(f)
			}
		}

	 	return ""
	})

	ilang.RegisterVariable(func(ic *ilang.Compiler, name string) ilang.Type {
		//Allow table values to be indexed in a method.
		if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {
			if _, ok := ic.LastDefinedType.Detail.Table[name]; ok {
				ic.DisableOwnership = true
				var value = ic.IndexUserType(ic.LastDefinedType.Name, name)
				ic.DisableOwnership = false

				ic.AssembleVar(name, value)
				ic.SetVariable(name+"_use", ilang.Used)
				return ic.ExpressionType
			}
		}
		return ilang.Undefined
	})

	ilang.RegisterShunt(".", ShuntMethodCall)
}

func Sync(ic *ilang.Compiler, variables ...string) {
	if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {

		for _, variable := range variables {

			if _, ok := ic.LastDefinedType.Detail.Table[variable]; ok {
				ic.SetUserType(ic.LastDefinedType.Name, variable, variable)
			}
		}
	}
}

func ShuntMethodCall(ic *ilang.Compiler, name string) string {
	var index = ic.Scan(ilang.Name)

	if _, ok  := ic.DefinedFunctions[index+"_m_"+ic.ExpressionType.GetComplexName()]; ok {
		var f = index+"_m_"+ic.ExpressionType.GetComplexName()
		ic.Assembly(ic.ExpressionType.Push," ", name)
		ic.ExpressionType = function.Flag
		return ic.Shunt(f)
	}

	ic.NextToken = index
	return ""
}

func NewEnd(ic *ilang.Compiler) {
	ic.Assembly("SHARE ", ic.LastDefinedType.Name)
	ic.LoseScope()
}

func Call(ic *ilang.Compiler, name string, t ilang.Type) {
	ic.Assembly(ic.RunFunction(name+"_m_"+t.GetComplexName()))
}

func ScanMethod(ic *ilang.Compiler) {
	ic.Header = false

	var name string = ic.Scan(ilang.Name)

	f := ic.DefinedFunctions[name]
	f.Method = true
	ic.DefinedFunctions[name] = f

	/*if name == "new" {
		ic.Scan('(')
		ic.ScanNew()
		return
	}*/

	var MethodType = ic.LastDefinedType

	var token = ic.Scan(0)
	if token == "(" {
		token = ic.Scan(0)
		if token != ")" {
			if t, ok := ic.DefinedTypes[token]; ok {
				MethodType = t
			} else {
				ic.NextToken = token
			}
		}

		ic.LastDefinedType = MethodType

		if MethodType.Name == "Game" && name == "new" {
			ic.NewGame = true
		}
		if MethodType.Name == "Game" && name == "draw" {
			ic.DrawGame = true
		}
		if MethodType.Name == "Game" && name == "update" {
			ic.UpdateGame = true
		}

		name += "_m_"+MethodType.Name

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()

		if name == "new_m_"+MethodType.Name {

			ic.Assembly("PUSH ", len(MethodType.Detail.Elements))
			ic.Assembly("MAKE")
			ic.Assembly("GRAB ", MethodType.Name)

			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)

		} else if  MethodType.Detail != nil && len(MethodType.Detail.Elements) > 0 {
			ic.Assembly("%v %v", MethodType.Pop, MethodType.Name)
			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)
		}

		function.CreateFromArguments(name, ic)
		ic.SetFlag(Flag)

		f = ic.DefinedFunctions[name]
		if name == "new_m_"+MethodType.Name {
			ic.GainScope()
			ic.SetFlag(New)
			f.Returns = []ilang.Type{MethodType}

		}

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	//Functional methods.
	} else if token == "." {

		if !ic.TypeExists(name) {
			ic.RaiseError("Undefined type: ", name)
		}

		t := ic.DefinedTypes[name]
		ic.LastDefinedType = t

		name = ic.Scan(ilang.Name)
		name += "_m_"+t.GetComplexName()

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()
		ic.Scan('(')

		function.CreateFromArguments(name, ic)

		if t.Detail == nil || len(t.Detail.Elements) > 0 {
			ic.Assembly("%v %v", t.Pop, t.Name)
			ic.SetVariable(t.Name, t)
			ic.SetVariable(t.Name+"_use", ilang.Used)
		}

		f = ic.DefinedFunctions[name]
		ic.SetFlag(Flag)

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	} else {
		var symbol = token
		var other = ic.Scan(ilang.Name)
		ic.Scan('{')

		if t, ok := ic.DefinedTypes[name]; ok {
			MethodType = t
		}

		var a = MethodType

		MethodType = ic.DefinedTypes[other]

		ic.LastDefinedType = MethodType

		var b = MethodType

		ilang.NewOperator(a, symbol, b, "SHARE %a\n SHARE %b\nRUN "+a.Name+"_"+symbol+"_"+b.Name+"\nGRAB %c", true)

		ic.Assembly("FUNCTION %s_%s_%s\n", a.Name, symbol, b.Name)
		ic.GainScope()
		ic.Assembly("GRAB b\nGRAB a\nARRAY c\n")
		for range a.Detail.Elements {
			ic.Assembly("PUT 0\n")
		}
		ic.InOperatorFunction = true

		ic.SetFlag(function.Flag)

		ic.SetVariable("c", a)
		ic.SetVariable("a", a)
		ic.SetVariable("b", b)
	}
}

<commit_msg>Allow empty types to emulate package selectors.<commit_after>package method

import "github.com/qlova/ilang/src"
import "github.com/qlova/ilang/src/modules/function"

var Flag = ilang.NewFlag()
var New = ilang.NewFlag()

func init() {
	ilang.RegisterToken([]string{"method"}, ScanMethod)
	ilang.RegisterListener(New, NewEnd)

	ilang.RegisterDefault(func(ic *ilang.Compiler) bool {
		token := ic.LastToken

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {

				var TYPE = ic.DefinedTypes[token]

				for {
					ic.Scan('.')

					var name = ic.Scan(ilang.Name)

					if TYPE.Detail != nil {
						if index, ok := TYPE.Detail.Table[name]; ok {
							TYPE = TYPE.Detail.Elements[index]
							continue
						}
					}

					ic.ExpressionType = function.Flag

					ic.Shunt(name+"_m_"+TYPE.GetComplexName())
					ic.Scan('(') //BUG I don't know why this has to be here.
					return true
				}
			}
		}

		if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {
			if _, ok := ic.LastDefinedType.Detail.Table[token]; ok {
				ic.NextToken = ic.LastDefinedType.Name
				ic.NextNextToken = "."
				ic.NextNextNextToken = token
				ic.ScanStatement()
				return true
			}
		}

		return false
	})

	ilang.RegisterExpression(func(ic *ilang.Compiler) string {
		token := ic.LastToken

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {

				var TYPE = ic.DefinedTypes[token]

				for {
					ic.Scan('.')
					var name = ic.Scan(ilang.Name)

					if TYPE.Detail != nil {
						if index, ok := TYPE.Detail.Table[name]; ok {
							TYPE = TYPE.Detail.Elements[index]
							continue
						}
					}

					ic.ExpressionType = function.Flag

					//Error checking.
					f, ok := ic.DefinedFunctions[name+"_m_"+TYPE.GetComplexName()]
					if !ok {
						ic.RaiseError("Method ",  name, " for ", TYPE.GetComplexName(), " does not exist!")
					}
					if len(f.Returns) == 0 {
						ic.RaiseError("Method ", TYPE.GetComplexName(), ".", name, "() does not return anything!")
					}

					var test = ic.Shunt(name+"_m_"+TYPE.GetComplexName())
					return test
				}
			}
		}

		if ic.GetFlag(Flag) {
			if ic.TypeExists(token) && ic.LastDefinedType.Super == token {
	 			ic.ExpressionType = ic.DefinedTypes[ic.LastDefinedType.Super]
				return ic.Shunt(ic.LastDefinedType.Name)
		 	}

			//Scope methods with multiple arguments inside the method.
			//eg. method Package.dosomething(22)
			// in a Package method, dosomething(22) should be local.
			if _, ok  := ic.DefinedFunctions[token+"_m_"+ic.LastDefinedType.Name]; ok {
				var f = token+"_m_"+ic.LastDefinedType.Name

				if !ic.LastDefinedType.Empty() {
					ic.Assembly(ic.LastDefinedType.Push," ", ic.LastDefinedType.Name)
				}

				ic.ExpressionType = function.Flag

				return ic.Shunt(f)
			}
		}

	 	return ""
	})

	ilang.RegisterVariable(func(ic *ilang.Compiler, name string) ilang.Type {
		//Allow table values to be indexed in a method.
		if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {
			if _, ok := ic.LastDefinedType.Detail.Table[name]; ok {
				ic.DisableOwnership = true
				var value = ic.IndexUserType(ic.LastDefinedType.Name, name)
				ic.DisableOwnership = false

				ic.AssembleVar(name, value)
				ic.SetVariable(name+"_use", ilang.Used)
				return ic.ExpressionType
			}
		}
		return ilang.Undefined
	})

	ilang.RegisterShunt(".", ShuntMethodCall)
}

func Sync(ic *ilang.Compiler, variables ...string) {
	if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {

		for _, variable := range variables {

			if _, ok := ic.LastDefinedType.Detail.Table[variable]; ok {
				ic.SetUserType(ic.LastDefinedType.Name, variable, variable)
			}
		}
	}
}

func ShuntMethodCall(ic *ilang.Compiler, name string) string {
	var index = ic.Scan(ilang.Name)

	if _, ok  := ic.DefinedFunctions[index+"_m_"+ic.ExpressionType.GetComplexName()]; ok {
		var f = index+"_m_"+ic.ExpressionType.GetComplexName()
		ic.Assembly(ic.ExpressionType.Push," ", name)
		ic.ExpressionType = function.Flag
		return ic.Shunt(f)
	}

	ic.NextToken = index
	return ""
}

func NewEnd(ic *ilang.Compiler) {
	ic.Assembly("SHARE ", ic.LastDefinedType.Name)
	ic.LoseScope()
}

func Call(ic *ilang.Compiler, name string, t ilang.Type) {
	ic.Assembly(ic.RunFunction(name+"_m_"+t.GetComplexName()))
}

func ScanMethod(ic *ilang.Compiler) {
	ic.Header = false

	var name string = ic.Scan(ilang.Name)

	f := ic.DefinedFunctions[name]
	f.Method = true
	ic.DefinedFunctions[name] = f

	/*if name == "new" {
		ic.Scan('(')
		ic.ScanNew()
		return
	}*/

	var MethodType = ic.LastDefinedType

	var token = ic.Scan(0)
	if token == "(" {
		token = ic.Scan(0)
		if token != ")" {
			if t, ok := ic.DefinedTypes[token]; ok {
				MethodType = t
			} else {
				ic.NextToken = token
			}
		}

		ic.LastDefinedType = MethodType

		if MethodType.Name == "Game" && name == "new" {
			ic.NewGame = true
		}
		if MethodType.Name == "Game" && name == "draw" {
			ic.DrawGame = true
		}
		if MethodType.Name == "Game" && name == "update" {
			ic.UpdateGame = true
		}

		name += "_m_"+MethodType.Name

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()

		if name == "new_m_"+MethodType.Name {

			ic.Assembly("PUSH ", len(MethodType.Detail.Elements))
			ic.Assembly("MAKE")
			ic.Assembly("GRAB ", MethodType.Name)

			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)

		} else if  MethodType.Detail != nil && len(MethodType.Detail.Elements) > 0 {
			ic.Assembly("%v %v", MethodType.Pop, MethodType.Name)
			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)
		}

		function.CreateFromArguments(name, ic)
		ic.SetFlag(Flag)

		f = ic.DefinedFunctions[name]
		if name == "new_m_"+MethodType.Name {
			ic.GainScope()
			ic.SetFlag(New)
			f.Returns = []ilang.Type{MethodType}

		}

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	//Functional methods.
	} else if token == "." {

		if !ic.TypeExists(name) {
			ic.RaiseError("Undefined type: ", name)
		}

		t := ic.DefinedTypes[name]
		ic.LastDefinedType = t

		name = ic.Scan(ilang.Name)
		name += "_m_"+t.GetComplexName()

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()
		ic.Scan('(')

		function.CreateFromArguments(name, ic)

		if t.Detail == nil || len(t.Detail.Elements) > 0 {
			ic.Assembly("%v %v", t.Pop, t.Name)
			ic.SetVariable(t.Name, t)
			ic.SetVariable(t.Name+"_use", ilang.Used)
		}

		f = ic.DefinedFunctions[name]
		ic.SetFlag(Flag)

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	} else {
		var symbol = token
		var other = ic.Scan(ilang.Name)
		ic.Scan('{')

		if t, ok := ic.DefinedTypes[name]; ok {
			MethodType = t
		}

		var a = MethodType

		MethodType = ic.DefinedTypes[other]

		ic.LastDefinedType = MethodType

		var b = MethodType

		ilang.NewOperator(a, symbol, b, "SHARE %a\n SHARE %b\nRUN "+a.Name+"_"+symbol+"_"+b.Name+"\nGRAB %c", true)

		ic.Assembly("FUNCTION %s_%s_%s\n", a.Name, symbol, b.Name)
		ic.GainScope()
		ic.Assembly("GRAB b\nGRAB a\nARRAY c\n")
		for range a.Detail.Elements {
			ic.Assembly("PUT 0\n")
		}
		ic.InOperatorFunction = true

		ic.SetFlag(function.Flag)

		ic.SetVariable("c", a)
		ic.SetVariable("a", a)
		ic.SetVariable("b", b)
	}
}

<|endoftext|>


<commit_before>package osutil

import "os"

// RootNames returns the result of /*.
func RootNames() []string {
	f, err := os.Open("/")
	if err != nil {
		panic(err)
	}

	names, err := f.Readdirnames(-1)
	f.Close()
	if err != nil {
		panic(err)
	}
	for i, name := range names {
		names[i] = "/" + name
	}
	return names
}
<commit_msg>Sort names in osutil.RootNames.<commit_after>package osutil

import (
	"os"
	"sort"
)

// RootNames returns the result of /*.
func RootNames() []string {
	f, err := os.Open("/")
	if err != nil {
		panic(err)
	}

	names, err := f.Readdirnames(-1)
	f.Close()
	if err != nil {
		panic(err)
	}
	sort.Strings(names)
	for i, name := range names {
		names[i] = "/" + name
	}
	return names
}
<|endoftext|>


<commit_before>package adapters

import (
        "encoding/json"
        "strconv"
        "strings"
        )

type WundergroundResponseStruct struct {
    Version string `json:"version"`
    TermsOfService string `json:"termsofService"`
    Features map[string]int
}

type WundergroundImageStruct struct {
    Url string `json:"url"`
    Title string `json:"title"`
    Link string `json:"link"`
}

type WundergroundLocationStruct struct {
    Full string `json:"full"`
    City string `json:"city"`
    State string `json:"state"`
    StateName string `json:"state_name"`
    Country string `json:"country"`
    CountryIso3166 string `json:"country_iso3166"`
    Zip string `json:"zip"`
    Latitude string `json:"latitude"`
    Longitude string `json:"longitude"`
    Elevation string `json:"elevation"`
}

type WundergroundCurrentObservationStruct struct {
    Image WundergroundImageStruct                   `json:"image"`
    DisplayLocation WundergroundLocationStruct      `json:"display_location"`
    ObservationLocation WundergroundLocationStruct  `json:"observation_location"`
    StationId string                                `json:"station_id"`
    ObservationTime string                          `json:"observation_time"`
    ObservationTimeRfc822 string                    `json:"observation_time_tfc822"`
    ObservationEpoch string                         `json:"observation_epoch"`
    LocalTimeRfc822 string                          `json:"local_time_rfc822"`
    LocalEpoch string                               `json:"local_epoch"`
    LocalTzShort string                             `json:"local_tz_short"`
    LocalTzLong string                              `json:"local_tz_long"`
    LocalTzOffset string                            `json:"local_tz_offset"`
    Weather string                                  `json:"weather"`
    TemperatureString string                        `json:"temperature_string"`
    TempF float64                                   `json:"temp_f"`
    TempC float64                                   `json:"temp_c"`
    RelativeHumidity string                         `json:"relative_humidity"`
    WindString string                               `json:"wind_string"`
    WindDir string                                  `json:"wind_dir"`
    WindDegrees int                                 `json:"wind_degrees"`
    WindMph float64                                 `json:"wind_mph"`
    WindGustMph string                              `json:"wind_gust_mph"`
    WindKph float64                                 `json:"wind_kph"`
    WindGustKph string                              `json:"wind_gust_kph"`
    PressureMb string                               `json:"pressure_mb"`
    PressureIn string                               `json:"pressure_in"`
    PressureTrend string                            `json:"pressure_trend"`
    DewpointString string                           `json:"dewpoint_string"`
    DewpointF int                                   `json:"dewpoint_f"`
    DewpointC int                                   `json:"dewpoint_c"`
    HeatIndexString string                          `json:"heat_index_string"`
    HeatIndexF string                               `json:"heat_index_f"`
    HeatIndexC string                               `json:"heat_index_c"`
    WindChillString string                          `json:"windchill_string"`
    WindChillF string                               `json:"windchill_f"`
    WindChillC string                               `json:"windchill_c"`
    FeelsLikeString string                          `json:"feelslike_string"`
    FeelsLikeF string                               `json:"feelslike_f"`
    FeelsLikeC string                               `json:"feelslike_c"`
    VisibilityMi string                             `json:"visibility_mi"`
    VisibilityKm string                             `json:"visibility_km"`
    SolarRadiation string                           `json:"solarradiation"`
    UV string                                       `json:"UV"`
    Precip1hrString string                          `json:"precip_1hr_string"`
    Precip1hrIn string                              `json:"precip_1hr_in"`
    Precip1hrMetric string                          `json:"precip_1hr_metric"`
    PrecipTodayString string                        `json:"precip_today_string"`
    PrecipTodayIn string                            `json:"precip_today_in"`
    PrecipTodayMetric string                        `json:"precip_today_metric"`
    Icon string                                     `json:"icon"`
    IconUrl string                                  `json:"icon_url"`
    ForecastUrl string                              `json:"forecast_url"`
    HistoryUrl string                               `json:"history_url"`
    ObUrl string                                    `json:"ob_url"`
}

type WundergroundWeatherStruct struct {
    Response WundergroundResponseStruct `json:"response"`
    CurrentObservation WundergroundCurrentObservationStruct `json:"current_observation"`
}

func wundergroundDecode (s string) WundergroundWeatherStruct {
    var byteString = []byte(s)
    var data = WundergroundWeatherStruct{}

    json.Unmarshal(byteString, &data)

    return data
}

func WundergroundAdaptCurrentWeather(jsonString string) MeasurementArray {
    var data = wundergroundDecode(jsonString)
    var measurements MeasurementArray

    humidity_raw := strings.TrimRight(strings.TrimSpace(data.CurrentObservation.RelativeHumidity), "%")
    pressure_raw := strings.TrimSpace(data.CurrentObservation.PressureMb)
    precipitation_raw := strings.TrimSpace(data.CurrentObservation.PrecipTodayMetric)
    temp_raw := data.CurrentObservation.TempC
    wind_raw := data.CurrentObservation.WindKph

    humidity, _ := strconv.ParseFloat(humidity_raw, 32)
    pressure, _ := strconv.ParseFloat(pressure_raw, 32)
    precipitation, _ := strconv.ParseFloat(precipitation_raw, 32)
    temp := float64(temp_raw)
    wind := float64(wind_raw)

    measurements = append(measurements, MeasurementSchema{Humidity:humidity, Precipitation:precipitation, Pressure:pressure, Temp:temp, Wind:wind})

    return measurements
}
<commit_msg>Исправления для wunderground<commit_after>package adapters

import (
        "encoding/json"
        "strconv"
        "strings"
        )

type WundergroundResponseStruct struct {
    Version string `json:"version"`
    TermsOfService string `json:"termsofService"`
    Features map[string]int
}

type WundergroundImageStruct struct {
    Url string `json:"url"`
    Title string `json:"title"`
    Link string `json:"link"`
}

type WundergroundLocationStruct struct {
    Full string `json:"full"`
    City string `json:"city"`
    State string `json:"state"`
    StateName string `json:"state_name"`
    Country string `json:"country"`
    CountryIso3166 string `json:"country_iso3166"`
    Zip string `json:"zip"`
    Latitude string `json:"latitude"`
    Longitude string `json:"longitude"`
    Elevation string `json:"elevation"`
}

type WundergroundCurrentObservationStruct struct {
    Image WundergroundImageStruct                   `json:"image"`
    DisplayLocation WundergroundLocationStruct      `json:"display_location"`
    ObservationLocation WundergroundLocationStruct  `json:"observation_location"`
    StationId string                                `json:"station_id"`
    ObservationTime string                          `json:"observation_time"`
    ObservationTimeRfc822 string                    `json:"observation_time_tfc822"`
    ObservationEpoch string                         `json:"observation_epoch"`
    LocalTimeRfc822 string                          `json:"local_time_rfc822"`
    LocalEpoch string                               `json:"local_epoch"`
    LocalTzShort string                             `json:"local_tz_short"`
    LocalTzLong string                              `json:"local_tz_long"`
    LocalTzOffset string                            `json:"local_tz_offset"`
    Weather string                                  `json:"weather"`
    TemperatureString string                        `json:"temperature_string"`
    TempF float64                                   `json:"temp_f"`
    TempC float64                                   `json:"temp_c"`
    RelativeHumidity string                         `json:"relative_humidity"`
    WindString string                               `json:"wind_string"`
    WindDir string                                  `json:"wind_dir"`
    WindDegrees int                                 `json:"wind_degrees"`
    WindMph float64                                 `json:"wind_mph"`
    WindGustMph float64                             `json:"wind_gust_mph"`
    WindKph float64                                 `json:"wind_kph"`
    WindGustKph float64                             `json:"wind_gust_kph"`
    PressureMb string                               `json:"pressure_mb"`
    PressureIn string                               `json:"pressure_in"`
    PressureTrend string                            `json:"pressure_trend"`
    DewpointString string                           `json:"dewpoint_string"`
    DewpointF float64                               `json:"dewpoint_f"`
    DewpointC float64                               `json:"dewpoint_c"`
    HeatIndexString string                          `json:"heat_index_string"`
    HeatIndexF string                               `json:"heat_index_f"`
    HeatIndexC string                               `json:"heat_index_c"`
    WindChillString string                          `json:"windchill_string"`
    WindChillF string                               `json:"windchill_f"`
    WindChillC string                               `json:"windchill_c"`
    FeelsLikeString string                          `json:"feelslike_string"`
    FeelsLikeF string                               `json:"feelslike_f"`
    FeelsLikeC string                               `json:"feelslike_c"`
    VisibilityMi string                             `json:"visibility_mi"`
    VisibilityKm string                             `json:"visibility_km"`
    SolarRadiation string                           `json:"solarradiation"`
    UV string                                       `json:"UV"`
    Precip1hrString string                          `json:"precip_1hr_string"`
    Precip1hrIn string                              `json:"precip_1hr_in"`
    Precip1hrMetric string                          `json:"precip_1hr_metric"`
    PrecipTodayString string                        `json:"precip_today_string"`
    PrecipTodayIn string                            `json:"precip_today_in"`
    PrecipTodayMetric string                        `json:"precip_today_metric"`
    Icon string                                     `json:"icon"`
    IconUrl string                                  `json:"icon_url"`
    ForecastUrl string                              `json:"forecast_url"`
    HistoryUrl string                               `json:"history_url"`
    ObUrl string                                    `json:"ob_url"`
}

type WundergroundWeatherStruct struct {
    Response WundergroundResponseStruct `json:"response"`
    CurrentObservation WundergroundCurrentObservationStruct `json:"current_observation"`
}

func wundergroundDecode (s string) WundergroundWeatherStruct {
    var byteString = []byte(s)
    var data = WundergroundWeatherStruct{}

    json.Unmarshal(byteString, &data)

    return data
}

func WundergroundAdaptCurrentWeather(jsonString string) MeasurementArray {
    var data = wundergroundDecode(jsonString)
    var measurements MeasurementArray

    humidity_raw := strings.TrimRight(strings.TrimSpace(data.CurrentObservation.RelativeHumidity), "%")
    pressure_raw := strings.TrimSpace(data.CurrentObservation.PressureMb)
    precipitation_raw := strings.TrimSpace(data.CurrentObservation.PrecipTodayMetric)
    temp_raw := data.CurrentObservation.TempC
    wind_raw := data.CurrentObservation.WindKph

    humidity, _ := strconv.ParseFloat(humidity_raw, 64)
    pressure, _ := strconv.ParseFloat(pressure_raw, 64)
    precipitation, _ := strconv.ParseFloat(precipitation_raw, 64)
    temp := float64(temp_raw)
    wind := float64(wind_raw)

    measurements = append(measurements, MeasurementSchema{Humidity:humidity, Precipitation:precipitation, Pressure:pressure, Temp:temp, Wind:wind})

    return measurements
}
<|endoftext|>


<commit_before>package agent

import (
	"net/http"
	"net/url"
	"strconv"
	"strings"

	"github.com/hashicorp/consul/agent/structs"
	"github.com/hashicorp/consul/api"
)

const (
	serviceHealth = "service"
	connectHealth = "connect"
	ingressHealth = "ingress"
)

func (s *HTTPHandlers) HealthChecksInState(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ChecksInStateRequest{}
	if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	s.parseSource(req, &args.Source)
	args.NodeMetaFilters = s.parseMetaFilter(req)
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the service name
	var err error
	args.State, err = getPathSuffixUnescaped(req.URL.Path, "/v1/health/state/")
	if err != nil {
		return nil, err
	}
	if args.State == "" {
		return nil, BadRequestError{Reason: "Missing check state"}
	}

	// Make the RPC request
	var out structs.IndexedHealthChecks
	defer setMeta(resp, &out.QueryMeta)
RETRY_ONCE:
	if err := s.agent.RPC("Health.ChecksInState", &args, &out); err != nil {
		return nil, err
	}
	if args.QueryOptions.AllowStale && args.MaxStaleDuration > 0 && args.MaxStaleDuration < out.LastContact {
		args.AllowStale = false
		args.MaxStaleDuration = 0
		goto RETRY_ONCE
	}
	out.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()

	// Use empty list instead of nil
	if out.HealthChecks == nil {
		out.HealthChecks = make(structs.HealthChecks, 0)
	}
	for i, c := range out.HealthChecks {
		if c.ServiceTags == nil {
			clone := *c
			clone.ServiceTags = make([]string, 0)
			out.HealthChecks[i] = &clone
		}
	}
	return out.HealthChecks, nil
}

func (s *HTTPHandlers) HealthNodeChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.NodeSpecificRequest{}
	if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the service name
	args.Node = strings.TrimPrefix(req.URL.Path, "/v1/health/node/")
	if args.Node == "" {
		return nil, BadRequestError{Reason: "Missing node name"}
	}

	// Make the RPC request
	var out structs.IndexedHealthChecks
	defer setMeta(resp, &out.QueryMeta)
RETRY_ONCE:
	if err := s.agent.RPC("Health.NodeChecks", &args, &out); err != nil {
		return nil, err
	}
	if args.QueryOptions.AllowStale && args.MaxStaleDuration > 0 && args.MaxStaleDuration < out.LastContact {
		args.AllowStale = false
		args.MaxStaleDuration = 0
		goto RETRY_ONCE
	}
	out.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()

	// Use empty list instead of nil
	if out.HealthChecks == nil {
		out.HealthChecks = make(structs.HealthChecks, 0)
	}
	for i, c := range out.HealthChecks {
		if c.ServiceTags == nil {
			clone := *c
			clone.ServiceTags = make([]string, 0)
			out.HealthChecks[i] = &clone
		}
	}
	return out.HealthChecks, nil
}

func (s *HTTPHandlers) HealthServiceChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ServiceSpecificRequest{}
	if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	s.parseSource(req, &args.Source)
	args.NodeMetaFilters = s.parseMetaFilter(req)
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the service name
	args.ServiceName = strings.TrimPrefix(req.URL.Path, "/v1/health/checks/")
	if args.ServiceName == "" {
		return nil, BadRequestError{Reason: "Missing service name"}
	}

	// Make the RPC request
	var out structs.IndexedHealthChecks
	defer setMeta(resp, &out.QueryMeta)
RETRY_ONCE:
	if err := s.agent.RPC("Health.ServiceChecks", &args, &out); err != nil {
		return nil, err
	}
	if args.QueryOptions.AllowStale && args.MaxStaleDuration > 0 && args.MaxStaleDuration < out.LastContact {
		args.AllowStale = false
		args.MaxStaleDuration = 0
		goto RETRY_ONCE
	}
	out.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()

	// Use empty list instead of nil
	if out.HealthChecks == nil {
		out.HealthChecks = make(structs.HealthChecks, 0)
	}
	for i, c := range out.HealthChecks {
		if c.ServiceTags == nil {
			clone := *c
			clone.ServiceTags = make([]string, 0)
			out.HealthChecks[i] = &clone
		}
	}
	return out.HealthChecks, nil
}

// HealthIngressServiceNodes should return "all the healthy ingress gateway instances
// that I can use to access this connect-enabled service without mTLS".
func (s *HTTPHandlers) HealthIngressServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	return s.healthServiceNodes(resp, req, ingressHealth)
}

// HealthConnectServiceNodes should return "all healthy connect-enabled
// endpoints (e.g. could be side car proxies or native instances) for this
// service so I can connect with mTLS".
func (s *HTTPHandlers) HealthConnectServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	return s.healthServiceNodes(resp, req, connectHealth)
}

// HealthServiceNodes should return "all the healthy instances of this service
// registered so I can connect directly to them".
func (s *HTTPHandlers) HealthServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	return s.healthServiceNodes(resp, req, serviceHealth)
}

func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Request, healthType string) (interface{}, error) {
	// Set default DC
	args := structs.ServiceSpecificRequest{}
	if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	s.parseSource(req, &args.Source)
	args.NodeMetaFilters = s.parseMetaFilter(req)
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Check for tags
	params := req.URL.Query()
	if _, ok := params["tag"]; ok {
		args.ServiceTags = params["tag"]
		args.TagFilter = true
	}

	// Determine the prefix
	var prefix string
	switch healthType {
	case connectHealth:
		prefix = "/v1/health/connect/"
		args.Connect = true
	case ingressHealth:
		prefix = "/v1/health/ingress/"
		args.Ingress = true
	default:
		// serviceHealth is the default type
		prefix = "/v1/health/service/"
	}

	// Pull out the service name
	args.ServiceName = strings.TrimPrefix(req.URL.Path, prefix)
	if args.ServiceName == "" {
		return nil, BadRequestError{Reason: "Missing service name"}
	}

	out, md, err := s.agent.rpcClientHealth.ServiceNodes(req.Context(), args)
	if err != nil {
		return nil, err
	}

	if args.QueryOptions.UseCache {
		setCacheMeta(resp, &md)
	}
	out.QueryMeta.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()
	setMeta(resp, &out.QueryMeta)

	// FIXME: argument parsing should be done before performing the rpc
	// Filter to only passing if specified
	filter, err := getBoolQueryParam(params, api.HealthPassing)
	if err != nil {
		return nil, BadRequestError{Reason: "Invalid value for ?passing"}
	}

	// FIXME: remove filterNonPassing, replace with nodes.Filter, which is used by DNSServer
	if filter {
		out.Nodes = filterNonPassing(out.Nodes)
	}

	// Translate addresses after filtering so we don't waste effort.
	s.agent.TranslateAddresses(args.Datacenter, out.Nodes, TranslateAddressAcceptAny)

	// Use empty list instead of nil
	if out.Nodes == nil {
		out.Nodes = make(structs.CheckServiceNodes, 0)
	}
	for i := range out.Nodes {
		if out.Nodes[i].Checks == nil {
			out.Nodes[i].Checks = make(structs.HealthChecks, 0)
		}
		for j, c := range out.Nodes[i].Checks {
			if c.ServiceTags == nil {
				clone := *c
				clone.ServiceTags = make([]string, 0)
				out.Nodes[i].Checks[j] = &clone
			}
		}
		if out.Nodes[i].Service != nil && out.Nodes[i].Service.Tags == nil {
			clone := *out.Nodes[i].Service
			clone.Tags = make([]string, 0)
			out.Nodes[i].Service = &clone
		}
	}
	return out.Nodes, nil
}

func getBoolQueryParam(params url.Values, key string) (bool, error) {
	var param bool
	if _, ok := params[key]; ok {
		val := params.Get(key)
		// Orginally a comment declared this check should be removed after Consul
		// 0.10, to no longer support using ?passing without a value. However, I
		// think this is a reasonable experience for a user and so am keeping it
		// here.
		if val == "" {
			param = true
		} else {
			var err error
			param, err = strconv.ParseBool(val)
			if err != nil {
				return false, err
			}
		}
	}
	return param, nil
}

// filterNonPassing is used to filter out any nodes that have check that are not passing
func filterNonPassing(nodes structs.CheckServiceNodes) structs.CheckServiceNodes {
	n := len(nodes)

	// Make a copy of the cached nodes rather than operating on the cache directly
	out := append(nodes[:0:0], nodes...)

OUTER:
	for i := 0; i < n; i++ {
		node := out[i]
		for _, check := range node.Checks {
			if check.Status != api.HealthPassing {
				out[i], out[n-1] = out[n-1], structs.CheckServiceNode{}
				n--
				i--
				continue OUTER
			}
		}
	}
	return out[:n]
}
<commit_msg>URL-encode/decode resource names for HTTP API part 5 (#12297)<commit_after>package agent

import (
	"net/http"
	"net/url"
	"strconv"

	"github.com/hashicorp/consul/agent/structs"
	"github.com/hashicorp/consul/api"
)

const (
	serviceHealth = "service"
	connectHealth = "connect"
	ingressHealth = "ingress"
)

func (s *HTTPHandlers) HealthChecksInState(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ChecksInStateRequest{}
	if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	s.parseSource(req, &args.Source)
	args.NodeMetaFilters = s.parseMetaFilter(req)
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the service name
	var err error
	args.State, err = getPathSuffixUnescaped(req.URL.Path, "/v1/health/state/")
	if err != nil {
		return nil, err
	}
	if args.State == "" {
		return nil, BadRequestError{Reason: "Missing check state"}
	}

	// Make the RPC request
	var out structs.IndexedHealthChecks
	defer setMeta(resp, &out.QueryMeta)
RETRY_ONCE:
	if err := s.agent.RPC("Health.ChecksInState", &args, &out); err != nil {
		return nil, err
	}
	if args.QueryOptions.AllowStale && args.MaxStaleDuration > 0 && args.MaxStaleDuration < out.LastContact {
		args.AllowStale = false
		args.MaxStaleDuration = 0
		goto RETRY_ONCE
	}
	out.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()

	// Use empty list instead of nil
	if out.HealthChecks == nil {
		out.HealthChecks = make(structs.HealthChecks, 0)
	}
	for i, c := range out.HealthChecks {
		if c.ServiceTags == nil {
			clone := *c
			clone.ServiceTags = make([]string, 0)
			out.HealthChecks[i] = &clone
		}
	}
	return out.HealthChecks, nil
}

func (s *HTTPHandlers) HealthNodeChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.NodeSpecificRequest{}
	if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the service name
	var err error
	args.Node, err = getPathSuffixUnescaped(req.URL.Path, "/v1/health/node/")
	if err != nil {
		return nil, err
	}
	if args.Node == "" {
		return nil, BadRequestError{Reason: "Missing node name"}
	}

	// Make the RPC request
	var out structs.IndexedHealthChecks
	defer setMeta(resp, &out.QueryMeta)
RETRY_ONCE:
	if err := s.agent.RPC("Health.NodeChecks", &args, &out); err != nil {
		return nil, err
	}
	if args.QueryOptions.AllowStale && args.MaxStaleDuration > 0 && args.MaxStaleDuration < out.LastContact {
		args.AllowStale = false
		args.MaxStaleDuration = 0
		goto RETRY_ONCE
	}
	out.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()

	// Use empty list instead of nil
	if out.HealthChecks == nil {
		out.HealthChecks = make(structs.HealthChecks, 0)
	}
	for i, c := range out.HealthChecks {
		if c.ServiceTags == nil {
			clone := *c
			clone.ServiceTags = make([]string, 0)
			out.HealthChecks[i] = &clone
		}
	}
	return out.HealthChecks, nil
}

func (s *HTTPHandlers) HealthServiceChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Set default DC
	args := structs.ServiceSpecificRequest{}
	if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	s.parseSource(req, &args.Source)
	args.NodeMetaFilters = s.parseMetaFilter(req)
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Pull out the service name
	var err error
	args.ServiceName, err = getPathSuffixUnescaped(req.URL.Path, "/v1/health/checks/")
	if err != nil {
		return nil, err
	}
	if args.ServiceName == "" {
		return nil, BadRequestError{Reason: "Missing service name"}
	}

	// Make the RPC request
	var out structs.IndexedHealthChecks
	defer setMeta(resp, &out.QueryMeta)
RETRY_ONCE:
	if err := s.agent.RPC("Health.ServiceChecks", &args, &out); err != nil {
		return nil, err
	}
	if args.QueryOptions.AllowStale && args.MaxStaleDuration > 0 && args.MaxStaleDuration < out.LastContact {
		args.AllowStale = false
		args.MaxStaleDuration = 0
		goto RETRY_ONCE
	}
	out.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()

	// Use empty list instead of nil
	if out.HealthChecks == nil {
		out.HealthChecks = make(structs.HealthChecks, 0)
	}
	for i, c := range out.HealthChecks {
		if c.ServiceTags == nil {
			clone := *c
			clone.ServiceTags = make([]string, 0)
			out.HealthChecks[i] = &clone
		}
	}
	return out.HealthChecks, nil
}

// HealthIngressServiceNodes should return "all the healthy ingress gateway instances
// that I can use to access this connect-enabled service without mTLS".
func (s *HTTPHandlers) HealthIngressServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	return s.healthServiceNodes(resp, req, ingressHealth)
}

// HealthConnectServiceNodes should return "all healthy connect-enabled
// endpoints (e.g. could be side car proxies or native instances) for this
// service so I can connect with mTLS".
func (s *HTTPHandlers) HealthConnectServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	return s.healthServiceNodes(resp, req, connectHealth)
}

// HealthServiceNodes should return "all the healthy instances of this service
// registered so I can connect directly to them".
func (s *HTTPHandlers) HealthServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
	return s.healthServiceNodes(resp, req, serviceHealth)
}

func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Request, healthType string) (interface{}, error) {
	// Set default DC
	args := structs.ServiceSpecificRequest{}
	if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
		return nil, err
	}
	s.parseSource(req, &args.Source)
	args.NodeMetaFilters = s.parseMetaFilter(req)
	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
		return nil, nil
	}

	// Check for tags
	params := req.URL.Query()
	if _, ok := params["tag"]; ok {
		args.ServiceTags = params["tag"]
		args.TagFilter = true
	}

	// Determine the prefix
	var prefix string
	switch healthType {
	case connectHealth:
		prefix = "/v1/health/connect/"
		args.Connect = true
	case ingressHealth:
		prefix = "/v1/health/ingress/"
		args.Ingress = true
	default:
		// serviceHealth is the default type
		prefix = "/v1/health/service/"
	}

	// Pull out the service name
	var err error
	args.ServiceName, err = getPathSuffixUnescaped(req.URL.Path, prefix)
	if err != nil {
		return nil, err
	}
	if args.ServiceName == "" {
		return nil, BadRequestError{Reason: "Missing service name"}
	}

	out, md, err := s.agent.rpcClientHealth.ServiceNodes(req.Context(), args)
	if err != nil {
		return nil, err
	}

	if args.QueryOptions.UseCache {
		setCacheMeta(resp, &md)
	}
	out.QueryMeta.ConsistencyLevel = args.QueryOptions.ConsistencyLevel()
	setMeta(resp, &out.QueryMeta)

	// FIXME: argument parsing should be done before performing the rpc
	// Filter to only passing if specified
	filter, err := getBoolQueryParam(params, api.HealthPassing)
	if err != nil {
		return nil, BadRequestError{Reason: "Invalid value for ?passing"}
	}

	// FIXME: remove filterNonPassing, replace with nodes.Filter, which is used by DNSServer
	if filter {
		out.Nodes = filterNonPassing(out.Nodes)
	}

	// Translate addresses after filtering so we don't waste effort.
	s.agent.TranslateAddresses(args.Datacenter, out.Nodes, TranslateAddressAcceptAny)

	// Use empty list instead of nil
	if out.Nodes == nil {
		out.Nodes = make(structs.CheckServiceNodes, 0)
	}
	for i := range out.Nodes {
		if out.Nodes[i].Checks == nil {
			out.Nodes[i].Checks = make(structs.HealthChecks, 0)
		}
		for j, c := range out.Nodes[i].Checks {
			if c.ServiceTags == nil {
				clone := *c
				clone.ServiceTags = make([]string, 0)
				out.Nodes[i].Checks[j] = &clone
			}
		}
		if out.Nodes[i].Service != nil && out.Nodes[i].Service.Tags == nil {
			clone := *out.Nodes[i].Service
			clone.Tags = make([]string, 0)
			out.Nodes[i].Service = &clone
		}
	}
	return out.Nodes, nil
}

func getBoolQueryParam(params url.Values, key string) (bool, error) {
	var param bool
	if _, ok := params[key]; ok {
		val := params.Get(key)
		// Orginally a comment declared this check should be removed after Consul
		// 0.10, to no longer support using ?passing without a value. However, I
		// think this is a reasonable experience for a user and so am keeping it
		// here.
		if val == "" {
			param = true
		} else {
			var err error
			param, err = strconv.ParseBool(val)
			if err != nil {
				return false, err
			}
		}
	}
	return param, nil
}

// filterNonPassing is used to filter out any nodes that have check that are not passing
func filterNonPassing(nodes structs.CheckServiceNodes) structs.CheckServiceNodes {
	n := len(nodes)

	// Make a copy of the cached nodes rather than operating on the cache directly
	out := append(nodes[:0:0], nodes...)

OUTER:
	for i := 0; i < n; i++ {
		node := out[i]
		for _, check := range node.Checks {
			if check.Status != api.HealthPassing {
				out[i], out[n-1] = out[n-1], structs.CheckServiceNode{}
				n--
				i--
				continue OUTER
			}
		}
	}
	return out[:n]
}
<|endoftext|>


<commit_before>package annotations

import (
	"errors"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/influx6/faux/fmtwriter"
	"github.com/influx6/moz"
	"github.com/influx6/moz/ast"
	"github.com/influx6/moz/gen"
)

var (
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterTypesForAnnotationGenerator)
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterStructTypesForAnnotationGenerator)
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterPackageTypesForAnnotationGenerator)
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterInterfaceTypesForAnnotationGenerator)
)

// TemplaterStructTypesForAnnotationGenerator defines a struct level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterStructTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, ty ast.StructDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation  ast.AnnotationDeclaration
		PkgDeclr    ast.PackageDeclaration
		Package     ast.Package
		StructDeclr ast.StructDeclaration
	}{
		PkgDeclr:    pkgDeclr,
		Annotation:  an,
		Package:     pkg,
		StructDeclr: ty,
	})
}

// TemplaterInterfaceTypesForAnnotationGenerator defines a package level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterInterfaceTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, ty ast.InterfaceDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation     ast.AnnotationDeclaration
		PkgDeclr       ast.PackageDeclaration
		Package        ast.Package
		InterfaceDeclr ast.InterfaceDeclaration
	}{
		PkgDeclr:       pkgDeclr,
		Annotation:     an,
		Package:        pkg,
		InterfaceDeclr: ty,
	})
}

// TemplaterPackageTypesForAnnotationGenerator defines a package level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterPackageTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation ast.AnnotationDeclaration
		PkgDeclr   ast.PackageDeclaration
		Package    ast.Package
	}{
		PkgDeclr:   pkgDeclr,
		Annotation: an,
		Package:    pkg,
	})
}

// TemplaterTypesForAnnotationGenerator defines a package level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, ty ast.TypeDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation ast.AnnotationDeclaration
		TypeDeclr  ast.TypeDeclaration
		Package    ast.Package
		PkgDeclr   ast.PackageDeclaration
	}{
		Annotation: an,
		TypeDeclr:  ty,
		PkgDeclr:   pkgDeclr,
		Package:    pkg,
	})
}

func handleGeneration(toDir string, an ast.AnnotationDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package, binding interface{}) ([]gen.WriteDirective, error) {
	templaterID, ok := an.Params["id"]
	if !ok {
		return nil, errors.New("No templater id provided")
	}

	// Get all templaters AnnotationDeclaration.
	templaters := pkg.AnnotationsFor("templater")
	var targetTemplater ast.AnnotationDeclaration

	// Search for templater with associated ID, if not found, return error, if multiple found, use the first.
	for _, targetTemplater = range templaters {
		if targetTemplater.Params["id"] != templaterID {
			continue
		}

		break
	}

	var templateData string

	switch len(targetTemplater.Template) == 0 {
	case true:
		templateFilePath, ok := targetTemplater.Params["file"]
		if !ok && targetTemplater.Template == "" {
			return nil, errors.New("Expected Template from annotation or provide `file => 'path_to_template`")
		}

		baseDir := filepath.Dir(pkgDeclr.FilePath)
		templateFile := filepath.Join(baseDir, templateFilePath)

		data, err := ioutil.ReadFile(templateFile)
		if err != nil {
			return nil, fmt.Errorf("Failed to find template file: %+q", err)
		}

		templateData = string(data)
	case false:
		templateData = targetTemplater.Template
	}

	var directives []gen.WriteDirective

	genName := strings.ToLower(targetTemplater.Params["gen"])

	fileName, ok := an.Params["filename"]
	if !ok {
		fileName = fmt.Sprintf("%s_impl_gen.go", strings.ToLower(an.Name))
	}

	typeGen := gen.Block(gen.SourceTextWith(templateData, template.FuncMap{
		"sel":                 an.Param,
		"param":               an.Param,
		"attr":                an.Attr,
		"hasArg":              an.HasArg,
		"annotationDefer":     func() bool { return an.Defer },
		"annotationTemplate":  func() string { return an.Template },
		"annotationParams":    func() map[string]string { return an.Params },
		"annotationAttrs":     func() map[string]interface{} { return an.Attrs },
		"annotationArguments": func() []string { return an.Arguments },
		"targetSel":           targetTemplater.Param,
		"targetAttr":          targetTemplater.Attr,
		"targetHasArg":        targetTemplater.HasArg,
		"targetDefer":         func() bool { return targetTemplater.Defer },
		"targetTemplate":      func() string { return targetTemplater.Template },
		"targetArguments":     func() []string { return targetTemplater.Arguments },
		"targetParams":        func() map[string]string { return targetTemplater.Params },
		"targetAttrs":         func() map[string]interface{} { return targetTemplater.Attrs },
	}, binding))

	switch genName {
	case "partial_test.go":

		var packageName string

		switch len(an.Params["packageName"]) == 0 {
		case true:
			packageName = ast.WhichPackage(toDir, pkg)
		case false:
			packageName = targetTemplater.Params["packageName"]
		}

		packageName = fmt.Sprintf("%s_test", packageName)

		pkgGen := gen.Block(

			gen.Package(
				gen.Name(packageName),
				typeGen,
			),
		)

		directives = append(directives, gen.WriteDirective{
			FileName:     fileName,
			DontOverride: true,
			Writer:       fmtwriter.New(pkgGen, true, true),
		})

	case "partial.go":

		var packageName string

		switch len(an.Params["packageName"]) == 0 {
		case true:
			packageName = ast.WhichPackage(toDir, pkg)
		case false:
			packageName = targetTemplater.Params["packageName"]
		}

		pkgGen := gen.Block(

			gen.Package(
				gen.Name(packageName),
				typeGen,
			),
		)

		directives = append(directives, gen.WriteDirective{
			FileName:     fileName,
			DontOverride: true,
			Writer:       fmtwriter.New(pkgGen, true, true),
		})

	case "go":
		directives = append(directives, gen.WriteDirective{
			FileName:     fileName,
			DontOverride: true,

			Writer: fmtwriter.New(typeGen, true, true),
		})

	default:
		directives = append(directives, gen.WriteDirective{
			Writer:       typeGen,
			DontOverride: true,
			FileName:     fileName,
		})
	}

	return directives, nil
}
<commit_msg>Fix nil Attrs map<commit_after>package annotations

import (
	"errors"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/influx6/faux/fmtwriter"
	"github.com/influx6/moz"
	"github.com/influx6/moz/ast"
	"github.com/influx6/moz/gen"
)

var (
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterTypesForAnnotationGenerator)
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterStructTypesForAnnotationGenerator)
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterPackageTypesForAnnotationGenerator)
	_ = moz.RegisterAnnotation("templaterTypesFor", TemplaterInterfaceTypesForAnnotationGenerator)
)

// TemplaterStructTypesForAnnotationGenerator defines a struct level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterStructTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, ty ast.StructDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation  ast.AnnotationDeclaration
		PkgDeclr    ast.PackageDeclaration
		Package     ast.Package
		StructDeclr ast.StructDeclaration
	}{
		PkgDeclr:    pkgDeclr,
		Annotation:  an,
		Package:     pkg,
		StructDeclr: ty,
	})
}

// TemplaterInterfaceTypesForAnnotationGenerator defines a package level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterInterfaceTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, ty ast.InterfaceDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation     ast.AnnotationDeclaration
		PkgDeclr       ast.PackageDeclaration
		Package        ast.Package
		InterfaceDeclr ast.InterfaceDeclaration
	}{
		PkgDeclr:       pkgDeclr,
		Annotation:     an,
		Package:        pkg,
		InterfaceDeclr: ty,
	})
}

// TemplaterPackageTypesForAnnotationGenerator defines a package level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterPackageTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation ast.AnnotationDeclaration
		PkgDeclr   ast.PackageDeclaration
		Package    ast.Package
	}{
		PkgDeclr:   pkgDeclr,
		Annotation: an,
		Package:    pkg,
	})
}

// TemplaterTypesForAnnotationGenerator defines a package level annotation generator which builds a go package in
// root of the package by using the content it receives from the annotation has a template for its output.
// package.
// Templater provides access to typenames by providing a "sel" function that gives you access to all
// arguments provided by the associated Annotation "templaterForTypes", which provides description of
// the filename, and the types to be used to replace the generic placeholders.
//
// Annotation: @templaterTypesFor
//
// Example:
// 1. Create a template that uses the "Go" generator, identified with the id "Mob" which will
// generate template for all types by using a template from a @templater with id of "Mob", define
// @templater anywhere either in package, struct, type or interface level.
//
// @templater(id => Mob, gen => Go, {
//
//   func Add(m {{sel TYPE1}}, n {{sel TYPE2}}) {{sel TYPE3}} {
//
//   }
//
// })
//
// 2. Add @templaterTypesFor annotation on any level (Type, Struct, Interface, Package) to have the code
// generated from the details provided.
//
// @templaterTypesFor(id => Mob, filename => bob_gen.go, TYPE1 => int32, TYPE2 => int32, TYPE3 => int64)
// @templaterTypesFor(id => Mob, filename => bib_gen.go, TYPE1 => int, TYPE2 => int, TYPE3 => int64)
//
func TemplaterTypesForAnnotationGenerator(toDir string, an ast.AnnotationDeclaration, ty ast.TypeDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package) ([]gen.WriteDirective, error) {
	return handleGeneration(toDir, an, pkgDeclr, pkg, struct {
		Annotation ast.AnnotationDeclaration
		TypeDeclr  ast.TypeDeclaration
		Package    ast.Package
		PkgDeclr   ast.PackageDeclaration
	}{
		Annotation: an,
		TypeDeclr:  ty,
		PkgDeclr:   pkgDeclr,
		Package:    pkg,
	})
}

func handleGeneration(toDir string, an ast.AnnotationDeclaration, pkgDeclr ast.PackageDeclaration, pkg ast.Package, binding interface{}) ([]gen.WriteDirective, error) {
	templaterID, ok := an.Params["id"]
	if !ok {
		return nil, errors.New("No templater id provided")
	}

	// Get all templaters AnnotationDeclaration.
	templaters := pkg.AnnotationsFor("templater")
	var targetTemplater ast.AnnotationDeclaration

	// Search for templater with associated ID, if not found, return error, if multiple found, use the first.
	for _, targetTemplater = range templaters {
		if targetTemplater.Params["id"] != templaterID {
			continue
		}

		break
	}

	var templateData string

	switch len(targetTemplater.Template) == 0 {
	case true:
		templateFilePath, ok := targetTemplater.Params["file"]
		if !ok && targetTemplater.Template == "" {
			return nil, errors.New("Expected Template from annotation or provide `file => 'path_to_template`")
		}

		baseDir := filepath.Dir(pkgDeclr.FilePath)
		templateFile := filepath.Join(baseDir, templateFilePath)

		data, err := ioutil.ReadFile(templateFile)
		if err != nil {
			return nil, fmt.Errorf("Failed to find template file: %+q", err)
		}

		templateData = string(data)
	case false:
		templateData = targetTemplater.Template
	}

	var directives []gen.WriteDirective

	genName := strings.ToLower(targetTemplater.Params["gen"])

	fileName, ok := an.Params["filename"]
	if !ok {
		fileName = fmt.Sprintf("%s_impl_gen.go", strings.ToLower(an.Name))
	}

	typeGen := gen.Block(gen.SourceTextWith(templateData, template.FuncMap{
		"sel":                    an.Param,
		"params":                 an.Param,
		"attrs":                  an.Attr,
		"hasArg":                 an.HasArg,
		"annotationDefer":        func() bool { return an.Defer },
		"annotationTemplate":     func() string { return an.Template },
		"annotationParams":       func() map[string]string { return an.Params },
		"annotationAttrs":        func() map[string]interface{} { return an.Attrs },
		"annotationArguments":    func() []string { return an.Arguments },
		"targetSel":              targetTemplater.Param,
		"targetParams":           targetTemplater.Param,
		"targetAttrs":            targetTemplater.Attr,
		"targetHasArg":           targetTemplater.HasArg,
		"targetDefer":            func() bool { return targetTemplater.Defer },
		"targetTemplate":         func() string { return targetTemplater.Template },
		"targetArguments":        func() []string { return targetTemplater.Arguments },
		"targetAnnotationParams": func() map[string]string { return targetTemplater.Params },
		"targetAnnotationAttrs":  func() map[string]interface{} { return targetTemplater.Attrs },
	}, binding))

	switch genName {
	case "partial_test.go":

		var packageName string

		switch len(an.Params["packageName"]) == 0 {
		case true:
			packageName = ast.WhichPackage(toDir, pkg)
		case false:
			packageName = targetTemplater.Params["packageName"]
		}

		packageName = fmt.Sprintf("%s_test", packageName)

		pkgGen := gen.Block(

			gen.Package(
				gen.Name(packageName),
				typeGen,
			),
		)

		directives = append(directives, gen.WriteDirective{
			FileName:     fileName,
			DontOverride: true,
			Writer:       fmtwriter.New(pkgGen, true, true),
		})

	case "partial.go":

		var packageName string

		switch len(an.Params["packageName"]) == 0 {
		case true:
			packageName = ast.WhichPackage(toDir, pkg)
		case false:
			packageName = targetTemplater.Params["packageName"]
		}

		pkgGen := gen.Block(

			gen.Package(
				gen.Name(packageName),
				typeGen,
			),
		)

		directives = append(directives, gen.WriteDirective{
			FileName:     fileName,
			DontOverride: true,
			Writer:       fmtwriter.New(pkgGen, true, true),
		})

	case "go":
		directives = append(directives, gen.WriteDirective{
			FileName:     fileName,
			DontOverride: true,

			Writer: fmtwriter.New(typeGen, true, true),
		})

	default:
		directives = append(directives, gen.WriteDirective{
			Writer:       typeGen,
			DontOverride: true,
			FileName:     fileName,
		})
	}

	return directives, nil
}
<|endoftext|>


<commit_before>package todoist

import (
	"strings"
)

type Project struct {
	HaveID
	HaveParentID
	HaveIndent
	Collapsed      int      `json:"collapsed"`
	Color          int      `json:"color"`
	HasMoreNotes   bool     `json:"has_more_notes"`
	InboxProject   bool     `json:"inbox_project"`
	IsArchived     int      `json:"is_archived"`
	IsDeleted      int      `json:"is_deleted"`
	ItemOrder      int      `json:"item_order"`
	Name           string   `json:"name"`
	Shared         bool     `json:"shared"`
	ChildProject   *Project `json:"-"`
	BrotherProject *Project `json:"-"`
}

type Projects []Project

func (a Projects) Len() int           { return len(a) }
func (a Projects) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a Projects) Less(i, j int) bool { return a[i].ID < a[j].ID }

func (a Projects) At(i int) IDCarrier { return a[i] }

func (a Projects) GetIDByName(name string) int {
	for _, pjt := range a {
		if pjt.Name == name {
			return pjt.GetID()
		}
	}
	return 0
}

func (a Projects) GetIDsByName(name string, isAll bool) []int {
	ids := []int{}
	name = strings.ToLower(name)
	for _, pjt := range a {
		if strings.Contains(strings.ToLower(pjt.Name), name) {
			ids = append(ids, pjt.ID)
			if isAll {
				parentID := pjt.ID
				// Find all children which has the project as parent
				ids = append(ids, parentID)
				for _, id := range childProjectIDs(parentID, a) {
					ids = append(ids, id)
				}
			}
		}
	}
	return ids
}

func childProjectIDs(parentId int, projects Projects) []int {
	ids := []int{}
	for _, pjt := range projects {
		id, err := pjt.GetParentID()
		if err != nil {
			continue
		}

		if id == parentId {
			ids = append(ids, pjt.ID)
			for _, id := range childProjectIDs(pjt.ID, projects) {
				ids = append(ids, id)
			}
		}
	}
	return ids
}
<commit_msg>better slice to slice appending (avoiding unnecessary for-loop)<commit_after>package todoist

import (
	"strings"
)

type Project struct {
	HaveID
	HaveParentID
	HaveIndent
	Collapsed      int      `json:"collapsed"`
	Color          int      `json:"color"`
	HasMoreNotes   bool     `json:"has_more_notes"`
	InboxProject   bool     `json:"inbox_project"`
	IsArchived     int      `json:"is_archived"`
	IsDeleted      int      `json:"is_deleted"`
	ItemOrder      int      `json:"item_order"`
	Name           string   `json:"name"`
	Shared         bool     `json:"shared"`
	ChildProject   *Project `json:"-"`
	BrotherProject *Project `json:"-"`
}

type Projects []Project

func (a Projects) Len() int           { return len(a) }
func (a Projects) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a Projects) Less(i, j int) bool { return a[i].ID < a[j].ID }

func (a Projects) At(i int) IDCarrier { return a[i] }

func (a Projects) GetIDByName(name string) int {
	for _, pjt := range a {
		if pjt.Name == name {
			return pjt.GetID()
		}
	}
	return 0
}

func (a Projects) GetIDsByName(name string, isAll bool) []int {
	ids := []int{}
	name = strings.ToLower(name)
	for _, pjt := range a {
		if strings.Contains(strings.ToLower(pjt.Name), name) {
			ids = append(ids, pjt.ID)
			if isAll {
				parentID := pjt.ID
				// Find all children which has the project as parent
				ids = append(ids, parentID)
				ids = append(ids, childProjectIDs(parentID, a)...)
			}
		}
	}
	return ids
}

func childProjectIDs(parentId int, projects Projects) []int {
	ids := []int{}
	for _, pjt := range projects {
		id, err := pjt.GetParentID()
		if err != nil {
			continue
		}

		if id == parentId {
			ids = append(ids, pjt.ID)
			ids = append(ids, childProjectIDs(pjt.ID, projects)...)
		}
	}
	return ids
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"
	"net/mail"
	"encoding/json"
	"os"
	"os/signal"
	"log"
	"io/ioutil"
	"net/http"
	"html/template"
)

const (
	tasklist_template = "ui_template.html"
)

type Task struct {
	Description string
	Frequency   time.Duration
	Users       []User // already a list (future feature)
}
type User mail.Address
type TaskList map[string]Task

func main() {

	file := "tasks.json"
	tasks := loadFromJson(file)
	defer saveToJson(file, tasks)

	go uiServer(8080, tasks)
	// go handleGlobalContext(&ctx)

	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)
	    select {
	    case <-sig:
		    fmt.Println("\nExiting …")
	    }
}

func uiServer(port int, tasks *TaskList) {
	http.Handle("/", tasks)
	http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
	    http.ServeFile(w, r, r.URL.Path[1:])
	})
	http.ListenAndServe(fmt.Sprintf(":%d", port), nil)

}

func (tasks *TaskList) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	switch req.Method {
	case "GET":
		w.Header()["Content-Type"] = []string{"text/html"}
		ts, err := ioutil.ReadFile(tasklist_template)
		logFatal(err)
		t := template.Must(template.New("tasklist").Parse(string(ts)))

		t.Execute(w, tasks)

	case "POST":
		err := req.ParseForm()
		// err := json.Unmarshal()

		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}
	}

}

func loadFromJson(file string) *TaskList {
	b, err := ioutil.ReadFile(file)
	if err != nil {
		l := make(TaskList)
		return &l
	}
	var tasks TaskList
	err = json.Unmarshal(b, &tasks)
	logFatal(err)
	return &tasks
}

func saveToJson(file string, tasks *TaskList) {
	b, err := json.Marshal(tasks)

	logFatal(err)
	err = ioutil.WriteFile(file, b, 0644)
	logFatal(err)
}

func logFatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>go fmt commitment-system.go go ftw!<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"net/mail"
	"os"
	"os/signal"
	"time"
)

const (
	tasklist_template = "ui_template.html"
)

type Task struct {
	Description string
	Frequency   time.Duration
	Users       []User // already a list (future feature)
}
type User mail.Address
type TaskList map[string]Task

func main() {

	file := "tasks.json"
	tasks := loadFromJson(file)
	defer saveToJson(file, tasks)

	go uiServer(8080, tasks)
	// go handleGlobalContext(&ctx)

	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)
	select {
	case <-sig:
		fmt.Println("\nExiting …")
	}
}

func uiServer(port int, tasks *TaskList) {
	http.Handle("/", tasks)
	http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, r.URL.Path[1:])
	})
	http.ListenAndServe(fmt.Sprintf(":%d", port), nil)

}

func (tasks *TaskList) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	switch req.Method {
	case "GET":
		w.Header()["Content-Type"] = []string{"text/html"}
		ts, err := ioutil.ReadFile(tasklist_template)
		logFatal(err)
		t := template.Must(template.New("tasklist").Parse(string(ts)))

		t.Execute(w, tasks)

	case "POST":
		err := req.ParseForm()
		// err := json.Unmarshal()

		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}
	}

}

func loadFromJson(file string) *TaskList {
	b, err := ioutil.ReadFile(file)
	if err != nil {
		l := make(TaskList)
		return &l
	}
	var tasks TaskList
	err = json.Unmarshal(b, &tasks)
	logFatal(err)
	return &tasks
}

func saveToJson(file string, tasks *TaskList) {
	b, err := json.Marshal(tasks)

	logFatal(err)
	err = ioutil.WriteFile(file, b, 0644)
	logFatal(err)
}

func logFatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package routes

import (
	"net/http"

	"github.com/generationtux/brizo/app/handlers/web"
	"github.com/generationtux/brizo/auth"
	"github.com/go-zoo/bone"
	"github.com/urfave/negroni"
)

// mainRoutes registers the routes for the user interface
func mainRoutes() *bone.Mux {
	router := bone.New()

	// Home page
	router.GetFunc("/", web.RootHandler)

	// Javascript UI
	router.GetFunc("/app", web.UIHandler)
	router.GetFunc("/app/*", web.UIHandler)
	router.Get("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("ui/dist/"))))

	// Healthz endpoint
	router.GetFunc("/healthz", web.HealthzHandler)

	// OAuth endpoints
	router.GetFunc("/o/auth/login/github", web.AuthGithubHandler)
	router.GetFunc("/o/auth/callback/github", web.AuthGithubCallbackHandler)

	return router
}

// BuildRouter configures the application router
func BuildRouter() http.Handler {
	// other routes
	r := mainRoutes()

	// protected API routes
	authorizedAPI := authAPIRoutes()
	r.SubRoute("/api/v1", negroni.New(
		negroni.HandlerFunc(auth.APIMiddleware),
		negroni.Wrap(authorizedAPI),
	))

	// unprotected API routes
	openAPI := apiRoutes()
	r.SubRoute("/api/v1", openAPI)

	n := negroni.New()
	n.Use(negroni.NewLogger())
	n.Use(negroni.NewRecovery())
	n.UseHandler(r)

	return n
}
<commit_msg>serve favicon<commit_after>package routes

import (
	"net/http"

	"github.com/generationtux/brizo/app/handlers/web"
	"github.com/generationtux/brizo/auth"
	"github.com/go-zoo/bone"
	"github.com/urfave/negroni"
)

// mainRoutes registers the routes for the user interface
func mainRoutes() *bone.Mux {
	router := bone.New()

	// Home page
	router.GetFunc("/", web.RootHandler)
	router.GetFunc("/favicon-16x16.png", func(rw http.ResponseWriter, r *http.Request) {
		http.ServeFile(rw, r, "ui/favicon-16x16.png")
	})
	router.GetFunc("/favicon-32x32.png", func(rw http.ResponseWriter, r *http.Request) {
		http.ServeFile(rw, r, "ui/favicon-32x32.png")
	})

	// Javascript UI
	router.GetFunc("/app", web.UIHandler)
	router.GetFunc("/app/*", web.UIHandler)
	router.Get("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("ui/dist/"))))

	// Healthz endpoint
	router.GetFunc("/healthz", web.HealthzHandler)

	// OAuth endpoints
	router.GetFunc("/o/auth/login/github", web.AuthGithubHandler)
	router.GetFunc("/o/auth/callback/github", web.AuthGithubCallbackHandler)

	return router
}

// BuildRouter configures the application router
func BuildRouter() http.Handler {
	// other routes
	r := mainRoutes()

	// protected API routes
	authorizedAPI := authAPIRoutes()
	r.SubRoute("/api/v1", negroni.New(
		negroni.HandlerFunc(auth.APIMiddleware),
		negroni.Wrap(authorizedAPI),
	))

	// unprotected API routes
	openAPI := apiRoutes()
	r.SubRoute("/api/v1", openAPI)

	n := negroni.New()
	n.Use(negroni.NewLogger())
	n.Use(negroni.NewRecovery())
	n.UseHandler(r)

	return n
}
<|endoftext|>


<commit_before>package goMiddlewareChain

import (
	"net/http"

	"digital.fino/contractsafe-api/middleware"
	"github.com/julienschmidt/httprouter"
)

// RequestChainHandler chains all handler
func RequestChainHandler(responseHandler middleware.ResponseHandler, handlers ...middleware.Handler) httprouter.Handle {
	return httprouter.Handle(func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
		payload := middleware.Response{}

		// iterate all handlers
		for _, handler := range handlers {
			handler(&payload, request, params)
		}

		// pass responseHandler
		responseHandler(&payload, writer, request, params)
	})
}
<commit_msg>fix: remove own dependecies<commit_after>package goMiddlewareChain

import (
	"net/http"

	"github.com/julienschmidt/httprouter"
)

// RequestChainHandler chains all handler
func RequestChainHandler(responseHandler ResponseHandler, handlers ...Handler) httprouter.Handle {
	return httprouter.Handle(func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
		payload := Response{}

		// iterate all handlers
		for _, handler := range handlers {
			handler(&payload, request, params)
		}

		// pass responseHandler
		responseHandler(&payload, writer, request, params)
	})
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"path/filepath"
	"strconv"

	lua "github.com/anaminus/gopher-lua"
	"github.com/anaminus/rbxmk"
	"github.com/anaminus/rbxmk/formats"
	"github.com/anaminus/rbxmk/library"
	"github.com/anaminus/rbxmk/sources"
	"github.com/anaminus/snek"
)

// shortenPath transforms the given path so that it is relative to the working
// directory. Returns the original path if that fails.
func shortenPath(filename string) string {
	if wd, err := os.Getwd(); err == nil {
		if abs, err := filepath.Abs(filename); err == nil {
			if r, err := filepath.Rel(wd, abs); err == nil {
				filename = r
			}
		}
	}
	return filename
}

// ParseLuaValue parses a string into a Lua value. Numbers, bools, and nil are
// parsed into their respective types, and any other value is interpreted as a
// string.
func ParseLuaValue(s string) lua.LValue {
	switch s {
	case "true":
		return lua.LTrue
	case "false":
		return lua.LFalse
	case "nil":
		return lua.LNil
	}
	if number, err := strconv.ParseFloat(s, 64); err == nil {
		return lua.LNumber(number)
	}
	return lua.LString(s)
}

func init() {
	Program.Register(snek.Def{
		Name:      "run",
		Summary:   "Execute a script.",
		Arguments: `[ FILE ] [ ...VALUE ]`,
		Description: `
Receives a file to be executed as a Lua script. If "-" is given, then the script
will be read from stdin instead.

Remaining arguments are Lua values to be passed to the file. Numbers, bools, and
nil are parsed into their respective types in Lua, and any other value is
interpreted as a string. Within the script, these arguments can be received from
the ... operator.`,
		New: func() snek.Command { return &RunCommand{} },
	})
}

type RunCommand struct {
	Debug bool
	Init  func(rbxmk.State)
}

func (c *RunCommand) SetFlags(flags snek.FlagSet) {
	flags.BoolVar(&c.Debug, "debug", false, "Display stack traces when an error occurs.")
}

// Run is the entrypoint to the command for running scripts. init runs after the
// World envrionment is fully initialized and arguments have been pushed, and
// before the script runs.
func (c *RunCommand) Run(opt snek.Options) error {
	// Parse flags.
	if err := opt.ParseFlags(); err != nil {
		return err
	}
	args := opt.Args()
	if len(args) == 0 {
		opt.Usage()
		return nil
	}
	file := args[0]
	args = args[1:]

	// Initialize world.
	world := rbxmk.NewWorld(lua.NewState(lua.Options{
		SkipOpenLibs:        true,
		IncludeGoStackTrace: c.Debug,
	}))
	if wd, err := os.Getwd(); err == nil {
		// Working directory is an accessible root.
		world.FS.AddRoot(wd)
	}
	for _, f := range formats.All() {
		world.RegisterFormat(f())
	}
	for _, s := range sources.All() {
		world.RegisterSource(s())
	}
	for _, lib := range library.All() {
		if err := world.Open(lib); err != nil {
			return err
		}
	}

	world.State().SetGlobal("_RBXMK_VERSION", lua.LString(Version))

	// Add script arguments.
	for _, arg := range args {
		world.State().Push(ParseLuaValue(arg))
	}

	if c.Init != nil {
		c.Init(rbxmk.State{World: world, L: world.State()})
	}

	// Run stdin as script.
	if file == "-" {
		return world.DoFileHandle(opt.Stdin, "", len(args))
	}

	// Run file as script.
	filename := shortenPath(filepath.Clean(file))
	return world.DoFile(filename, len(args))
}
<commit_msg>Handle nil stdin file.<commit_after>package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"

	lua "github.com/anaminus/gopher-lua"
	"github.com/anaminus/rbxmk"
	"github.com/anaminus/rbxmk/formats"
	"github.com/anaminus/rbxmk/library"
	"github.com/anaminus/rbxmk/sources"
	"github.com/anaminus/snek"
)

// shortenPath transforms the given path so that it is relative to the working
// directory. Returns the original path if that fails.
func shortenPath(filename string) string {
	if wd, err := os.Getwd(); err == nil {
		if abs, err := filepath.Abs(filename); err == nil {
			if r, err := filepath.Rel(wd, abs); err == nil {
				filename = r
			}
		}
	}
	return filename
}

// ParseLuaValue parses a string into a Lua value. Numbers, bools, and nil are
// parsed into their respective types, and any other value is interpreted as a
// string.
func ParseLuaValue(s string) lua.LValue {
	switch s {
	case "true":
		return lua.LTrue
	case "false":
		return lua.LFalse
	case "nil":
		return lua.LNil
	}
	if number, err := strconv.ParseFloat(s, 64); err == nil {
		return lua.LNumber(number)
	}
	return lua.LString(s)
}

func init() {
	Program.Register(snek.Def{
		Name:      "run",
		Summary:   "Execute a script.",
		Arguments: `[ FILE ] [ ...VALUE ]`,
		Description: `
Receives a file to be executed as a Lua script. If "-" is given, then the script
will be read from stdin instead.

Remaining arguments are Lua values to be passed to the file. Numbers, bools, and
nil are parsed into their respective types in Lua, and any other value is
interpreted as a string. Within the script, these arguments can be received from
the ... operator.`,
		New: func() snek.Command { return &RunCommand{} },
	})
}

type RunCommand struct {
	Debug bool
	Init  func(rbxmk.State)
}

func (c *RunCommand) SetFlags(flags snek.FlagSet) {
	flags.BoolVar(&c.Debug, "debug", false, "Display stack traces when an error occurs.")
}

// Run is the entrypoint to the command for running scripts. init runs after the
// World envrionment is fully initialized and arguments have been pushed, and
// before the script runs.
func (c *RunCommand) Run(opt snek.Options) error {
	// Parse flags.
	if err := opt.ParseFlags(); err != nil {
		return err
	}
	args := opt.Args()
	if len(args) == 0 {
		opt.Usage()
		return nil
	}
	file := args[0]
	args = args[1:]

	// Initialize world.
	world := rbxmk.NewWorld(lua.NewState(lua.Options{
		SkipOpenLibs:        true,
		IncludeGoStackTrace: c.Debug,
	}))
	if wd, err := os.Getwd(); err == nil {
		// Working directory is an accessible root.
		world.FS.AddRoot(wd)
	}
	for _, f := range formats.All() {
		world.RegisterFormat(f())
	}
	for _, s := range sources.All() {
		world.RegisterSource(s())
	}
	for _, lib := range library.All() {
		if err := world.Open(lib); err != nil {
			return err
		}
	}

	world.State().SetGlobal("_RBXMK_VERSION", lua.LString(Version))

	// Add script arguments.
	for _, arg := range args {
		world.State().Push(ParseLuaValue(arg))
	}

	if c.Init != nil {
		c.Init(rbxmk.State{World: world, L: world.State()})
	}

	// Run stdin as script.
	if file == "-" {
		if opt.Stdin == nil {
			return fmt.Errorf("no file handle")
		}
		return world.DoFileHandle(opt.Stdin, "", len(args))
	}

	// Run file as script.
	filename := shortenPath(filepath.Clean(file))
	return world.DoFile(filename, len(args))
}
<|endoftext|>