Search code examples
govariadic-functions

What is the best way to take in optional parameters in this case?


I have a function in my library to modify the state of a given light. When the inputted mode is flashing, I want to allow the caller to pass in the interval time, on time, off time, and some other parameters only neccesarry for the flashing light. What would be the best way to do this?

func (p *Printer) Light(light _light.Light, mode _light.Mode) error {
    // This light_mode is currently believed to be deprecated, leaving here commented in case it ends up being useful later.
    //command, err := mqtt.NewCommand(mqtt.System).AddCommandField("light_mode").AddParamField("on").JSON()
    //if err != nil {
    //  return err
    //}

    // https://github.com/Doridian/OpenBambuAPI/blob/main/mqtt.md#systemledctrl
    command := mqtt.NewCommand(mqtt.System).AddCommandField("ledctrl").AddField("led_node", light).AddField("led_mode", mode)
    // Add fields only used for mode "flashing" but required nonetheless
    command.AddField("led_on_time", 500)
    command.AddField("led_off_time", 500)
    command.AddField("loop_times", 1)
    command.AddField("interval_time", 1000)

    if err := p.mqttClient.Publish(command); err != nil {
        return fmt.Errorf("error setting light %s: %w", light, err)
    }

    return nil
}

I have though about possibly using a variadic argument for the times but I'm not a huge fan of the ambiguity in regards to the order of the inputted times.


Solution

  • you can use pointers:

    
    type Flashing struct {
        LedOnTime    int
        LedOffTime   int
        LoopTimes    int
        IntervalTime int
    }
    
    func (p *Printer) Light(light _light.Light, mode _light.Mode, flashing *Flashing) error {
        // This light_mode is currently believed to be deprecated, leaving here commented in case it ends up being useful later.
        //command, err := mqtt.NewCommand(mqtt.System).AddCommandField("light_mode").AddParamField("on").JSON()
        //if err != nil {
        //  return err
        //}
    
        // https://github.com/Doridian/OpenBambuAPI/blob/main/mqtt.md#systemledctrl
        command := mqtt.NewCommand(mqtt.System).AddCommandField("ledctrl").AddField("led_node", light).AddField("led_mode", mode)
        // Add fields only used for mode "flashing" but required nonetheless
        if flashing != nil {
            command.AddField("led_on_time", flashing.LedOnTime)
            command.AddField("led_off_time", flashing.LedOffTime)
            command.AddField("loop_times", flashing.LoopTimes)
            command.AddField("interval_time", flashing.IntervalTime)
        }
    
        if err := p.mqttClient.Publish(command); err != nil {
            return fmt.Errorf("error setting light %s: %w", light, err)
        }
    
        return nil
    }
    
    func main() {
        p := Printer{}
        err := p.Light(_light.Strong, _light.Normal, nil)
        if err != nil {
            log.Fatalln(err)
        }
        err = p.Light(_light.Weak, _light.Flashing, &Flashing{500, 500, 1, 1000})
        if err != nil {
            log.Fatalln(err)
        }
    }