File Structure
Usually, black box test cases go in a tests
directory at the root of your project (not under src
). See Testing. As far as I can tell, all of your test cases are black box test cases.
Also, implementations usually go below definitions, not in different files. For example, I'd put the Composite
enum in the composite
module.
Other than that, your file layout looks good.
Public or private
Is Polynomial
"just" data? If you think you'll ever add constraints or private fields, make its fields private now. If it's just data (no constraints), then you might as well leave it open.
I'm more worried about Composite
. Composite
is fully public but you appear to be converting the Variable
variant to a character through a u8
. This won't work very well for if a user passes a large u16
.
Code
Clippy
Go install and run clippy (cargo clippy
). Unfortunately, this only works on nightly and breaks often because it depends on many compiler internals. However, this will give you lots of good suggestions (if you can get it working...).
Formatting
Go install and run rustfmt (cargo fmt
) You don't have to do everything it tells you to but it's a good starting point.
Match
In general, prefer match *x { Case => ..., }
over match x { &Case => ..., }
. Clippy should tell you to do this.
Use the question mark operator (?
)
This is a new operator that replaces try!
in most cases. Basically, instead of writing try!(...)
, you'd write ...?
.
Avoid #[repr(C)]
.
Unless you really need it (usually, you're calling C
code or doing some fancy unsafe magic) and understand it, don't use the repr
annotation.
You don't have to try!
Instead of, try!(x); Ok(())
, you can just write x
if x
has the right type. Specifically, you could get rid of all of your try!
calls in your formatting (Display
and Debug
) functions.
Byte literals
You can write byte literals as b'x'
. You can write byte string literals as b"abc"
. No need to cast.
CamelCase
Types and enum variants are usually CamelCase
, modules and functions are usually snake_case
, constants and statics are usually UPPER_CASE
. Your ConvolutionMode
enum has UPPER_CASE
variants.
Derive Debug
Usually, I prefer to just derive Debug
rather than manually implement it. This is especially important when the internals are public as you don't want to lie about public internals.
Using IntoIterator
In general, you can iterate over a collection by reference as follows: for x in &my_collection { ... }
instead of for x in my_collection.iter() { ... }
. This works because there is (usually) an implementation of IntoIterator
on &MyCollectionType
(where MyCollectionType
is something like Vec
or HashMap
) and for loops work as described in std::iter.