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

Add support for BSON marshaling #49

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

KatamariJr
Copy link

Add the funcs MarshalBSONValue and UnmarshalBSONValue, allowing enums to be inserted and retrieved from MongoDB which uses a BSON store.

@alvaroloes
Copy link
Owner

Thank you for the PR.

I haven't gone deep into the details, but I don't feel comfortable with adding a dependency to an external library. If we go down this path, then Enumer would end up depending on a lot of external libraries and would need to "track" their versions. Also, What if other people use a different BSON library?

Maybe there is a way to be able to be compatible with external marshalers without depending on them

@KatamariJr
Copy link
Author

I understand the concern. The main problem lies with mongo-driver requiring an interface method with prototype MarshalBSONValue() (bsontype.Type, []byte, error), immediately including a package dependency. There is also a MashalBSON func that doesn't have this, however I spent most of yesterday trying to get that to work with mashaling a simple string and found that you must use MashalBSONValue. Not really sure where to go from there.

I don't think the slippery-slope argument necessarily applies here, as there would still need to be a major reason to want to serialize to whatever format is specified, which leads me to...

MongoDB is extremely popular with Go and I feel that this will come up as a request sooner rather than later. The official mongo-driver package (the only mongo / BSON package being actively worked on, mgo is dead) is at a stable 1.0.+ release and should not have any breaking changes until 2.0 comes out, and even then it would be surprising if they change the interface for un/marshaling.

Any thoughts on a middle ground?

@alvaroloes
Copy link
Owner

I see. Here is a workaround that I think it is a good trade-off: You can autogenerate all the methods Enumer support for your enum type, and then add any extra method you want manually. At least this will work for your project and you won't notice any difference in behavior if we decide to eventually autogenerate methods with external dependencies. For example:

//go:generate enumer -type=EntityType -json
type EntityType int

const (
	EntityTypeUser EntityType = iota
	EntityTypeCustomer
	EntityTypeProduct
)

// This is added manually
func (et *EntityType) MarshalBSONValue() (bsontype.Type, []byte, error) {
	// ...
	return nil, nil, nil
}

// In another file...
func main() {
	const x EntityType = 3
	x.String() // Correct. It's been autogenerated
	x.MarshalJSON() // Correct. It's been autogenerated
	x.MarshalBSONValue() // Correct. It's the method you defined above, but it is at the same level as the autogenerated ones
}

Running go generate in the folder this file is placed will generate a file called entitytype_enumer.go with all the autogenerated methods. Then you add any custom methods you want to your enum in the same file where it is defined (or in another, but in the same package). As all the methods are in the same package, they all belong to the enum method set and you can marshal it to JSON or BSON when needed.

Let me know if this helped you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants