Skip to content

Commit a035fb6

Browse files
committed
Port DocumentType enum to Rust
Port DocumentType enum to Rust as `document::DocumentType`, removing it from `redisearch.h`. Use `document::DocumentType` in `rlookup` instead of `rlookup::bindings::DocumentType`.
1 parent d9574d8 commit a035fb6

13 files changed

Lines changed: 202 additions & 16 deletions

File tree

src/redisearch.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <limits.h>
1515
#include <stdbool.h>
1616
#include <time.h>
17+
#include "document_rs.h"
1718
#include "util/dllist.h"
1819
#include "stemmer.h"
1920
#include "types_rs.h"
@@ -65,12 +66,6 @@ do {
6566
extern "C" {
6667
#endif
6768

68-
typedef enum {
69-
DocumentType_Hash,
70-
DocumentType_Json,
71-
DocumentType_Unsupported,
72-
} DocumentType;
73-
7469
#define isSpecHash(spec) ((spec)->rule && (spec)->rule->type == DocumentType_Hash)
7570
#define isSpecJson(spec) ((spec)->rule && (spec)->rule->type == DocumentType_Json)
7671
#define SpecRuleTypeName(spec) ((spec)->rule ? DocumentType_ToString((spec)->rule->type) : "Unknown")

src/redisearch_rs/Cargo.lock

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/redisearch_rs/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ members = [
33
"buffer",
44
"build_utils",
55
"c_entrypoint/*",
6+
"document",
67
"ffi",
78
"field",
89
"fnv",
@@ -64,6 +65,7 @@ publish = false
6465
[workspace.dependencies]
6566
buffer = { path = "./buffer" }
6667
c_ffi_utils = { path = "./c_entrypoint/c_ffi_utils" }
68+
document = { path = "./document" }
6769
ffi = { path = "./ffi", default-features = false }
6870
field = { path = "./field" }
6971
fnv = { path = "./fnv" }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "document_ffi"
3+
version.workspace = true
4+
edition.workspace = true
5+
license-file.workspace = true
6+
publish.workspace = true
7+
8+
[lints]
9+
workspace = true
10+
11+
[build-dependencies]
12+
cbindgen.workspace = true
13+
build_utils = { path = "../../build_utils" }
14+
15+
[dependencies]
16+
c_ffi_utils.workspace = true
17+
libc.workspace = true
18+
document.workspace = true
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) 2006-Present, Redis Ltd.
3+
* All rights reserved.
4+
*
5+
* Licensed under your choice of the Redis Source Available License 2.0
6+
* (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
7+
* GNU Affero General Public License v3 (AGPLv3).
8+
*/
9+
10+
use build_utils::run_cbinden;
11+
12+
fn main() {
13+
run_cbinden("../../headers/document_rs.h").unwrap();
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language = "C"
2+
autogen_warning = "/* Warning, this file is autogenerated by cbindgen from `src/redisearch_rs/c_entrypoint/doc_type_ffi/build.rs. Don't modify it manually. */"
3+
cpp_compat = true
4+
pragma_once = true
5+
6+
no_includes = true
7+
8+
[parse]
9+
parse_deps = true
10+
include = ["document", "c_ffi_utils"]
11+
12+
[export]
13+
include = ["DocumentType"]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright (c) 2006-Present, Redis Ltd.
3+
* All rights reserved.
4+
*
5+
* Licensed under your choice of the Redis Source Available License 2.0
6+
* (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
7+
* GNU Affero General Public License v3 (AGPLv3).
8+
*/
9+
10+
//! This crate currently only exposes the [`DocumentType`](document::DocumentType) enum
11+
//! to C. It can be expanded to host more document-related APIs later.
12+
use document as _;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "document"
3+
version.workspace = true
4+
edition.workspace = true
5+
license-file.workspace = true
6+
publish.workspace = true
7+
8+
[dependencies]
9+
strum.workspace = true
10+
thiserror.workspace = true
11+
12+
[lints]
13+
workspace = true
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2006-Present, Redis Ltd.
3+
* All rights reserved.
4+
*
5+
* Licensed under your choice of the Redis Source Available License 2.0
6+
* (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
7+
* GNU Affero General Public License v3 (AGPLv3).
8+
*/
9+
10+
/// The various document types supported by RediSearch.
11+
///
12+
/// cbindgen:prefix-with-name
13+
#[repr(C)]
14+
#[derive(
15+
Clone,
16+
Copy,
17+
Debug,
18+
PartialEq,
19+
Eq,
20+
strum::EnumString,
21+
strum::Display,
22+
strum::AsRefStr,
23+
strum::FromRepr,
24+
)]
25+
pub enum DocumentType {
26+
/// Hash document type
27+
#[strum(serialize = "hash")]
28+
Hash = 0,
29+
/// JSON document type
30+
#[strum(serialize = "json")]
31+
Json = 1,
32+
/// Unsupported document type
33+
#[strum(serialize = "unsupported")]
34+
Unsupported = 2,
35+
}
36+
37+
impl From<u32> for DocumentType {
38+
fn from(value: u32) -> Self {
39+
let Ok(value_usize) = value.try_into() else {
40+
return Self::Unsupported;
41+
};
42+
43+
Self::from_repr(value_usize).unwrap_or(Self::Unsupported)
44+
}
45+
}
46+
47+
#[cfg(test)]
48+
mod test {
49+
use std::str::FromStr;
50+
51+
use crate::DocumentType;
52+
53+
#[test]
54+
fn test_serialize_deserialize_from_ffi() {
55+
#[rustfmt::skip]
56+
let doc_types = [
57+
(DocumentType::Hash, "hash", 0),
58+
(DocumentType::Json, "json", 1),
59+
(DocumentType::Unsupported, "unsupported", 2),
60+
];
61+
for (doc_type, expected_str, expected_ffi) in doc_types {
62+
let serialized = doc_type.to_string();
63+
assert_eq!(serialized, expected_str);
64+
65+
let deserialized = DocumentType::from_str(expected_str).unwrap();
66+
assert_eq!(deserialized, doc_type);
67+
68+
let from_num = DocumentType::from(expected_ffi as u32);
69+
assert_eq!(from_num, doc_type);
70+
71+
let from_repr = DocumentType::from_repr(expected_ffi).unwrap();
72+
assert_eq!(from_repr, doc_type);
73+
}
74+
75+
assert_eq!(DocumentType::from(u32::MAX), DocumentType::Unsupported);
76+
77+
assert_eq!(
78+
DocumentType::from_str("Je n'existe"),
79+
Err(strum::ParseError::VariantNotFound)
80+
);
81+
82+
assert_eq!(DocumentType::from_repr(usize::MAX), None);
83+
}
84+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
/* Warning, this file is autogenerated by cbindgen from `src/redisearch_rs/c_entrypoint/doc_type_ffi/build.rs. Don't modify it manually. */
4+
5+
/**
6+
* The various document types supported by RediSearch.
7+
*
8+
*/
9+
typedef enum DocumentType {
10+
/**
11+
* Hash document type
12+
*/
13+
DocumentType_Hash = 0,
14+
/**
15+
* JSON document type
16+
*/
17+
DocumentType_Json = 1,
18+
/**
19+
* Unsupported document type
20+
*/
21+
DocumentType_Unsupported = 2,
22+
} DocumentType;

0 commit comments

Comments
 (0)