HasLen trait not working on custome impl
Closed this issue · 4 comments
Hey, I found a weird behavior of the HasLen trait, by impl
the trait on any type one would expect that the length validation will be possible on the type:
use serde::Serialize;
use validator::{HasLen, Validate};
const MAX_FILE_SIZE: usize = 1024;
#[derive(Serialize, Validate)]
struct FileData {
file_name: String,
size: usize,
content_type: String,
}
impl HasLen for &FileData {
fn length(&self) -> u64 {
self.size as u64
}
}
#[derive(Validate)]
struct Foo {
#[validate(length(max = "MAX_FILE_SIZE"))]
file: FileData,
}
but this is not the case, I am receiving the following error Validator length can only be used on types String, &str
etc. only the types that the crate impl
I found that If I change the name of the struct to FileDatastr
or FileDataString
the above code sniped will compile.
After looking a bit in the source code, I found that the fn
used to check if the length
validation can be applied to a certain type is being made with this fn assert_has_len
(validator_derive/src/lib.rs;509).
I think changing the assert_has_len
to check if the field type impl HasLen
and if so let the code compile.
It's an issue with the fact that the derive macros checks for specific types. These checks should be removed since in practice it's causing a lot of issues and not solving much.
I cloned the repo, and changed the above code to the following:
(working on the "next" branch)
use validator::{Validate, ValidateLength};
---
impl ValidateLength for &FileData {
fn length(&self) -> u64 {
self.size as u64
}
}
----
And I removed the assert_has_len(rust_ident.clone(), field_type, &field.ty);
line I mentioned, and the code compiles as it should.
considering the above is there a reason to keep the assert_has_len
check? or I can open a pr to remove it?
edit:
I will also add an example to the readme.
It will be removed for the next version, no need to do a PR.
Great thank you for letting me know, have a nice day!