Compare commits

...

2 commits

Author SHA1 Message Date
Jonathan Flueren
9ca389c90a Improve README.md 2023-07-07 18:23:39 +02:00
Jonathan Flueren
4171bc9645 Switch to &str as parameter, improve schmfication extensively 2023-07-07 18:18:40 +02:00
3 changed files with 208 additions and 29 deletions

View file

@ -1,11 +1,11 @@
[package]
name = "schmfy"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "Schmfication library"
readme = "README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
repository = "https://git.flueren.eu/JonOfUs/Schmfy"
documentation = "https://docs.rs/schmfy"
[dependencies]

View file

@ -1,5 +1,20 @@
# Schmfy library
This library is able to schmfy single words.
This library is able to schmfy any text.
## Usage
Just add this crate to your project and you will be able to use the `schmfy()`-function to turn any word into its 'schmord'.
Example usage:
```rust
use schmfy::schmfy;
fn improve_text(text: &str) {
let improved_text = schmfy(text);
println!("Old and boring: {}", text);
println!("Improved and great: {}", text);
}
```
## Capabilities
The schmfication capabilities are able to preserve text case and any non-alphabetical characters.
If a non-alphabetical character is between two alphabetical strings, both of the alphabetical strings will be interpreted as completely separate words.
For example, the HTML code `<span>Entry<br></span>` will be converted into `<schman>Schmentry<schmer></schman>`.

View file

@ -1,36 +1,124 @@
// Schmfies any String
pub fn schmfy(source: String) -> String {
if source.starts_with("schm") {
return source;
//! schmfy - a library to schmfy everything
#[derive(PartialEq, Copy, Clone)]
enum CaseType {
/// the whole word is in lowercase [default]
Lcase,
/// the whole word is in uppercase
Ucase,
/// the first letter us uppercase, the rest is lowercase
FstUcase,
}
/// Returns the case type of a str
fn get_case(txt: &str) -> CaseType {
let mut cnt_lcase: usize = 0;
let mut cnt_ucase: usize = 0;
let alph = txt
.chars()
.filter(|c| c.is_alphabetic())
.collect::<Vec<char>>();
alph.iter().for_each(|c| {
if c.is_uppercase() {
cnt_ucase += 1;
}
if c.is_lowercase() {
cnt_lcase += 1;
}
});
if alph.len() == 0 {
return CaseType::Lcase; // default
} else if cnt_lcase > 0 && cnt_ucase == 0 {
return CaseType::Lcase;
} else if cnt_lcase == 0 && cnt_ucase > 0 {
return CaseType::Ucase;
} else if alph[0].is_uppercase() && alph[1].is_lowercase() {
// atleast 2 entries
return CaseType::FstUcase;
}
CaseType::Lcase
}
fn restore_case(txt: String, case: CaseType) -> String {
match case {
CaseType::FstUcase => txt
.to_lowercase()
.chars()
.enumerate()
.map(|(pos, c)| {
if pos == 0 {
c.to_ascii_uppercase()
} else {
c.to_ascii_lowercase()
}
})
.collect::<String>(),
CaseType::Lcase => txt.to_lowercase(),
CaseType::Ucase => txt.to_uppercase(),
}
}
/// Schmfies any str, preserving case and everything non-alphabetical
pub fn schmfy(source: &str) -> String {
// instantly return if input is non-alphabetic single char
if source.len() == 1 && !source.chars().next().unwrap().is_alphabetic() {
return String::from(source);
}
let case = get_case(source);
// already schmfied
if source.to_lowercase().starts_with("schm") {
return String::from(source);
}
// empty
if source.len() == 0 {
return source;
return String::from(source);
}
// can't be empty
if !source.chars().next().unwrap().is_alphabetic() {
return source;
// Schmfy each substring separately
let mut current_substr: Vec<char> = vec![];
let mut substrings: Vec<String> = vec![];
source.chars().for_each(|c| {
if c.is_alphabetic() {
current_substr.push(c)
} else {
if current_substr.len() > 0 {
substrings.push(current_substr.iter().collect::<String>());
current_substr.clear();
}
substrings.push(c.to_string())
}
});
if current_substr.len() > 0 {
substrings.push(current_substr.iter().collect::<String>());
}
// if source is subsite (e.g. news/fsr), schmfy all parts separately
if source.contains('/') {
return source
.split('/')
.map(|s| schmfy(String::from(s)))
if substrings.len() > 1 {
return substrings
.iter()
.map(|txt| schmfy(txt))
.collect::<Vec<String>>()
.join("/");
.join("");
}
if source.is_empty() {
return source;
// substrings now has to contain exactly one element
let source = substrings[0].to_lowercase();
if !source.chars().next().unwrap().is_alphabetic() {
return String::from(source);
}
// schmfy first char if word is no longer than 3
if source.len() <= 3 {
if source.len() <= 3 && case != CaseType::FstUcase {
let (prefix, suffix) = source.split_at(1);
let c = prefix.chars().next().unwrap_or('-');
return schmfy_char(c) + suffix;
return restore_case(schmfy_char(c) + suffix, case);
}
// Normal words - replace prefix before first vocal
@ -42,10 +130,10 @@ pub fn schmfy(source: String) -> String {
let (_, suffix) = source.split_at(vok_pos);
String::from("schm") + suffix
restore_case(String::from("schm") + suffix, case)
}
// Schmfies single char
/// Schmfies single char
fn schmfy_char(c: char) -> String {
let mut ret = String::from("schm");
match c {
@ -82,14 +170,90 @@ fn schmfy_char(c: char) -> String {
ret
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let schmfied = schmfy(String::from("test"));
assert_eq!(schmfied, "schmest");
fn schmfy_plaintext_tests() {
assert_eq!(schmfy("test"), "schmest");
assert_eq!(schmfy("Hello"), "Schmello");
assert_eq!(schmfy("HELLO"), "SCHMELLO");
assert_eq!(schmfy("hello"), "schmello");
assert_eq!(schmfy("Bar"), "Schmar");
}
#[test]
fn schmfy_mixtext_tests() {
assert_eq!(schmfy(">Test"), ">Schmest");
assert_eq!(schmfy(">tesT"), ">schmest");
assert_eq!(schmfy("One&Two"), "Schmone&Schmo");
assert_eq!(
schmfy("<span>Entry<br></span>"),
"<schman>Schmentry<schmer></schman>"
);
assert_eq!(schmfy("foo/bar/baz"), "schmefoo/schmear/schmeaz");
assert_eq!(
schmfy("long/Longer/LONGESTTT"),
"schmong/Schmonger/SCHMONGESTTT"
);
}
#[test]
fn schmfy_sentences_tests() {
assert_eq!(
schmfy("Today I am VERY tired."),
"Schmoday SCHMI schmam SCHMERY schmired."
);
assert_eq!(
schmfy("Lorem ipsum dolor sit amet, consetetur sadipscing elitr"),
"Schmorem schmipsum schmolor schmesit schmamet, schmonsetetur schmadipscing schmelitr"
);
}
#[test]
fn schmfy_code_tests() {
assert_eq!(
schmfy(
"#include <stdio.h>
#include <sys/types.h>
int main()
{
while(1)
fork();
return 0;
}"
),
"#schminclude <schmio.schma>
#schminclude <schmesys/schmes.schma>
schmint schmain()
{
schmile(1)
schmork();
schmeturn 0;
}"
);
assert_eq!(
schmfy(
"
```
This is a Markdown codebox
```
| This | is |
|---|---|
| a | Markdown |
| table | ! |"),
"
```
Schmis schmis schma Schmarkdown schmodebox
```
| Schmis | schmis |
|---|---|
| schma | Schmarkdown |
| schmable | ! |"
)
}
}