sift-query-derive 0.1.0

Derive macros for SiftQuery entities
Documentation
use sift_query_algorithm::StableHasher64;

use crate::attrs::{EntityConfig, FieldConfig};

pub(crate) fn schema_fingerprint(
    entity_name: &str,
    entity: &EntityConfig,
    fields: &[FieldConfig],
) -> u64 {
    let mut hash = StableHasher64::default();
    let mut add = |value: &str| {
        hash.write_delimited(value);
    };
    add(entity_name);
    add(&entity.from);
    if let Some(value) = &entity.base_where {
        add(value);
    }
    if let Some(value) = &entity.fixed_having {
        add(value);
    }
    add(if entity.distinct { "distinct" } else { "all" });
    if let Some(value) = &entity.default_order {
        add(value);
    }
    if let Some(value) = &entity.stable_order {
        add(value);
    }
    add(&entity.max_page_size.to_string());
    add(&entity.max_offset.to_string());
    add(&entity.timeout_ms.to_string());
    for field in fields {
        add(&field.public_name);
        if field.cursor_non_null {
            add("cursor_non_null");
        }
        for value in [&field.sort_from, &field.sort_operator, &field.sort_template]
            .into_iter()
            .flatten()
        {
            add("condition_order");
            add(value);
        }
        if let Some(codec) = &field.codec {
            add("codec");
            add(codec);
        }
        if let Some(label) = &field.label {
            add("label");
            add(label);
        }
        for operator in &field.custom_operators {
            add("http_custom_operator");
            add(operator);
        }
        add(&field.column);
        if let Some(alias) = &field.result_alias {
            add(alias);
        }
        add(&format!("{:?}", field.kind));
        add(&field.value_type.to_string());
        add(if field.filterable {
            "filterable"
        } else {
            "no-filter"
        });
        add(if field.selectable {
            "selectable"
        } else {
            "no-select"
        });
        add(if field.sortable {
            "sortable"
        } else {
            "no-sort"
        });
        for operator in &field.operators {
            add(&operator.to_string());
        }
    }
    hash.finish()
}