Yeah, any of these choices will work^. Well, the last choice shouldn't be a trait, really, just a standalone function.
Associated types would also help simplify this (note, if you have a trait Foo<A>, the trait can be implemented multiple times on the same type, with different A. If you have a trait Foo with associated type A, only one implementation will be allowed, the associated type is a property of the implementation)
^ In more complicated situations coherence may disallow one or more of those choices.