Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix mavlink codegen enum methods #47

Merged
merged 1 commit into from
Mar 31, 2023

Conversation

sirno-baka
Copy link
Contributor

Bug while calling the MarshalText method for enum
Example:
(common.MAV_SYS_STATUS_SENSOR_3D_GYRO | common.MAV_SYS_STATUS_SENSOR_3D_ACCEL).MarshalText()

an error occurs because this value is not in labels_{{ENUM}}

I propose to return the hex value of the number.

@aler9
Copy link
Member

aler9 commented Mar 28, 2023

Hello, you're right about adding support for combined flags, however, TextUnmarshal() has been specifically requested by some users in order to convert strings into enums, and this PR breaks the feature.

Therefore, edit the PR in this way:

  • in MarshalText, return the hex dump if and only if there isn't an associated label:
func (e enum) MarshalText() ([]byte, error) {
    if l, ok := labels_{{ .Enum.Name }}[e]; ok {
        return []byte(l), nil
    }
    return []byte(strconv.FormatUint(uint64(e), 16)), nil
}
  • in UnmarshalText do the same:
func (e enum) UnmarshalText(text []byte) error {
	if rl, ok := reverseLabels_{{ .Enum.Name }}[string(text)]; ok {
		*e = rl
		return nil
	}
	hexInt, err := strconv.ParseUint(string(text), 16, 32)
	if err == nil {
		*e = {{ .Enum.Name }}(hexInt)
		return nil
	}
	return errors.New("invalid value")
}
  • Link String() to MarshalText() in order for them to have the same behavior:
func (e {{ .Enum.Name }}) String() string {
    val, _ := e.MarshalText()
   return string(val)
}

thanks

@sirno-baka
Copy link
Contributor Author

sirno-baka commented Mar 29, 2023

specifically requested by some users in order to convert strings into enums

If you need names, I can suggest this code:

type MAV_SYS_STATUS_SENSOR uint32

const (
	MAV_SYS_STATUS_SENSOR_3D_GYRO  MAV_SYS_STATUS_SENSOR = 1 << 0 // 0x01
	MAV_SYS_STATUS_SENSOR_3D_ACCEL MAV_SYS_STATUS_SENSOR = 1 << 1 // 0x02
)

var labels_MAV_SYS_STATUS_SENSOR = map[MAV_SYS_STATUS_SENSOR]string{
	MAV_SYS_STATUS_SENSOR_3D_GYRO:  "MAV_SYS_STATUS_SENSOR_3D_GYRO",
	MAV_SYS_STATUS_SENSOR_3D_ACCEL: "MAV_SYS_STATUS_SENSOR_3D_ACCEL",
}

func (e MAV_SYS_STATUS_SENSOR) MarshalText() ([]byte, error) {
	var names []string
	for mask, label := range labels_MAV_SYS_STATUS_SENSOR {
		if e&mask == mask {
			names = append(names, label)
		}
	}
	return []byte(strings.Join(names, " | ")), nil
}

func (e *MAV_SYS_STATUS_SENSOR) UnmarshalText(text []byte) error {
	labels := strings.Split(string(text), " | ")
	var mask MAV_SYS_STATUS_SENSOR
	for _, label := range labels {
		found := false
		for value, l := range labels_MAV_SYS_STATUS_SENSOR {
			if l == label {
				mask |= value
				found = true
				break
			}
		}
		if !found {
			return fmt.Errorf("invalid label '%s'", label)
		}
	}
	*e = mask
	return nil
}

func (e MAV_SYS_STATUS_SENSOR) String() string {
	val, _ := e.MarshalText()
	return string(val)
}

Tests:

value := MAV_SYS_STATUS_SENSOR_3D_GYRO | MAV_SYS_STATUS_SENSOR_3D_ACCEL
byteMarshal, _ := value.MarshalText()
fmt.Println(string(byteMarshal)) // "MAV_SYS_STATUS_SENSOR_3D_GYRO | MAV_SYS_STATUS_SENSOR_3D_ACCEL"  <nil>

value = MAV_SYS_STATUS_SENSOR_3D_GYRO
fmt.Println(value.String()) // "MAV_SYS_STATUS_SENSOR_3D_GYRO"

var sens MAV_SYS_STATUS_SENSOR
err := sens.UnmarshalText([]byte("MAV_SYS_STATUS_SENSOR_3D_GYRO | MAV_SYS_STATUS_SENSOR_3D_ACCEL"))
if err != nil {
// handle error
}
fmt.Println(sens.String()) // "MAV_SYS_STATUS_SENSOR_3D_GYRO | MAV_SYS_STATUS_SENSOR_3D_ACCEL"

@sirno-baka
Copy link
Contributor Author

sirno-baka commented Mar 30, 2023

It seems that with the update of mavlink, new Enums and Messages have been added.
mavlink/mavlink#1943
and i forgot to add them to the commit

@aler9 aler9 force-pushed the fix-mav-codegen branch 3 times, most recently from a9368f6 to 7c2112e Compare March 31, 2023 10:11
Refactored MarshalText, UnmarshalText, and String methods for Enum types.

Add MessageTargetAbsolute MessageTargetRelative and TARGET_OBS_FRAME TARGET_ABSOLUTE_SENSOR_CAPABILITY_FLAGS Enums
@aler9 aler9 merged commit 1e50535 into bluenviron:main Mar 31, 2023
@aler9
Copy link
Member

aler9 commented Mar 31, 2023

merged, thanks!

@@ -57,27 +58,38 @@ var labels_ADSB_EMITTER_TYPE = map[ADSB_EMITTER_TYPE]string{

// MarshalText implements the encoding.TextMarshaler interface.
func (e ADSB_EMITTER_TYPE) MarshalText() ([]byte, error) {
if l, ok := labels_ADSB_EMITTER_TYPE[e]; ok {
return []byte(l), nil
var names []string
Copy link

@willschenck willschenck Aug 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this changed? This enum is not a bit mask, so these changes to the MarshalText and UnmashalText methods return all the types whose values match the mask, not the single expected string.
For example, I would expect this test to pass:

assert.Equal(t, "ADSB_EMITTER_TYPE_ROTOCRAFT", common.ADSB_EMITTER_TYPE_ROTOCRAFT.String())

But it fails:

-ADSB_EMITTER_TYPE_ROTOCRAFT
+ADSB_EMITTER_TYPE_ROTOCRAFT | ADSB_EMITTER_TYPE_SMALL | ADSB_EMITTER_TYPE_HIGH_VORTEX_LARGE | ADSB_EMITTER_TYPE_HEAVY | ADSB_EMITTER_TYPE_LARGE | ADSB_EMITTER_TYPE_LIGHT | ADSB_EMITTER_TYPE_HIGHLY_MANUV | ADSB_EMITTER_TYPE_NO_INFO

@github-actions github-actions bot locked and limited conversation to collaborators Feb 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants