func (es *ExpressionStats) ConsiderValue(val otto.Value) { // increment the count es.Count += 1 if val.IsNumber() { f, err := val.ToFloat() if err != nil { log.Printf("Error converting number to float %v", err) } else { // update the sum es.Sum += f // if this is smaller than anything we've seen so far update the min if f < es.Min { es.Min = f } // if this is larger than anything we've seen so far update the max if f > es.Max { es.Max = f } // update the average (perhaps wasteful, could be done once at the end // but i'd have to walk the whole tree again, for now will do update it each time es.Avg = es.Sum / float64(es.Count) // we incremented es.count in this function, can not divide by 0 } } }
// Converts an Otto value to a Go value. Handles all JSON-compatible types. func ottoToGo(value otto.Value) (interface{}, error) { if value.IsBoolean() { return value.ToBoolean() } else if value.IsNull() || value.IsUndefined() { return nil, nil } else if value.IsNumber() { return value.ToFloat() } else if value.IsString() { return value.ToString() } else { switch value.Class() { case "Array": return ottoToGoArray(value.Object()) } } return nil, fmt.Errorf("Unsupported Otto value: %v", value) }
func convertToPrimitive(v otto.Value) interface{} { if v.IsBoolean() { v_b, err := v.ToBoolean() if err != nil { log.Printf("Error converting to boolean") } return v_b } else if v.IsNumber() { v_f, err := v.ToFloat() if err != nil { log.Printf("Error converting to float") } return v_f } else { v_s, err := v.ToString() if err != nil { log.Printf("Error converting to boolean") } return v_s } return nil }
// Helper function to populate a sample structure with a single sample func (sr *SampleReader) getSample() (*Sample, error) { var err error var v otto.Value s := new(Sample) // Extract date field from javascript runtime v, err = sr.vm.Get("date") if err != nil { return nil, err } if !v.IsDefined() { return nil, errors.New("date not defined") } ds, err := v.ToString() if err != nil { return nil, err } s.Date, err = time.Parse("2006-01-02T15:04:05", ds) if err != nil { return nil, err } // Extract latitude field from javascript runtime v, err = sr.vm.Get("latitude") if err != nil { return nil, err } if !v.IsDefined() { return nil, errors.New("latitude not defined") } s.Latitude, err = v.ToFloat() if err != nil { return nil, err } // Extract longitude field from javascript runtime v, err = sr.vm.Get("longitude") if err != nil { return nil, err } if !v.IsDefined() { return nil, errors.New("longitude not defined") } s.Longitude, err = v.ToFloat() if err != nil { return nil, err } // Extract altitude field from javascript runtime v, err = sr.vm.Get("altitude") if err != nil { return nil, err } if !v.IsDefined() { return nil, errors.New("altitude not defined") } s.Altitude, err = v.ToFloat() if err != nil { return nil, err } // Extract value field from javascript runtime v, err = sr.vm.Get("value") if err != nil { return nil, err } if !v.IsDefined() { return nil, errors.New("value not defined") } s.Value, err = v.ToFloat() if err != nil { return nil, err } // Extract unit field from javascript runtime v, err = sr.vm.Get("unit") if err != nil { return nil, err } if !v.IsDefined() { return nil, errors.New("unit not defined") } s.Unit, err = v.ToString() if err != nil { return nil, err } return s, nil }