// Copyright (c) 2023-2025 ParadeDB, Inc.
//
// This file is part of ParadeDB - Postgres for Search and Analytics
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
use pgrx::{iter::TableIterator, name, pg_extern, JsonB};
use strum::VariantNames;
use tokenizers::SearchTokenizer;
/// Tokenize text with a given tokenizer setting
#[pg_extern(immutable, parallel_safe)]
pub fn tokenize(
tokenizer_setting: JsonB,
input_text: &str,
) -> TableIterator<(name!(token, String), name!(position, i32))> {
let tokenizer_setting = serde_json::to_value(tokenizer_setting)
.expect("invalid tokenizer setting, expected paradedb.tokenizer()");
let tokenizer = SearchTokenizer::from_json_value(&tokenizer_setting)
.expect("invalid tokenizer setting, expected paradedb.tokenizer()");
let mut analyzer = tokenizer
.to_tantivy_tokenizer()
.expect("failed to convert tokenizer to tantivy tokenizer");
let mut stream = analyzer.token_stream(input_text);
let mut result = Vec::new();
while stream.advance() {
let token = stream.token();
result.push((token.text.to_string(), token.position as i32));
}
TableIterator::new(result)
}
/// List all available tokenizers names in ParadeDB
#[pg_extern(immutable, parallel_safe)]
pub fn tokenizers() -> TableIterator<'static, (name!(tokenizer, String),)> {
TableIterator::new(
SearchTokenizer::VARIANTS
.iter()
.map(|t| (t.to_string(),))
.collect::>(),
)
}