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

chore: Add a feature gate to allow user disabling the NaN check #308

Closed
wants to merge 3 commits into from

Conversation

dqhl76
Copy link

@dqhl76 dqhl76 commented Sep 3, 2024

In the current implementation, there is an enforced check for NaN values during the serialization and deserialization of f32 and f64 because of cross platform problems. However, if user operate within homogenous environments where cross-platform compatibility is not a concern they cannot disable the check.

This PR add a feature gate to make this possible.

@dqhl76 dqhl76 requested review from frol and dj8yfo as code owners September 3, 2024 07:43
@dqhl76
Copy link
Author

dqhl76 commented Sep 3, 2024

In the default setting, the NaN check will still be performed. The check is only skipped if the allow_nan feature is enabled.

Copy link
Collaborator

@dj8yfo dj8yfo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dqhl76 we've thought about this a bit and decided to decline this PR.

One of the reasons is that a crate in cargo's dependency tree is resolved with a single set of features (not multiple sets of features). Thus using two crates in single project,
where one has borsh with this feature enabled and another has borsh with this feature disabled will result in single version of borsh with this feature enabled,
which may be incorrect behaviour for the second crate (which opens door to subtle hard-to-figure-out errors)

You may try using some wrapper types in client code like this, if you need to handle NaN-s:

use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
#[derive(Debug, BorshSerialize, BorshDeserialize, BorshSchema)]
enum F32Full {
    Value(f32),
    NaN,
}
impl From<f32> for F32Full {
    fn from(value: f32) -> Self {
        if value.is_nan() {
            Self::NaN
        } else {
            Self::Value(value)
        }
    }
}
fn main() {
    let source_vec: Vec<F32Full> = vec![f32::NAN.into(), 0.4342324f32.into()];
    let bytes = borsh::to_vec(&source_vec).unwrap();
    let output_vec: Vec<F32Full> = borsh::from_slice(&bytes).unwrap() ;
    println!("{:?}", output_vec);
}

@dqhl76
Copy link
Author

dqhl76 commented Sep 4, 2024

@dj8yfo Thank you for your prompt review, and I understand your concerns regarding these changes. Close.

@dqhl76 dqhl76 closed this Sep 4, 2024
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