marisa-ffi 0.3.1

Rust FFI bindings for libmarisa - a space-efficient trie data structure
Documentation
#include "marisa_ffi.h"
#include "marisa/base.h"
#include <iostream>
#include <string>
#include <vector>

int main() {
    std::cout << "Marisa FFI Test" << std::endl;
    std::cout << "Version: " << marisa_version() << std::endl;
    std::cout << std::endl;

    // Test basic functionality
    std::cout << "=== Basic Functionality Test ===" << std::endl;
    
    // Create keyset
    marisa_keyset_t* keyset = marisa_keyset_create();
    if (!keyset) {
        std::cerr << "Failed to create keyset" << std::endl;
        return 1;
    }
    
    // Add some test keys
    std::vector<std::string> test_keys = {"hello", "world", "rust", "ffi", "marisa"};
    for (const auto& key : test_keys) {
        int result = marisa_keyset_push(keyset, key.c_str(), key.length());
        if (result != MARISA_OK) {
            std::cerr << "Failed to push key: " << key << std::endl;
            marisa_keyset_destroy(keyset);
            return 1;
        }
    }
    
    std::cout << "Added " << test_keys.size() << " keys to keyset" << std::endl;
    
    // Build trie
    marisa_t* trie = marisa_create();
    if (!trie) {
        std::cerr << "Failed to create trie" << std::endl;
        marisa_keyset_destroy(keyset);
        return 1;
    }
    
    int result = marisa_build(trie, keyset);
    if (result != MARISA_OK) {
        std::cerr << "Failed to build trie: " << marisa_strerror(result) << std::endl;
        marisa_destroy(trie);
        marisa_keyset_destroy(keyset);
        return 1;
    }
    
    std::cout << "Trie built successfully" << std::endl;
    
    // Test lookup
    std::cout << std::endl << "=== Lookup Test ===" << std::endl;
    for (const auto& key : test_keys) {
        marisa_id_t id;
        int lookup_result = marisa_lookup(trie, key.c_str(), key.length(), &id);
        if (lookup_result == MARISA_OK) {
            std::cout << "Found '" << key << "' with ID: " << id << std::endl;
        } else {
            std::cout << "Failed to lookup '" << key << "': " << marisa_strerror(lookup_result) << std::endl;
        }
    }
    
    // Test predictive search
    std::cout << std::endl << "=== Predictive Search Test ===" << std::endl;
    marisa_agent_t* agent = marisa_agent_create();
    if (!agent) {
        std::cerr << "Failed to create agent" << std::endl;
        marisa_destroy(trie);
        marisa_keyset_destroy(keyset);
        return 1;
    }
    
    std::string prefix = "h";
    int search_result = marisa_predictive_search(trie, prefix.c_str(), prefix.length(), agent);
    if (search_result == MARISA_OK) {
        const char* key = marisa_agent_key(agent);
        size_t key_length = marisa_agent_key_length(agent);
        marisa_id_t id = marisa_agent_id(agent);
        
        std::cout << "Predictive search for '" << prefix << "' found: '";
        std::cout.write(key, key_length);
        std::cout << "' (ID: " << id << ")" << std::endl;
    } else {
        std::cout << "Predictive search failed: " << marisa_strerror(search_result) << std::endl;
    }
    
    // Test reverse lookup
    std::cout << std::endl << "=== Reverse Lookup Test ===" << std::endl;
    marisa_id_t test_id = 0;
    int reverse_result = marisa_reverse_lookup(trie, test_id, agent);
    if (reverse_result == MARISA_OK) {
        const char* key = marisa_agent_key(agent);
        size_t key_length = marisa_agent_key_length(agent);
        
        std::cout << "Reverse lookup for ID " << test_id << " found: '";
        std::cout.write(key, key_length);
        std::cout << "'" << std::endl;
    } else {
        std::cout << "Reverse lookup failed: " << marisa_strerror(reverse_result) << std::endl;
    }
    
    // Test common prefix search
    std::cout << std::endl << "=== Common Prefix Search Test ===" << std::endl;
    std::string test_string = "hello";
    int prefix_result = marisa_common_prefix_search(trie, test_string.c_str(), test_string.length(), agent);
    if (prefix_result == MARISA_OK) {
        const char* key = marisa_agent_key(agent);
        size_t key_length = marisa_agent_key_length(agent);
        marisa_id_t id = marisa_agent_id(agent);
        
        std::cout << "Common prefix search for '" << test_string << "' found: '";
        std::cout.write(key, key_length);
        std::cout << "' (ID: " << id << ")" << std::endl;
    } else {
        std::cout << "Common prefix search failed: " << marisa_strerror(prefix_result) << std::endl;
    }
    
    // Test save/load
    std::cout << std::endl << "=== Save/Load Test ===" << std::endl;
    const char* filename = "test_trie.marisa";
    
    int save_result = marisa_save(trie, filename);
    if (save_result == MARISA_OK) {
        std::cout << "Trie saved to '" << filename << "'" << std::endl;
        
        // Load it back
        marisa_t* loaded_trie = marisa_create();
        if (loaded_trie) {
            int load_result = marisa_open(loaded_trie, filename);
            if (load_result == MARISA_OK) {
                std::cout << "Trie loaded from '" << filename << "'" << std::endl;
                
                // Test loaded trie
                marisa_id_t id;
                int loaded_lookup = marisa_lookup(loaded_trie, "hello", 5, &id);
                if (loaded_lookup == MARISA_OK) {
                    std::cout << "Loaded trie lookup 'hello' -> ID: " << id << std::endl;
                } else {
                    std::cout << "Loaded trie lookup failed" << std::endl;
                }
            } else {
                std::cout << "Failed to load trie: " << marisa_strerror(load_result) << std::endl;
            }
            marisa_destroy(loaded_trie);
        }
        
        // Clean up test file
        std::remove(filename);
        std::cout << "Test file removed" << std::endl;
    } else {
        std::cout << "Failed to save trie: " << marisa_strerror(save_result) << std::endl;
    }
    
    // Clean up
    marisa_agent_destroy(agent);
    marisa_destroy(trie);
    marisa_keyset_destroy(keyset);
    
    std::cout << std::endl << "All tests completed successfully!" << std::endl;
    return 0;
}