shardmap 0.2.1

Sharded embedded in-memory map with optional cache, protocol, and server internals
Documentation
#[cfg(feature = "server")]
use bytes::BytesMut;

use crate::commands::redis::{
    bulk, define_redis_command, error, parse_f64, string_value, write_resp_wrong_arity,
    write_resp_wrongtype, wrong_arity,
};
use crate::protocol::Frame;
#[cfg(feature = "server")]
use crate::server::wire::ServerWire;
use crate::storage::{EmbeddedStore, RedisStringLookup};

define_redis_command!(IncrByFloat, "INCRBYFLOAT", true);

impl crate::commands::redis::RedisCommand for IncrByFloat {
    fn execute(store: &EmbeddedStore, args: &[&[u8]]) -> Frame {
        match args {
            [key, delta] => {
                let Ok(delta) = parse_f64(delta) else {
                    return error("ERR value is not a valid float");
                };
                match string_value(store, key) {
                    Ok(value) => {
                        let current = if value.is_empty() {
                            0.0
                        } else {
                            match parse_f64(&value) {
                                Ok(value) => value,
                                Err(_) => return error("ERR value is not a valid float"),
                            }
                        };
                        let next = current + delta;
                        if !next.is_finite() {
                            return error("ERR increment would produce NaN or Infinity");
                        }
                        let bytes = next.to_string().into_bytes();
                        store.set((*key).to_vec(), bytes.clone(), None);
                        bulk(bytes)
                    }
                    Err(frame) => frame,
                }
            }
            _ => wrong_arity("INCRBYFLOAT"),
        }
    }

    #[cfg(feature = "server")]
    fn write_resp(store: &EmbeddedStore, args: &[&[u8]], out: &mut BytesMut) {
        match args {
            [key, delta] => {
                let Ok(delta) = parse_f64(delta) else {
                    ServerWire::write_resp_error(out, "ERR value is not a valid float");
                    return;
                };
                let mut current = 0.0;
                match store.get_string_value_into(key, |bytes| {
                    current = parse_f64(bytes).unwrap_or(f64::NAN);
                }) {
                    RedisStringLookup::Hit if current.is_nan() => {
                        ServerWire::write_resp_error(out, "ERR value is not a valid float");
                    }
                    RedisStringLookup::Hit | RedisStringLookup::Miss => {
                        let next = current + delta;
                        if !next.is_finite() {
                            ServerWire::write_resp_error(
                                out,
                                "ERR increment would produce NaN or Infinity",
                            );
                            return;
                        }
                        let bytes = next.to_string().into_bytes();
                        store.set((*key).to_vec(), bytes.clone(), None);
                        ServerWire::write_resp_blob_string(out, &bytes);
                    }
                    RedisStringLookup::WrongType => write_resp_wrongtype(out),
                }
            }
            _ => write_resp_wrong_arity(out, "INCRBYFLOAT"),
        }
    }
}