candding 0.1.0

Pure candle embeddings for Rust with no ONNX: dense, sparse, multi-vector and rerank models today, image models on the roadmap
Documentation
use super::*;

fn tokens(strs: &[&str]) -> Vec<String> {
  strs.iter().map(|s| s.to_string()).collect()
}

#[test]
fn a_single_token_is_its_own_whole_word() {
  let words = reconstruct(&tokens(&["hello"]));
  assert_eq!(
    words,
    vec![Word {
      text: "hello".to_string(),
      tokens: 0..1,
    }]
  );
}

#[test]
fn a_word_split_into_three_pieces_rejoins_into_one() {
  let words = reconstruct(&tokens(&["un", "##believ", "##able"]));
  assert_eq!(
    words,
    vec![Word {
      text: "unbelievable".to_string(),
      tokens: 0..3,
    }]
  );
}

#[test]
fn a_non_continuation_token_starts_a_new_word() {
  let words = reconstruct(&tokens(&["the", "cat", "##s"]));
  assert_eq!(
    words,
    vec![
      Word {
        text: "the".to_string(),
        tokens: 0..1,
      },
      Word {
        text: "cats".to_string(),
        tokens: 1..3,
      },
    ]
  );
}

/// A real tokenizer never emits a leading `##` token, but it must not panic: it starts its own word.
#[test]
fn a_leading_continuation_token_starts_its_own_word_instead_of_panicking() {
  let words = reconstruct(&tokens(&["##oops"]));
  assert_eq!(
    words,
    vec![Word {
      text: "oops".to_string(),
      tokens: 0..1,
    }]
  );
}

#[test]
fn no_tokens_reconstruct_into_no_words() {
  assert_eq!(reconstruct(&[]), Vec::<Word>::new());
}