Yep. This whole discussion just seems like a C vs C++ styleguide slapfight.
Having the functions that operate on the struct attached directly to the struct declaration, vs having some functions that the first parameter is the struct on which the function operates, doesn't seem like a particularly meaningful distinction to me. OK, you like C-style programming in favor of C++-style programming, congrats. It's still a class either way.
The distinction you describe is not meaningful, but the key feature that separates classes from other forms of code organization/polymorphism, like typeclasses as in Haskell/Rust, is not that. It is inheritance.
I guess it's kind close to a C++ class. It's pretty different to a class in a language like Java, because all classes in Java are heap allocated and behind references.
Enums are are the better example of non-class types. For example, you can have:
enum StringOrInt {
String(String),
Int(u32),
}
And you can go ahead and implement methods on that type. Classes have "AND-state", not "OR-state". But a Type in general can have either kind of state.
That's equivalent to wrapping an enum in a class. Emulations of type hierarchies without OO often fail like this, having a A-or-B be literally the same type so losing out on type safety/forcing constant rechecking of the discriminant.