├── .github ├── Demo.gif └── workflows │ └── test.yml ├── .gitignore ├── .vscode └── settings.json ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── examples ├── README.md ├── chunk-search-rayon.rs ├── chunk-search.rs ├── fuseable-search.rs ├── iterable-search.rs ├── search-bar │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs └── simple-search.rs └── src ├── lib.rs ├── tests.rs └── utils.rs /.github/Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blakeinstein/fuse-rust/89da7aeed277251296c8d57e05cb85c3b40ec332/.github/Demo.gif -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | env: 6 | CARGO_TERM_COLOR: always 7 | 8 | jobs: 9 | check: 10 | name: Build Check 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions-rs/toolchain@v1 15 | with: 16 | profile: minimal 17 | toolchain: stable 18 | override: true 19 | - uses: actions-rs/cargo@v1 20 | with: 21 | command: check 22 | 23 | test: 24 | name: Unit tests 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v2 28 | - uses: actions-rs/toolchain@v1 29 | with: 30 | profile: minimal 31 | toolchain: stable 32 | override: true 33 | - uses: actions-rs/cargo@v1 34 | with: 35 | command: test 36 | args: --all-targets 37 | 38 | fmt: 39 | name: Rust formatting 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v2 43 | - uses: actions-rs/toolchain@v1 44 | with: 45 | profile: minimal 46 | toolchain: stable 47 | override: true 48 | - run: rustup component add rustfmt 49 | - uses: actions-rs/cargo@v1 50 | with: 51 | command: fmt 52 | args: --all -- --check 53 | 54 | clippy: 55 | name: Clippy 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: actions/checkout@v2 59 | - uses: actions-rs/toolchain@v1 60 | with: 61 | profile: minimal 62 | toolchain: stable 63 | override: true 64 | - run: rustup component add clippy 65 | - uses: actions-rs/cargo@v1 66 | with: 67 | command: clippy 68 | args: -- -D warnings 69 | 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "conventionalCommits.scopes": [ 3 | "search-algo", 4 | "code" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fuse-rust" 3 | version = "0.4.0" 4 | authors = ["Blaine "] 5 | edition = "2021" 6 | license = "MIT" 7 | readme = "README.md" 8 | documentation = "https://docs.rs/fuse-rust" 9 | repository = "https://github.com/Blakeinstein/fuse-rust" 10 | homepage = "https://github.com/Blakeinstein/fuse-rust" 11 | categories = ["algorithms", "text-processing", "gui"] 12 | keywords = [ 13 | "weighted-search", 14 | "search", 15 | "bitap", 16 | "fuzzy-search", 17 | "fuzzy-matching", 18 | ] 19 | description = """ 20 | Fuse is a super lightweight library which provides a simple way to do fuzzy searching. 21 | Fuse-Rust is a port of Fuse-Swift, written purely in rust. 22 | """ 23 | 24 | [dependencies] 25 | crossbeam-utils = { version = "0.8", optional = true } 26 | rayon = { version = "1", optional = true } 27 | 28 | [features] 29 | default = ["rayon"] 30 | async = ["crossbeam-utils"] 31 | rayon = ["dep:rayon"] 32 | 33 | [workspace] 34 | members = ["examples/search-bar"] 35 | 36 | [[example]] 37 | name = "chunk-search" 38 | required-features = ["async"] 39 | 40 | [[example]] 41 | name = "chunk-search-rayon" 42 | required-features = ["rayon"] 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Rishikesh "Blaine" Anand 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Fuse-rust

2 |

3 | 4 | 5 |

6 | 7 | ## What is Fuse? 8 | Fuse is a super lightweight library which provides a simple way to do fuzzy searching. 9 | 10 | Fuse-RS is a port of https://github.com/krisk/fuse-swift written purely in rust. 11 | 12 | ## Usage 13 | 14 | 15 | 16 | An example of a real use case, a search bar made using [iced](https://github.com/iced-rs/iced) is also available. 17 | 18 | Try it using 19 | ```shell 20 | cargo run --package search_bar 21 | ``` 22 | > Check all available examples and their source code [here.](/examples/) 23 | 24 | 25 | ### Async 26 | Use the feature flag "async" to also be able to use async functions. 27 | ```toml 28 | fuse-rust = { version = ..., features = ["async"]} 29 | ``` 30 | 31 | #### Initializing 32 | 33 | The first step is to create a fuse object, with the necessary parameters. Fuse::default, returns the following parameters. 34 | ```rust 35 | Fuse::default() = Fuse{ 36 | location: 0, // Approx where to start looking for the pattern 37 | distance: 100, // Maximum distance the score should scale to 38 | threshold: 0.6, // A threshold for guess work 39 | max_pattern_length: 32, // max valid pattern length 40 | is_case_sensitive: false, 41 | tokenize: false, // the input search text should be tokenized 42 | } 43 | ``` 44 | For how to implement individual searching operations, check the [examples.](/examples/) 45 | 46 | ## Options 47 | 48 | As given above, Fuse takes the following options 49 | 50 | - `location`: Approximately where in the text is the pattern expected to be found. Defaults to `0` 51 | - `distance`: Determines how close the match must be to the fuzzy `location` (specified above). An exact letter match which is `distance` characters away from the fuzzy location would score as a complete mismatch. A distance of `0` requires the match be at the exact `location` specified, a `distance` of `1000` would require a perfect match to be within `800` characters of the fuzzy location to be found using a 0.8 threshold. Defaults to `100` 52 | - `threshold`: At what point does the match algorithm give up. A threshold of `0.0` requires a perfect match (of both letters and location), a threshold of `1.0` would match anything. Defaults to `0.6` 53 | - `maxPatternLength`: The maximum valid pattern length. The longer the pattern, the more intensive the search operation will be. If the pattern exceeds the `maxPatternLength`, the `search` operation will return `nil`. Why is this important? [Read this](https://en.wikipedia.org/wiki/Word_(computer_architecture)#Word_size_choice). Defaults to `32` 54 | - `isCaseSensitive`: Indicates whether comparisons should be case sensitive. Defaults to `false` 55 | 56 |
-------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Usage Examples 2 | 3 | ## Search Bar 4 | 5 | 6 | 7 | Demo made using [iced-rs](https://github.com/iced-rs/iced). 8 | 9 | You can run this example locally by running 10 | 11 | ```shell 12 | cargo run --package search_bar 13 | ``` 14 | 15 |
16 | 17 | #### Simple search 18 | 19 | Simple search. 20 | ```shell 21 | cargo run --example simple-search 22 | ``` 23 | 24 | ```rust 25 | let fuse = Fuse::default(); 26 | let text = "Old Man's War"; 27 | let search_text = "od mn war"; 28 | 29 | let result = fuse.search_text_in_string(search_text, text); 30 | assert_eq!(result, Some(ScoreResult{ 31 | score: 0.4444444444444444, 32 | ranges: vec!((0..1), (2..7), (9..13)), 33 | }), "Simple search returned incorrect results"); 34 | ``` 35 | 36 | #### Iterable search 37 | 38 | Search over a string iterable. 39 | ```shell 40 | cargo run --example iterable-search 41 | ``` 42 | 43 | ```rust 44 | let fuse = Fuse::default(); 45 | let books = [ 46 | "The Silmarillion", 47 | "The Lock Artist", 48 | "The Lost Symbol" 49 | ]; 50 | 51 | // Improve performance by creating the pattern before hand. 52 | let search_pattern = fuse.create_pattern("Te silm"); 53 | 54 | let results = fuse.search_text_in_iterable("Te silm", books.iter()); 55 | assert_eq!(results, vec!( 56 | SearchResult{ 57 | index: 0, 58 | score: 0.14285714285714285, 59 | ranges: vec!((0..1), (2..8), (10..14)), 60 | }, 61 | SearchResult{ 62 | index: 2, 63 | score: 0.49857142857142855, 64 | ranges: vec!((0..1), (2..5), (6..10), (11..12), (14..15)), 65 | }, 66 | SearchResult{ 67 | index: 1, 68 | score: 0.5714285714285714, 69 | ranges: vec!((0..1), (2..5), (8..9), (11..15)), 70 | }, 71 | ), "Iterable search returned incorrect results"); 72 | ``` 73 | 74 | #### Fuseable search 75 | 76 | Search over a list of items implementing the Fuseable trait. 77 | 78 | ```shell 79 | cargo run --example fuseable-search 80 | ``` 81 | 82 | ```rust 83 | struct Book<'a> { 84 | title: &'a str, 85 | author: &'a str, 86 | } 87 | 88 | impl Fuseable for Book<'_>{ 89 | fn properties(&self) -> Vec { 90 | return vec!( 91 | FuseProperty{value: String::from("title"), weight: 0.3}, 92 | FuseProperty{value: String::from("author"), weight: 0.7}, 93 | ) 94 | } 95 | 96 | fn lookup(&self, key: &str) -> Option<&str> { 97 | return match key { 98 | "title" => Some(self.title), 99 | "author" => Some(self.author), 100 | _ => None 101 | } 102 | } 103 | } 104 | fn main() { 105 | let books = [ 106 | Book{author: "John X", title: "Old Man's War fiction"}, 107 | Book{author: "P.D. Mans", title: "Right Ho Jeeves"}, 108 | ]; 109 | 110 | let fuse = Fuse::default(); 111 | let results = fuse.search_text_in_fuse_list("man", &books); 112 | 113 | assert_eq!(results, vec!( 114 | FusableSearchResult{ 115 | index: 1, 116 | score: 0.015000000000000003, 117 | results: vec!(FResult{ 118 | value: String::from("author"), 119 | score: 0.015000000000000003, 120 | ranges: vec!((5..8)), 121 | }), 122 | }, 123 | FusableSearchResult{ 124 | index: 0, 125 | score: 0.027999999999999997, 126 | results: vec!(FResult{ 127 | value: String::from("title"), 128 | score: 0.027999999999999997, 129 | ranges: vec!((4..7)), 130 | }) 131 | } 132 | ), "Fuseable Search returned incorrect results"); 133 | } 134 | ``` 135 | 136 | Furthermore, you can add a chunk size to run this over multiple threads. 137 | 138 | Currently, the chunk size is one, so the chunks of size 1 will be run on seperate threads. 139 | ```rust 140 | fuse.search_text_in_fuse_list_with_chunk_size("man", &books, 1, |x: FuseableSearchResult| { 141 | dbg!(x); 142 | }); 143 | ``` 144 | 145 | #### Chunk search 146 | 147 | You can look into chunk-search.rs for the source code, and can run the same with: 148 | 149 | ```shell 150 | cargo run --example chunk-search 151 | ``` -------------------------------------------------------------------------------- /examples/chunk-search-rayon.rs: -------------------------------------------------------------------------------- 1 | use fuse_rust::{Fuse, SearchResult}; 2 | 3 | fn test(list: Vec) { 4 | dbg!(list); 5 | } 6 | fn main() { 7 | let fuse = Fuse::default(); 8 | let random_strings = [ 9 | "tbtlaafazm", 10 | "koyqdadlgq", 11 | "oimiuidxph", 12 | "vpsduaanow", 13 | "hebiahfitj", 14 | "npwhrthmil", 15 | "azrwbimxwv", 16 | "vcsawdweuu", 17 | "rxkratrkmy", 18 | "aylajveblo", 19 | "rrxcujnscn", 20 | "qiquwmbjnq", 21 | "rnhfquhitv", 22 | "fdaerpicep", 23 | "uqdxisyife", 24 | "cjjoczaokp", 25 | "rzyqcbsysx", 26 | "hbbpyleeld", 27 | "agcpswynrh", 28 | "yfszgoorut", 29 | "bgqyspeffj", 30 | "izbqqtbicy", 31 | "fmtylhheez", 32 | "qwqmrjgsof", 33 | "ukxctnwjoa", 34 | "dudeqiiywj", 35 | "tkzoipxcwj", 36 | "ksceoqifgh", 37 | "ibganykxkk", 38 | "xjcmlkipmx", 39 | "lqlymvienh", 40 | "oixeifwozn", 41 | "rcliwhskci", 42 | "egccrviiht", 43 | "phfyrggvns", 44 | "wyppwykhlr", 45 | "jzbdxsvtnh", 46 | "zliedzschj", 47 | "hqvvdzmosr", 48 | "xkmcraghkf", 49 | "blyvvzlfvn", 50 | "snyozhntqh", 51 | "evlondyrqy", 52 | "sixjfceouu", 53 | "jtkryuwqug", 54 | "qceukaadkw", 55 | "sadaexvhps", 56 | "ikxraiifbo", 57 | "ilopqywxxd", 58 | "dcabhorpap", 59 | "kkvzxmqjmk", 60 | "euzucvvxrt", 61 | "cgqllottas", 62 | "ziyhnyjwly", 63 | "iczgeymhsz", 64 | "vqeccwggup", 65 | "srjpkgjsrm", 66 | "tdvlcuabbh", 67 | "egkbeovaet", 68 | "oqjnttcbnj", 69 | "mlspwbbbjl", 70 | "bbxyujiptq", 71 | "exjrsuxblo", 72 | "zoadfaqwqo", 73 | "dlqryyrnqr", 74 | "sdxdddshpu", 75 | "cszwyvgnbb", 76 | "ejyzvbhecn", 77 | "twacwdcmvp", 78 | "gtfljpvnuw", 79 | "bgjorqekho", 80 | "rqlgsjdcyn", 81 | "ssglbheril", 82 | "jaizdkhsuw", 83 | "cdbvmuicqu", 84 | "pesefozfyj", 85 | "tkjazdchyc", 86 | "enafivjxst", 87 | "nbvninlnqf", 88 | "aflmujlxxy", 89 | "edydtfyvpr", 90 | "nrrdxpibno", 91 | "lzavdwnasq", 92 | "cfmkkspgxd", 93 | "zkieyyejli", 94 | "uzgjmycefq", 95 | "pwhuafsdmd", 96 | "htblqmlnem", 97 | "loqhdoggub", 98 | "thaneejlnz", 99 | "tffydqyvuv", 100 | "ubatmpwlvq", 101 | "lqmspwfeuh", 102 | "upfvzbshvs", 103 | "uezupxkawl", 104 | "nlttwsdgcq", 105 | "vqjbleazcs", 106 | "faobxtvixg", 107 | "gbtqzvyiqf", 108 | "itovolfijo", 109 | ]; 110 | 111 | fuse.search_text_in_string_list_rayon("aa", &random_strings, 10 as usize, &test); 112 | } 113 | -------------------------------------------------------------------------------- /examples/chunk-search.rs: -------------------------------------------------------------------------------- 1 | use fuse_rust::{Fuse, SearchResult}; 2 | 3 | fn test(list: Vec) { 4 | dbg!(list); 5 | } 6 | fn main() { 7 | let fuse = Fuse::default(); 8 | let random_strings = [ 9 | "tbtlaafazm", 10 | "koyqdadlgq", 11 | "oimiuidxph", 12 | "vpsduaanow", 13 | "hebiahfitj", 14 | "npwhrthmil", 15 | "azrwbimxwv", 16 | "vcsawdweuu", 17 | "rxkratrkmy", 18 | "aylajveblo", 19 | "rrxcujnscn", 20 | "qiquwmbjnq", 21 | "rnhfquhitv", 22 | "fdaerpicep", 23 | "uqdxisyife", 24 | "cjjoczaokp", 25 | "rzyqcbsysx", 26 | "hbbpyleeld", 27 | "agcpswynrh", 28 | "yfszgoorut", 29 | "bgqyspeffj", 30 | "izbqqtbicy", 31 | "fmtylhheez", 32 | "qwqmrjgsof", 33 | "ukxctnwjoa", 34 | "dudeqiiywj", 35 | "tkzoipxcwj", 36 | "ksceoqifgh", 37 | "ibganykxkk", 38 | "xjcmlkipmx", 39 | "lqlymvienh", 40 | "oixeifwozn", 41 | "rcliwhskci", 42 | "egccrviiht", 43 | "phfyrggvns", 44 | "wyppwykhlr", 45 | "jzbdxsvtnh", 46 | "zliedzschj", 47 | "hqvvdzmosr", 48 | "xkmcraghkf", 49 | "blyvvzlfvn", 50 | "snyozhntqh", 51 | "evlondyrqy", 52 | "sixjfceouu", 53 | "jtkryuwqug", 54 | "qceukaadkw", 55 | "sadaexvhps", 56 | "ikxraiifbo", 57 | "ilopqywxxd", 58 | "dcabhorpap", 59 | "kkvzxmqjmk", 60 | "euzucvvxrt", 61 | "cgqllottas", 62 | "ziyhnyjwly", 63 | "iczgeymhsz", 64 | "vqeccwggup", 65 | "srjpkgjsrm", 66 | "tdvlcuabbh", 67 | "egkbeovaet", 68 | "oqjnttcbnj", 69 | "mlspwbbbjl", 70 | "bbxyujiptq", 71 | "exjrsuxblo", 72 | "zoadfaqwqo", 73 | "dlqryyrnqr", 74 | "sdxdddshpu", 75 | "cszwyvgnbb", 76 | "ejyzvbhecn", 77 | "twacwdcmvp", 78 | "gtfljpvnuw", 79 | "bgjorqekho", 80 | "rqlgsjdcyn", 81 | "ssglbheril", 82 | "jaizdkhsuw", 83 | "cdbvmuicqu", 84 | "pesefozfyj", 85 | "tkjazdchyc", 86 | "enafivjxst", 87 | "nbvninlnqf", 88 | "aflmujlxxy", 89 | "edydtfyvpr", 90 | "nrrdxpibno", 91 | "lzavdwnasq", 92 | "cfmkkspgxd", 93 | "zkieyyejli", 94 | "uzgjmycefq", 95 | "pwhuafsdmd", 96 | "htblqmlnem", 97 | "loqhdoggub", 98 | "thaneejlnz", 99 | "tffydqyvuv", 100 | "ubatmpwlvq", 101 | "lqmspwfeuh", 102 | "upfvzbshvs", 103 | "uezupxkawl", 104 | "nlttwsdgcq", 105 | "vqjbleazcs", 106 | "faobxtvixg", 107 | "gbtqzvyiqf", 108 | "itovolfijo", 109 | ]; 110 | 111 | fuse.search_text_in_string_list("aa", &random_strings, 10 as usize, &test); 112 | } 113 | -------------------------------------------------------------------------------- /examples/fuseable-search.rs: -------------------------------------------------------------------------------- 1 | use fuse_rust::{FResult, Fuse, FuseProperty, Fuseable, FuseableSearchResult}; 2 | 3 | #[derive(Debug)] 4 | struct Book<'a> { 5 | title: &'a str, 6 | author: &'a str, 7 | } 8 | 9 | impl Fuseable for Book<'_> { 10 | fn properties(&self) -> Vec { 11 | vec![ 12 | FuseProperty { 13 | value: String::from("title"), 14 | weight: 0.3, 15 | }, 16 | FuseProperty { 17 | value: String::from("author"), 18 | weight: 0.7, 19 | }, 20 | ] 21 | } 22 | 23 | fn lookup(&self, key: &str) -> Option<&str> { 24 | match key { 25 | "title" => Some(self.title), 26 | "author" => Some(self.author), 27 | _ => None, 28 | } 29 | } 30 | } 31 | fn main() { 32 | let books = [ 33 | Book { 34 | author: "John X", 35 | title: "Old Man's War fiction", 36 | }, 37 | Book { 38 | author: "P.D. Mans", 39 | title: "Right Ho Jeeves", 40 | }, 41 | ]; 42 | 43 | let fuse = Fuse::default(); 44 | let results = fuse.search_text_in_fuse_list("man", &books); 45 | 46 | assert_eq!( 47 | results, 48 | vec!( 49 | FuseableSearchResult { 50 | index: 1, 51 | score: 0.015000000000000003, 52 | results: vec!(FResult { 53 | value: String::from("author"), 54 | score: 0.015000000000000003, 55 | ranges: vec!((5..8)), 56 | }), 57 | }, 58 | FuseableSearchResult { 59 | index: 0, 60 | score: 0.027999999999999997, 61 | results: vec!(FResult { 62 | value: String::from("title"), 63 | score: 0.027999999999999997, 64 | ranges: vec!((4..7)), 65 | }) 66 | } 67 | ), 68 | "Fuseable Search returned incorrect results" 69 | ); 70 | 71 | results.iter().for_each(|result| { 72 | println!( 73 | r#" 74 | index: {} 75 | score: {} 76 | results: {:?} 77 | ---------------"#, 78 | result.index, result.score, result.results 79 | ) 80 | }); 81 | } 82 | -------------------------------------------------------------------------------- /examples/iterable-search.rs: -------------------------------------------------------------------------------- 1 | use fuse_rust::{Fuse, SearchResult}; 2 | 3 | fn main() { 4 | let fuse = Fuse::default(); 5 | let books = ["The Silmarillion", "The Lock Artist", "The Lost Symbol"]; 6 | 7 | let results = fuse.search_text_in_iterable("Te silm", books.iter()); 8 | assert_eq!( 9 | results, 10 | vec!( 11 | SearchResult { 12 | index: 0, 13 | score: 0.14285714285714285, 14 | ranges: vec!((0..1), (2..8), (10..14)), 15 | }, 16 | SearchResult { 17 | index: 2, 18 | score: 0.49857142857142855, 19 | ranges: vec!((0..1), (2..5), (6..10), (11..12), (14..15)), 20 | }, 21 | SearchResult { 22 | index: 1, 23 | score: 0.5714285714285714, 24 | ranges: vec!((0..1), (2..5), (8..9), (11..15)), 25 | }, 26 | ), 27 | "Iterable search returned incorrect results" 28 | ); 29 | dbg!(results); 30 | } 31 | -------------------------------------------------------------------------------- /examples/search-bar/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ab_glyph" 7 | version = "0.2.18" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "4dcdbc68024b653943864d436fe8a24b028095bc1cf91a8926f8241e4aaffe59" 10 | dependencies = [ 11 | "ab_glyph_rasterizer", 12 | "owned_ttf_parser", 13 | ] 14 | 15 | [[package]] 16 | name = "ab_glyph_rasterizer" 17 | version = "0.1.7" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "330223a1aecc308757b9926e9391c9b47f8ef2dbd8aea9df88312aea18c5e8d6" 20 | 21 | [[package]] 22 | name = "adler" 23 | version = "1.0.2" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 26 | 27 | [[package]] 28 | name = "ahash" 29 | version = "0.7.6" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 32 | dependencies = [ 33 | "getrandom", 34 | "once_cell", 35 | "version_check", 36 | ] 37 | 38 | [[package]] 39 | name = "android_system_properties" 40 | version = "0.1.5" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 43 | dependencies = [ 44 | "libc", 45 | ] 46 | 47 | [[package]] 48 | name = "approx" 49 | version = "0.5.1" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" 52 | dependencies = [ 53 | "num-traits", 54 | ] 55 | 56 | [[package]] 57 | name = "arrayref" 58 | version = "0.3.6" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 61 | 62 | [[package]] 63 | name = "arrayvec" 64 | version = "0.5.2" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 67 | 68 | [[package]] 69 | name = "arrayvec" 70 | version = "0.7.2" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 73 | 74 | [[package]] 75 | name = "ash" 76 | version = "0.37.1+1.3.235" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "911015c962d56e2e4052f40182ca5462ba60a3d2ff04e827c365a0ab3d65726d" 79 | dependencies = [ 80 | "libloading", 81 | ] 82 | 83 | [[package]] 84 | name = "autocfg" 85 | version = "1.1.0" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 88 | 89 | [[package]] 90 | name = "bit-set" 91 | version = "0.5.3" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 94 | dependencies = [ 95 | "bit-vec", 96 | ] 97 | 98 | [[package]] 99 | name = "bit-vec" 100 | version = "0.6.3" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 103 | 104 | [[package]] 105 | name = "bitflags" 106 | version = "1.3.2" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 109 | 110 | [[package]] 111 | name = "block" 112 | version = "0.1.6" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 115 | 116 | [[package]] 117 | name = "bumpalo" 118 | version = "3.11.1" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" 121 | 122 | [[package]] 123 | name = "bytemuck" 124 | version = "1.12.3" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" 127 | dependencies = [ 128 | "bytemuck_derive", 129 | ] 130 | 131 | [[package]] 132 | name = "bytemuck_derive" 133 | version = "1.3.0" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4" 136 | dependencies = [ 137 | "proc-macro2", 138 | "quote", 139 | "syn", 140 | ] 141 | 142 | [[package]] 143 | name = "byteorder" 144 | version = "1.4.3" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 147 | 148 | [[package]] 149 | name = "calloop" 150 | version = "0.10.4" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "19457a0da465234abd76134a5c2a910c14bd3c5558463e4396ab9a37a328e465" 153 | dependencies = [ 154 | "log", 155 | "nix 0.25.1", 156 | "slotmap", 157 | "thiserror", 158 | "vec_map", 159 | ] 160 | 161 | [[package]] 162 | name = "cc" 163 | version = "1.0.77" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" 166 | 167 | [[package]] 168 | name = "cfg-if" 169 | version = "1.0.0" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 172 | 173 | [[package]] 174 | name = "cfg_aliases" 175 | version = "0.1.1" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" 178 | 179 | [[package]] 180 | name = "clipboard-win" 181 | version = "4.4.2" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219" 184 | dependencies = [ 185 | "error-code", 186 | "str-buf", 187 | "winapi", 188 | ] 189 | 190 | [[package]] 191 | name = "clipboard_macos" 192 | version = "0.1.0" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95" 195 | dependencies = [ 196 | "objc", 197 | "objc-foundation", 198 | "objc_id", 199 | ] 200 | 201 | [[package]] 202 | name = "clipboard_wayland" 203 | version = "0.2.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "6f6364a9f7a66f2ac1a1a098aa1c7f6b686f2496c6ac5e5c0d773445df912747" 206 | dependencies = [ 207 | "smithay-clipboard", 208 | ] 209 | 210 | [[package]] 211 | name = "clipboard_x11" 212 | version = "0.4.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "983a7010836ecd04dde2c6d27a0cb56ec5d21572177e782bdcb24a600124e921" 215 | dependencies = [ 216 | "thiserror", 217 | "x11rb", 218 | ] 219 | 220 | [[package]] 221 | name = "cmake" 222 | version = "0.1.49" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" 225 | dependencies = [ 226 | "cc", 227 | ] 228 | 229 | [[package]] 230 | name = "cocoa" 231 | version = "0.24.1" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" 234 | dependencies = [ 235 | "bitflags", 236 | "block", 237 | "cocoa-foundation", 238 | "core-foundation", 239 | "core-graphics", 240 | "foreign-types 0.3.2", 241 | "libc", 242 | "objc", 243 | ] 244 | 245 | [[package]] 246 | name = "cocoa-foundation" 247 | version = "0.1.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" 250 | dependencies = [ 251 | "bitflags", 252 | "block", 253 | "core-foundation", 254 | "core-graphics-types", 255 | "foreign-types 0.3.2", 256 | "libc", 257 | "objc", 258 | ] 259 | 260 | [[package]] 261 | name = "codespan-reporting" 262 | version = "0.11.1" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 265 | dependencies = [ 266 | "termcolor", 267 | "unicode-width", 268 | ] 269 | 270 | [[package]] 271 | name = "const_panic" 272 | version = "0.2.7" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf" 275 | 276 | [[package]] 277 | name = "core-foundation" 278 | version = "0.9.3" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 281 | dependencies = [ 282 | "core-foundation-sys", 283 | "libc", 284 | ] 285 | 286 | [[package]] 287 | name = "core-foundation-sys" 288 | version = "0.8.3" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 291 | 292 | [[package]] 293 | name = "core-graphics" 294 | version = "0.22.3" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" 297 | dependencies = [ 298 | "bitflags", 299 | "core-foundation", 300 | "core-graphics-types", 301 | "foreign-types 0.3.2", 302 | "libc", 303 | ] 304 | 305 | [[package]] 306 | name = "core-graphics-types" 307 | version = "0.1.1" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" 310 | dependencies = [ 311 | "bitflags", 312 | "core-foundation", 313 | "foreign-types 0.3.2", 314 | "libc", 315 | ] 316 | 317 | [[package]] 318 | name = "core-text" 319 | version = "19.2.0" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" 322 | dependencies = [ 323 | "core-foundation", 324 | "core-graphics", 325 | "foreign-types 0.3.2", 326 | "libc", 327 | ] 328 | 329 | [[package]] 330 | name = "crc32fast" 331 | version = "1.3.2" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 334 | dependencies = [ 335 | "cfg-if", 336 | ] 337 | 338 | [[package]] 339 | name = "crossbeam-channel" 340 | version = "0.5.6" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" 343 | dependencies = [ 344 | "cfg-if", 345 | "crossbeam-utils", 346 | ] 347 | 348 | [[package]] 349 | name = "crossbeam-deque" 350 | version = "0.8.2" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" 353 | dependencies = [ 354 | "cfg-if", 355 | "crossbeam-epoch", 356 | "crossbeam-utils", 357 | ] 358 | 359 | [[package]] 360 | name = "crossbeam-epoch" 361 | version = "0.9.13" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" 364 | dependencies = [ 365 | "autocfg", 366 | "cfg-if", 367 | "crossbeam-utils", 368 | "memoffset 0.7.1", 369 | "scopeguard", 370 | ] 371 | 372 | [[package]] 373 | name = "crossbeam-utils" 374 | version = "0.8.14" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" 377 | dependencies = [ 378 | "cfg-if", 379 | ] 380 | 381 | [[package]] 382 | name = "crossfont" 383 | version = "0.5.1" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" 386 | dependencies = [ 387 | "cocoa", 388 | "core-foundation", 389 | "core-foundation-sys", 390 | "core-graphics", 391 | "core-text", 392 | "dwrote", 393 | "foreign-types 0.5.0", 394 | "freetype-rs", 395 | "libc", 396 | "log", 397 | "objc", 398 | "once_cell", 399 | "pkg-config", 400 | "servo-fontconfig", 401 | "winapi", 402 | ] 403 | 404 | [[package]] 405 | name = "cty" 406 | version = "0.2.2" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" 409 | 410 | [[package]] 411 | name = "d3d12" 412 | version = "0.5.0" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "827914e1f53b1e0e025ecd3d967a7836b7bcb54520f90e21ef8df7b4d88a2759" 415 | dependencies = [ 416 | "bitflags", 417 | "libloading", 418 | "winapi", 419 | ] 420 | 421 | [[package]] 422 | name = "darling" 423 | version = "0.13.4" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" 426 | dependencies = [ 427 | "darling_core", 428 | "darling_macro", 429 | ] 430 | 431 | [[package]] 432 | name = "darling_core" 433 | version = "0.13.4" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" 436 | dependencies = [ 437 | "fnv", 438 | "ident_case", 439 | "proc-macro2", 440 | "quote", 441 | "strsim", 442 | "syn", 443 | ] 444 | 445 | [[package]] 446 | name = "darling_macro" 447 | version = "0.13.4" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" 450 | dependencies = [ 451 | "darling_core", 452 | "quote", 453 | "syn", 454 | ] 455 | 456 | [[package]] 457 | name = "dispatch" 458 | version = "0.2.0" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 461 | 462 | [[package]] 463 | name = "dlib" 464 | version = "0.5.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" 467 | dependencies = [ 468 | "libloading", 469 | ] 470 | 471 | [[package]] 472 | name = "downcast-rs" 473 | version = "1.2.0" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" 476 | 477 | [[package]] 478 | name = "dwrote" 479 | version = "0.11.0" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" 482 | dependencies = [ 483 | "lazy_static", 484 | "libc", 485 | "serde", 486 | "serde_derive", 487 | "winapi", 488 | "wio", 489 | ] 490 | 491 | [[package]] 492 | name = "either" 493 | version = "1.8.0" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" 496 | 497 | [[package]] 498 | name = "encase" 499 | version = "0.3.0" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "0a516181e9a36e8982cb37933c5e7dba638c42938cacde46ee4e5b4156f881b9" 502 | dependencies = [ 503 | "const_panic", 504 | "encase_derive", 505 | "glam", 506 | "thiserror", 507 | ] 508 | 509 | [[package]] 510 | name = "encase_derive" 511 | version = "0.3.0" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "f5b802412eea315f29f2bb2da3a5963cd6121f56eaa06aebcdc0c54eea578f22" 514 | dependencies = [ 515 | "encase_derive_impl", 516 | ] 517 | 518 | [[package]] 519 | name = "encase_derive_impl" 520 | version = "0.3.0" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "0f2f4de457d974f548d2c2a16f709ebd81013579e543bd1a9b19ced88132c2cf" 523 | dependencies = [ 524 | "proc-macro2", 525 | "quote", 526 | "syn", 527 | ] 528 | 529 | [[package]] 530 | name = "error-code" 531 | version = "2.3.1" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" 534 | dependencies = [ 535 | "libc", 536 | "str-buf", 537 | ] 538 | 539 | [[package]] 540 | name = "euclid" 541 | version = "0.22.7" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "b52c2ef4a78da0ba68fbe1fd920627411096d2ac478f7f4c9f3a54ba6705bade" 544 | dependencies = [ 545 | "num-traits", 546 | ] 547 | 548 | [[package]] 549 | name = "expat-sys" 550 | version = "2.1.6" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" 553 | dependencies = [ 554 | "cmake", 555 | "pkg-config", 556 | ] 557 | 558 | [[package]] 559 | name = "find-crate" 560 | version = "0.6.3" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" 563 | dependencies = [ 564 | "toml", 565 | ] 566 | 567 | [[package]] 568 | name = "flate2" 569 | version = "1.0.25" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" 572 | dependencies = [ 573 | "crc32fast", 574 | "miniz_oxide", 575 | ] 576 | 577 | [[package]] 578 | name = "fnv" 579 | version = "1.0.7" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 582 | 583 | [[package]] 584 | name = "foreign-types" 585 | version = "0.3.2" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 588 | dependencies = [ 589 | "foreign-types-shared 0.1.1", 590 | ] 591 | 592 | [[package]] 593 | name = "foreign-types" 594 | version = "0.5.0" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" 597 | dependencies = [ 598 | "foreign-types-macros", 599 | "foreign-types-shared 0.3.1", 600 | ] 601 | 602 | [[package]] 603 | name = "foreign-types-macros" 604 | version = "0.2.2" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "c8469d0d40519bc608ec6863f1cc88f3f1deee15913f2f3b3e573d81ed38cccc" 607 | dependencies = [ 608 | "proc-macro2", 609 | "quote", 610 | "syn", 611 | ] 612 | 613 | [[package]] 614 | name = "foreign-types-shared" 615 | version = "0.1.1" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 618 | 619 | [[package]] 620 | name = "foreign-types-shared" 621 | version = "0.3.1" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" 624 | 625 | [[package]] 626 | name = "freetype-rs" 627 | version = "0.26.0" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" 630 | dependencies = [ 631 | "bitflags", 632 | "freetype-sys", 633 | "libc", 634 | ] 635 | 636 | [[package]] 637 | name = "freetype-sys" 638 | version = "0.13.1" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" 641 | dependencies = [ 642 | "cmake", 643 | "libc", 644 | "pkg-config", 645 | ] 646 | 647 | [[package]] 648 | name = "fuse-rust" 649 | version = "0.3.0" 650 | dependencies = [ 651 | "crossbeam-utils", 652 | ] 653 | 654 | [[package]] 655 | name = "futures" 656 | version = "0.3.25" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" 659 | dependencies = [ 660 | "futures-channel", 661 | "futures-core", 662 | "futures-executor", 663 | "futures-io", 664 | "futures-sink", 665 | "futures-task", 666 | "futures-util", 667 | ] 668 | 669 | [[package]] 670 | name = "futures-channel" 671 | version = "0.3.25" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" 674 | dependencies = [ 675 | "futures-core", 676 | "futures-sink", 677 | ] 678 | 679 | [[package]] 680 | name = "futures-core" 681 | version = "0.3.25" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" 684 | 685 | [[package]] 686 | name = "futures-executor" 687 | version = "0.3.25" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" 690 | dependencies = [ 691 | "futures-core", 692 | "futures-task", 693 | "futures-util", 694 | "num_cpus", 695 | ] 696 | 697 | [[package]] 698 | name = "futures-io" 699 | version = "0.3.25" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" 702 | 703 | [[package]] 704 | name = "futures-macro" 705 | version = "0.3.25" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" 708 | dependencies = [ 709 | "proc-macro2", 710 | "quote", 711 | "syn", 712 | ] 713 | 714 | [[package]] 715 | name = "futures-sink" 716 | version = "0.3.25" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" 719 | 720 | [[package]] 721 | name = "futures-task" 722 | version = "0.3.25" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" 725 | 726 | [[package]] 727 | name = "futures-util" 728 | version = "0.3.25" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" 731 | dependencies = [ 732 | "futures-channel", 733 | "futures-core", 734 | "futures-io", 735 | "futures-macro", 736 | "futures-sink", 737 | "futures-task", 738 | "memchr", 739 | "pin-project-lite", 740 | "pin-utils", 741 | "slab", 742 | ] 743 | 744 | [[package]] 745 | name = "fxhash" 746 | version = "0.2.1" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 749 | dependencies = [ 750 | "byteorder", 751 | ] 752 | 753 | [[package]] 754 | name = "gethostname" 755 | version = "0.2.3" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" 758 | dependencies = [ 759 | "libc", 760 | "winapi", 761 | ] 762 | 763 | [[package]] 764 | name = "getrandom" 765 | version = "0.2.8" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 768 | dependencies = [ 769 | "cfg-if", 770 | "libc", 771 | "wasi", 772 | ] 773 | 774 | [[package]] 775 | name = "glam" 776 | version = "0.21.3" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815" 779 | 780 | [[package]] 781 | name = "glow" 782 | version = "0.11.2" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919" 785 | dependencies = [ 786 | "js-sys", 787 | "slotmap", 788 | "wasm-bindgen", 789 | "web-sys", 790 | ] 791 | 792 | [[package]] 793 | name = "glyph_brush" 794 | version = "0.7.5" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "ac02497410cdb5062cc056a33f2e1e19ff69fbf26a4be9a02bf29d6e17ea105b" 797 | dependencies = [ 798 | "glyph_brush_draw_cache", 799 | "glyph_brush_layout", 800 | "log", 801 | "ordered-float", 802 | "rustc-hash", 803 | "twox-hash", 804 | ] 805 | 806 | [[package]] 807 | name = "glyph_brush_draw_cache" 808 | version = "0.1.5" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "6010675390f6889e09a21e2c8b575b3ee25667ea8237a8d59423f73cb8c28610" 811 | dependencies = [ 812 | "ab_glyph", 813 | "crossbeam-channel", 814 | "crossbeam-deque", 815 | "linked-hash-map", 816 | "rayon", 817 | "rustc-hash", 818 | ] 819 | 820 | [[package]] 821 | name = "glyph_brush_layout" 822 | version = "0.2.3" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38" 825 | dependencies = [ 826 | "ab_glyph", 827 | "approx", 828 | "xi-unicode", 829 | ] 830 | 831 | [[package]] 832 | name = "gpu-alloc" 833 | version = "0.5.3" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "7fc59e5f710e310e76e6707f86c561dd646f69a8876da9131703b2f717de818d" 836 | dependencies = [ 837 | "bitflags", 838 | "gpu-alloc-types", 839 | ] 840 | 841 | [[package]] 842 | name = "gpu-alloc-types" 843 | version = "0.2.0" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" 846 | dependencies = [ 847 | "bitflags", 848 | ] 849 | 850 | [[package]] 851 | name = "gpu-descriptor" 852 | version = "0.2.3" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" 855 | dependencies = [ 856 | "bitflags", 857 | "gpu-descriptor-types", 858 | "hashbrown", 859 | ] 860 | 861 | [[package]] 862 | name = "gpu-descriptor-types" 863 | version = "0.1.1" 864 | source = "registry+https://github.com/rust-lang/crates.io-index" 865 | checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" 866 | dependencies = [ 867 | "bitflags", 868 | ] 869 | 870 | [[package]] 871 | name = "guillotiere" 872 | version = "0.6.2" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" 875 | dependencies = [ 876 | "euclid", 877 | "svg_fmt", 878 | ] 879 | 880 | [[package]] 881 | name = "hashbrown" 882 | version = "0.12.3" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 885 | dependencies = [ 886 | "ahash", 887 | ] 888 | 889 | [[package]] 890 | name = "hermit-abi" 891 | version = "0.1.19" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 894 | dependencies = [ 895 | "libc", 896 | ] 897 | 898 | [[package]] 899 | name = "hexf-parse" 900 | version = "0.2.1" 901 | source = "registry+https://github.com/rust-lang/crates.io-index" 902 | checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" 903 | 904 | [[package]] 905 | name = "iced" 906 | version = "0.5.2" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "139821b0929b3c00943b3b73405ee5ecf9a8863122c74622ddeda55a8553db1c" 909 | dependencies = [ 910 | "iced_core", 911 | "iced_futures", 912 | "iced_graphics", 913 | "iced_native", 914 | "iced_wgpu", 915 | "iced_winit", 916 | "thiserror", 917 | ] 918 | 919 | [[package]] 920 | name = "iced_core" 921 | version = "0.6.1" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "b55abd96c8580c45614f63725c760e2c9a1fdaf5071c7504197da97fa24f183a" 924 | dependencies = [ 925 | "bitflags", 926 | "palette", 927 | "wasm-timer", 928 | ] 929 | 930 | [[package]] 931 | name = "iced_futures" 932 | version = "0.5.1" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "3cc3a9fd79b857228dde2a3e923a04ade4095abeda33248c6230e8c909749366" 935 | dependencies = [ 936 | "futures", 937 | "log", 938 | "wasm-bindgen-futures", 939 | "wasm-timer", 940 | ] 941 | 942 | [[package]] 943 | name = "iced_graphics" 944 | version = "0.4.0" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "c0bed954a9e61e665c6c965b56a0152d87288088736d1ca99c96b166875c5707" 947 | dependencies = [ 948 | "bitflags", 949 | "bytemuck", 950 | "glam", 951 | "iced_native", 952 | "iced_style", 953 | "log", 954 | "raw-window-handle 0.5.0", 955 | "thiserror", 956 | ] 957 | 958 | [[package]] 959 | name = "iced_native" 960 | version = "0.6.1" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "61964acdd967f58ee6194b0b746c5656826f1e4aafc8f12de28ad4f7ced8ec0b" 963 | dependencies = [ 964 | "iced_core", 965 | "iced_futures", 966 | "iced_style", 967 | "num-traits", 968 | "twox-hash", 969 | "unicode-segmentation", 970 | ] 971 | 972 | [[package]] 973 | name = "iced_style" 974 | version = "0.5.0" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "ca6cad47936109f1424a9c1d4e13899621ebcd5945677dd3cf7b3dd4b74e665c" 977 | dependencies = [ 978 | "iced_core", 979 | "once_cell", 980 | "palette", 981 | ] 982 | 983 | [[package]] 984 | name = "iced_wgpu" 985 | version = "0.6.1" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "132e359d07022fb1066cb48f6ab6aba9b1a48c2f51060e7a9929b09851ab45b7" 988 | dependencies = [ 989 | "bitflags", 990 | "bytemuck", 991 | "encase", 992 | "futures", 993 | "glam", 994 | "glyph_brush", 995 | "guillotiere", 996 | "iced_graphics", 997 | "iced_native", 998 | "log", 999 | "raw-window-handle 0.5.0", 1000 | "wgpu", 1001 | "wgpu_glyph", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "iced_winit" 1006 | version = "0.5.1" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "217f078cb38bedf1d4283eca4c82327e1ef0de8c78d2652187108ebd1e613a14" 1009 | dependencies = [ 1010 | "iced_futures", 1011 | "iced_graphics", 1012 | "iced_native", 1013 | "log", 1014 | "thiserror", 1015 | "web-sys", 1016 | "winapi", 1017 | "window_clipboard", 1018 | "winit", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "ident_case" 1023 | version = "1.0.1" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1026 | 1027 | [[package]] 1028 | name = "indexmap" 1029 | version = "1.9.2" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" 1032 | dependencies = [ 1033 | "autocfg", 1034 | "hashbrown", 1035 | ] 1036 | 1037 | [[package]] 1038 | name = "instant" 1039 | version = "0.1.12" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 1042 | dependencies = [ 1043 | "cfg-if", 1044 | "js-sys", 1045 | "wasm-bindgen", 1046 | "web-sys", 1047 | ] 1048 | 1049 | [[package]] 1050 | name = "jni-sys" 1051 | version = "0.3.0" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1054 | 1055 | [[package]] 1056 | name = "js-sys" 1057 | version = "0.3.60" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" 1060 | dependencies = [ 1061 | "wasm-bindgen", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "khronos-egl" 1066 | version = "4.1.0" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" 1069 | dependencies = [ 1070 | "libc", 1071 | "libloading", 1072 | "pkg-config", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "lazy_static" 1077 | version = "1.4.0" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1080 | 1081 | [[package]] 1082 | name = "libc" 1083 | version = "0.2.138" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" 1086 | 1087 | [[package]] 1088 | name = "libloading" 1089 | version = "0.7.4" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 1092 | dependencies = [ 1093 | "cfg-if", 1094 | "winapi", 1095 | ] 1096 | 1097 | [[package]] 1098 | name = "linked-hash-map" 1099 | version = "0.5.6" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1102 | 1103 | [[package]] 1104 | name = "lock_api" 1105 | version = "0.4.9" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 1108 | dependencies = [ 1109 | "autocfg", 1110 | "scopeguard", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "log" 1115 | version = "0.4.17" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 1118 | dependencies = [ 1119 | "cfg-if", 1120 | ] 1121 | 1122 | [[package]] 1123 | name = "malloc_buf" 1124 | version = "0.0.6" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1127 | dependencies = [ 1128 | "libc", 1129 | ] 1130 | 1131 | [[package]] 1132 | name = "memchr" 1133 | version = "2.5.0" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 1136 | 1137 | [[package]] 1138 | name = "memmap2" 1139 | version = "0.5.8" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" 1142 | dependencies = [ 1143 | "libc", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "memoffset" 1148 | version = "0.6.5" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 1151 | dependencies = [ 1152 | "autocfg", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "memoffset" 1157 | version = "0.7.1" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 1160 | dependencies = [ 1161 | "autocfg", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "metal" 1166 | version = "0.24.0" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "de11355d1f6781482d027a3b4d4de7825dcedb197bf573e0596d00008402d060" 1169 | dependencies = [ 1170 | "bitflags", 1171 | "block", 1172 | "core-graphics-types", 1173 | "foreign-types 0.3.2", 1174 | "log", 1175 | "objc", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "minimal-lexical" 1180 | version = "0.2.1" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1183 | 1184 | [[package]] 1185 | name = "miniz_oxide" 1186 | version = "0.6.2" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" 1189 | dependencies = [ 1190 | "adler", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "mio" 1195 | version = "0.8.5" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" 1198 | dependencies = [ 1199 | "libc", 1200 | "log", 1201 | "wasi", 1202 | "windows-sys 0.42.0", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "naga" 1207 | version = "0.10.0" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" 1210 | dependencies = [ 1211 | "bit-set", 1212 | "bitflags", 1213 | "codespan-reporting", 1214 | "hexf-parse", 1215 | "indexmap", 1216 | "log", 1217 | "num-traits", 1218 | "rustc-hash", 1219 | "spirv", 1220 | "termcolor", 1221 | "thiserror", 1222 | "unicode-xid", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "ndk" 1227 | version = "0.7.0" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" 1230 | dependencies = [ 1231 | "bitflags", 1232 | "jni-sys", 1233 | "ndk-sys", 1234 | "num_enum", 1235 | "raw-window-handle 0.5.0", 1236 | "thiserror", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "ndk-context" 1241 | version = "0.1.1" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 1244 | 1245 | [[package]] 1246 | name = "ndk-glue" 1247 | version = "0.7.0" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" 1250 | dependencies = [ 1251 | "libc", 1252 | "log", 1253 | "ndk", 1254 | "ndk-context", 1255 | "ndk-macro", 1256 | "ndk-sys", 1257 | "once_cell", 1258 | "parking_lot 0.12.1", 1259 | ] 1260 | 1261 | [[package]] 1262 | name = "ndk-macro" 1263 | version = "0.3.0" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" 1266 | dependencies = [ 1267 | "darling", 1268 | "proc-macro-crate", 1269 | "proc-macro2", 1270 | "quote", 1271 | "syn", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "ndk-sys" 1276 | version = "0.4.1+23.1.7779620" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" 1279 | dependencies = [ 1280 | "jni-sys", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "nix" 1285 | version = "0.22.3" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" 1288 | dependencies = [ 1289 | "bitflags", 1290 | "cc", 1291 | "cfg-if", 1292 | "libc", 1293 | "memoffset 0.6.5", 1294 | ] 1295 | 1296 | [[package]] 1297 | name = "nix" 1298 | version = "0.24.3" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" 1301 | dependencies = [ 1302 | "bitflags", 1303 | "cfg-if", 1304 | "libc", 1305 | "memoffset 0.6.5", 1306 | ] 1307 | 1308 | [[package]] 1309 | name = "nix" 1310 | version = "0.25.1" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" 1313 | dependencies = [ 1314 | "autocfg", 1315 | "bitflags", 1316 | "cfg-if", 1317 | "libc", 1318 | "memoffset 0.6.5", 1319 | ] 1320 | 1321 | [[package]] 1322 | name = "nom" 1323 | version = "7.1.1" 1324 | source = "registry+https://github.com/rust-lang/crates.io-index" 1325 | checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" 1326 | dependencies = [ 1327 | "memchr", 1328 | "minimal-lexical", 1329 | ] 1330 | 1331 | [[package]] 1332 | name = "num-traits" 1333 | version = "0.2.15" 1334 | source = "registry+https://github.com/rust-lang/crates.io-index" 1335 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1336 | dependencies = [ 1337 | "autocfg", 1338 | ] 1339 | 1340 | [[package]] 1341 | name = "num_cpus" 1342 | version = "1.14.0" 1343 | source = "registry+https://github.com/rust-lang/crates.io-index" 1344 | checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" 1345 | dependencies = [ 1346 | "hermit-abi", 1347 | "libc", 1348 | ] 1349 | 1350 | [[package]] 1351 | name = "num_enum" 1352 | version = "0.5.7" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" 1355 | dependencies = [ 1356 | "num_enum_derive", 1357 | ] 1358 | 1359 | [[package]] 1360 | name = "num_enum_derive" 1361 | version = "0.5.7" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" 1364 | dependencies = [ 1365 | "proc-macro-crate", 1366 | "proc-macro2", 1367 | "quote", 1368 | "syn", 1369 | ] 1370 | 1371 | [[package]] 1372 | name = "objc" 1373 | version = "0.2.7" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1376 | dependencies = [ 1377 | "malloc_buf", 1378 | "objc_exception", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "objc-foundation" 1383 | version = "0.1.1" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" 1386 | dependencies = [ 1387 | "block", 1388 | "objc", 1389 | "objc_id", 1390 | ] 1391 | 1392 | [[package]] 1393 | name = "objc_exception" 1394 | version = "0.1.2" 1395 | source = "registry+https://github.com/rust-lang/crates.io-index" 1396 | checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" 1397 | dependencies = [ 1398 | "cc", 1399 | ] 1400 | 1401 | [[package]] 1402 | name = "objc_id" 1403 | version = "0.1.1" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 1406 | dependencies = [ 1407 | "objc", 1408 | ] 1409 | 1410 | [[package]] 1411 | name = "once_cell" 1412 | version = "1.16.0" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" 1415 | 1416 | [[package]] 1417 | name = "ordered-float" 1418 | version = "3.4.0" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "d84eb1409416d254e4a9c8fa56cc24701755025b458f0fcd8e59e1f5f40c23bf" 1421 | dependencies = [ 1422 | "num-traits", 1423 | ] 1424 | 1425 | [[package]] 1426 | name = "owned_ttf_parser" 1427 | version = "0.17.1" 1428 | source = "registry+https://github.com/rust-lang/crates.io-index" 1429 | checksum = "18904d3c65493a9f0d7542293d1a7f69bfdc309a6b9ef4f46dc3e58b0577edc5" 1430 | dependencies = [ 1431 | "ttf-parser", 1432 | ] 1433 | 1434 | [[package]] 1435 | name = "palette" 1436 | version = "0.6.1" 1437 | source = "registry+https://github.com/rust-lang/crates.io-index" 1438 | checksum = "8f9cd68f7112581033f157e56c77ac4a5538ec5836a2e39284e65bd7d7275e49" 1439 | dependencies = [ 1440 | "approx", 1441 | "num-traits", 1442 | "palette_derive", 1443 | "phf", 1444 | ] 1445 | 1446 | [[package]] 1447 | name = "palette_derive" 1448 | version = "0.6.1" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "05eedf46a8e7c27f74af0c9cfcdb004ceca158cb1b918c6f68f8d7a549b3e427" 1451 | dependencies = [ 1452 | "find-crate", 1453 | "proc-macro2", 1454 | "quote", 1455 | "syn", 1456 | ] 1457 | 1458 | [[package]] 1459 | name = "parking_lot" 1460 | version = "0.11.2" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 1463 | dependencies = [ 1464 | "instant", 1465 | "lock_api", 1466 | "parking_lot_core 0.8.5", 1467 | ] 1468 | 1469 | [[package]] 1470 | name = "parking_lot" 1471 | version = "0.12.1" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1474 | dependencies = [ 1475 | "lock_api", 1476 | "parking_lot_core 0.9.5", 1477 | ] 1478 | 1479 | [[package]] 1480 | name = "parking_lot_core" 1481 | version = "0.8.5" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 1484 | dependencies = [ 1485 | "cfg-if", 1486 | "instant", 1487 | "libc", 1488 | "redox_syscall", 1489 | "smallvec", 1490 | "winapi", 1491 | ] 1492 | 1493 | [[package]] 1494 | name = "parking_lot_core" 1495 | version = "0.9.5" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" 1498 | dependencies = [ 1499 | "cfg-if", 1500 | "libc", 1501 | "redox_syscall", 1502 | "smallvec", 1503 | "windows-sys 0.42.0", 1504 | ] 1505 | 1506 | [[package]] 1507 | name = "percent-encoding" 1508 | version = "2.2.0" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 1511 | 1512 | [[package]] 1513 | name = "phf" 1514 | version = "0.11.1" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" 1517 | dependencies = [ 1518 | "phf_macros", 1519 | "phf_shared", 1520 | ] 1521 | 1522 | [[package]] 1523 | name = "phf_generator" 1524 | version = "0.11.1" 1525 | source = "registry+https://github.com/rust-lang/crates.io-index" 1526 | checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" 1527 | dependencies = [ 1528 | "phf_shared", 1529 | "rand", 1530 | ] 1531 | 1532 | [[package]] 1533 | name = "phf_macros" 1534 | version = "0.11.1" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" 1537 | dependencies = [ 1538 | "phf_generator", 1539 | "phf_shared", 1540 | "proc-macro2", 1541 | "quote", 1542 | "syn", 1543 | ] 1544 | 1545 | [[package]] 1546 | name = "phf_shared" 1547 | version = "0.11.1" 1548 | source = "registry+https://github.com/rust-lang/crates.io-index" 1549 | checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" 1550 | dependencies = [ 1551 | "siphasher", 1552 | ] 1553 | 1554 | [[package]] 1555 | name = "pin-project-lite" 1556 | version = "0.2.9" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1559 | 1560 | [[package]] 1561 | name = "pin-utils" 1562 | version = "0.1.0" 1563 | source = "registry+https://github.com/rust-lang/crates.io-index" 1564 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1565 | 1566 | [[package]] 1567 | name = "pkg-config" 1568 | version = "0.3.26" 1569 | source = "registry+https://github.com/rust-lang/crates.io-index" 1570 | checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" 1571 | 1572 | [[package]] 1573 | name = "png" 1574 | version = "0.17.7" 1575 | source = "registry+https://github.com/rust-lang/crates.io-index" 1576 | checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" 1577 | dependencies = [ 1578 | "bitflags", 1579 | "crc32fast", 1580 | "flate2", 1581 | "miniz_oxide", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "ppv-lite86" 1586 | version = "0.2.17" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1589 | 1590 | [[package]] 1591 | name = "proc-macro-crate" 1592 | version = "1.2.1" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" 1595 | dependencies = [ 1596 | "once_cell", 1597 | "thiserror", 1598 | "toml", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "proc-macro2" 1603 | version = "1.0.47" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" 1606 | dependencies = [ 1607 | "unicode-ident", 1608 | ] 1609 | 1610 | [[package]] 1611 | name = "profiling" 1612 | version = "1.0.7" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "74605f360ce573babfe43964cbe520294dcb081afbf8c108fc6e23036b4da2df" 1615 | 1616 | [[package]] 1617 | name = "quote" 1618 | version = "1.0.21" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 1621 | dependencies = [ 1622 | "proc-macro2", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "rand" 1627 | version = "0.8.5" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1630 | dependencies = [ 1631 | "libc", 1632 | "rand_chacha", 1633 | "rand_core", 1634 | ] 1635 | 1636 | [[package]] 1637 | name = "rand_chacha" 1638 | version = "0.3.1" 1639 | source = "registry+https://github.com/rust-lang/crates.io-index" 1640 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1641 | dependencies = [ 1642 | "ppv-lite86", 1643 | "rand_core", 1644 | ] 1645 | 1646 | [[package]] 1647 | name = "rand_core" 1648 | version = "0.6.4" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1651 | dependencies = [ 1652 | "getrandom", 1653 | ] 1654 | 1655 | [[package]] 1656 | name = "range-alloc" 1657 | version = "0.1.2" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" 1660 | 1661 | [[package]] 1662 | name = "raw-window-handle" 1663 | version = "0.3.4" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" 1666 | dependencies = [ 1667 | "libc", 1668 | "raw-window-handle 0.4.3", 1669 | ] 1670 | 1671 | [[package]] 1672 | name = "raw-window-handle" 1673 | version = "0.4.3" 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" 1675 | checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" 1676 | dependencies = [ 1677 | "cty", 1678 | ] 1679 | 1680 | [[package]] 1681 | name = "raw-window-handle" 1682 | version = "0.5.0" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" 1685 | dependencies = [ 1686 | "cty", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "rayon" 1691 | version = "1.6.0" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" 1694 | dependencies = [ 1695 | "crossbeam-deque", 1696 | "either", 1697 | "rayon-core", 1698 | ] 1699 | 1700 | [[package]] 1701 | name = "rayon-core" 1702 | version = "1.10.1" 1703 | source = "registry+https://github.com/rust-lang/crates.io-index" 1704 | checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" 1705 | dependencies = [ 1706 | "crossbeam-channel", 1707 | "crossbeam-deque", 1708 | "crossbeam-utils", 1709 | "num_cpus", 1710 | ] 1711 | 1712 | [[package]] 1713 | name = "redox_syscall" 1714 | version = "0.2.16" 1715 | source = "registry+https://github.com/rust-lang/crates.io-index" 1716 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1717 | dependencies = [ 1718 | "bitflags", 1719 | ] 1720 | 1721 | [[package]] 1722 | name = "renderdoc-sys" 1723 | version = "0.7.1" 1724 | source = "registry+https://github.com/rust-lang/crates.io-index" 1725 | checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" 1726 | 1727 | [[package]] 1728 | name = "rustc-hash" 1729 | version = "1.1.0" 1730 | source = "registry+https://github.com/rust-lang/crates.io-index" 1731 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1732 | 1733 | [[package]] 1734 | name = "safe_arch" 1735 | version = "0.5.2" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" 1738 | dependencies = [ 1739 | "bytemuck", 1740 | ] 1741 | 1742 | [[package]] 1743 | name = "scoped-tls" 1744 | version = "1.0.1" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1747 | 1748 | [[package]] 1749 | name = "scopeguard" 1750 | version = "1.1.0" 1751 | source = "registry+https://github.com/rust-lang/crates.io-index" 1752 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1753 | 1754 | [[package]] 1755 | name = "sctk-adwaita" 1756 | version = "0.4.3" 1757 | source = "registry+https://github.com/rust-lang/crates.io-index" 1758 | checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" 1759 | dependencies = [ 1760 | "crossfont", 1761 | "log", 1762 | "smithay-client-toolkit", 1763 | "tiny-skia", 1764 | ] 1765 | 1766 | [[package]] 1767 | name = "search_bar" 1768 | version = "0.1.0" 1769 | dependencies = [ 1770 | "fuse-rust", 1771 | "iced", 1772 | "once_cell", 1773 | ] 1774 | 1775 | [[package]] 1776 | name = "serde" 1777 | version = "1.0.149" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" 1780 | 1781 | [[package]] 1782 | name = "serde_derive" 1783 | version = "1.0.149" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" 1786 | dependencies = [ 1787 | "proc-macro2", 1788 | "quote", 1789 | "syn", 1790 | ] 1791 | 1792 | [[package]] 1793 | name = "servo-fontconfig" 1794 | version = "0.5.1" 1795 | source = "registry+https://github.com/rust-lang/crates.io-index" 1796 | checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" 1797 | dependencies = [ 1798 | "libc", 1799 | "servo-fontconfig-sys", 1800 | ] 1801 | 1802 | [[package]] 1803 | name = "servo-fontconfig-sys" 1804 | version = "5.1.0" 1805 | source = "registry+https://github.com/rust-lang/crates.io-index" 1806 | checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" 1807 | dependencies = [ 1808 | "expat-sys", 1809 | "freetype-sys", 1810 | "pkg-config", 1811 | ] 1812 | 1813 | [[package]] 1814 | name = "siphasher" 1815 | version = "0.3.10" 1816 | source = "registry+https://github.com/rust-lang/crates.io-index" 1817 | checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" 1818 | 1819 | [[package]] 1820 | name = "slab" 1821 | version = "0.4.7" 1822 | source = "registry+https://github.com/rust-lang/crates.io-index" 1823 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 1824 | dependencies = [ 1825 | "autocfg", 1826 | ] 1827 | 1828 | [[package]] 1829 | name = "slotmap" 1830 | version = "1.0.6" 1831 | source = "registry+https://github.com/rust-lang/crates.io-index" 1832 | checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" 1833 | dependencies = [ 1834 | "version_check", 1835 | ] 1836 | 1837 | [[package]] 1838 | name = "smallvec" 1839 | version = "1.10.0" 1840 | source = "registry+https://github.com/rust-lang/crates.io-index" 1841 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1842 | 1843 | [[package]] 1844 | name = "smithay-client-toolkit" 1845 | version = "0.16.0" 1846 | source = "registry+https://github.com/rust-lang/crates.io-index" 1847 | checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454" 1848 | dependencies = [ 1849 | "bitflags", 1850 | "calloop", 1851 | "dlib", 1852 | "lazy_static", 1853 | "log", 1854 | "memmap2", 1855 | "nix 0.24.3", 1856 | "pkg-config", 1857 | "wayland-client", 1858 | "wayland-cursor", 1859 | "wayland-protocols", 1860 | ] 1861 | 1862 | [[package]] 1863 | name = "smithay-clipboard" 1864 | version = "0.6.6" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" 1867 | dependencies = [ 1868 | "smithay-client-toolkit", 1869 | "wayland-client", 1870 | ] 1871 | 1872 | [[package]] 1873 | name = "spirv" 1874 | version = "0.2.0+1.5.4" 1875 | source = "registry+https://github.com/rust-lang/crates.io-index" 1876 | checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" 1877 | dependencies = [ 1878 | "bitflags", 1879 | "num-traits", 1880 | ] 1881 | 1882 | [[package]] 1883 | name = "static_assertions" 1884 | version = "1.1.0" 1885 | source = "registry+https://github.com/rust-lang/crates.io-index" 1886 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1887 | 1888 | [[package]] 1889 | name = "str-buf" 1890 | version = "1.0.6" 1891 | source = "registry+https://github.com/rust-lang/crates.io-index" 1892 | checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" 1893 | 1894 | [[package]] 1895 | name = "strsim" 1896 | version = "0.10.0" 1897 | source = "registry+https://github.com/rust-lang/crates.io-index" 1898 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1899 | 1900 | [[package]] 1901 | name = "svg_fmt" 1902 | version = "0.4.1" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2" 1905 | 1906 | [[package]] 1907 | name = "syn" 1908 | version = "1.0.105" 1909 | source = "registry+https://github.com/rust-lang/crates.io-index" 1910 | checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" 1911 | dependencies = [ 1912 | "proc-macro2", 1913 | "quote", 1914 | "unicode-ident", 1915 | ] 1916 | 1917 | [[package]] 1918 | name = "termcolor" 1919 | version = "1.1.3" 1920 | source = "registry+https://github.com/rust-lang/crates.io-index" 1921 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1922 | dependencies = [ 1923 | "winapi-util", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "thiserror" 1928 | version = "1.0.37" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" 1931 | dependencies = [ 1932 | "thiserror-impl", 1933 | ] 1934 | 1935 | [[package]] 1936 | name = "thiserror-impl" 1937 | version = "1.0.37" 1938 | source = "registry+https://github.com/rust-lang/crates.io-index" 1939 | checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" 1940 | dependencies = [ 1941 | "proc-macro2", 1942 | "quote", 1943 | "syn", 1944 | ] 1945 | 1946 | [[package]] 1947 | name = "tiny-skia" 1948 | version = "0.7.0" 1949 | source = "registry+https://github.com/rust-lang/crates.io-index" 1950 | checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" 1951 | dependencies = [ 1952 | "arrayref", 1953 | "arrayvec 0.5.2", 1954 | "bytemuck", 1955 | "cfg-if", 1956 | "png", 1957 | "safe_arch", 1958 | "tiny-skia-path", 1959 | ] 1960 | 1961 | [[package]] 1962 | name = "tiny-skia-path" 1963 | version = "0.7.0" 1964 | source = "registry+https://github.com/rust-lang/crates.io-index" 1965 | checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" 1966 | dependencies = [ 1967 | "arrayref", 1968 | "bytemuck", 1969 | ] 1970 | 1971 | [[package]] 1972 | name = "toml" 1973 | version = "0.5.9" 1974 | source = "registry+https://github.com/rust-lang/crates.io-index" 1975 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1976 | dependencies = [ 1977 | "serde", 1978 | ] 1979 | 1980 | [[package]] 1981 | name = "ttf-parser" 1982 | version = "0.17.1" 1983 | source = "registry+https://github.com/rust-lang/crates.io-index" 1984 | checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff" 1985 | 1986 | [[package]] 1987 | name = "twox-hash" 1988 | version = "1.6.3" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" 1991 | dependencies = [ 1992 | "cfg-if", 1993 | "rand", 1994 | "static_assertions", 1995 | ] 1996 | 1997 | [[package]] 1998 | name = "unicode-ident" 1999 | version = "1.0.5" 2000 | source = "registry+https://github.com/rust-lang/crates.io-index" 2001 | checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" 2002 | 2003 | [[package]] 2004 | name = "unicode-segmentation" 2005 | version = "1.10.0" 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" 2007 | checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" 2008 | 2009 | [[package]] 2010 | name = "unicode-width" 2011 | version = "0.1.10" 2012 | source = "registry+https://github.com/rust-lang/crates.io-index" 2013 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 2014 | 2015 | [[package]] 2016 | name = "unicode-xid" 2017 | version = "0.2.4" 2018 | source = "registry+https://github.com/rust-lang/crates.io-index" 2019 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 2020 | 2021 | [[package]] 2022 | name = "vec_map" 2023 | version = "0.8.2" 2024 | source = "registry+https://github.com/rust-lang/crates.io-index" 2025 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 2026 | 2027 | [[package]] 2028 | name = "version_check" 2029 | version = "0.9.4" 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" 2031 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2032 | 2033 | [[package]] 2034 | name = "wasi" 2035 | version = "0.11.0+wasi-snapshot-preview1" 2036 | source = "registry+https://github.com/rust-lang/crates.io-index" 2037 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2038 | 2039 | [[package]] 2040 | name = "wasm-bindgen" 2041 | version = "0.2.83" 2042 | source = "registry+https://github.com/rust-lang/crates.io-index" 2043 | checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" 2044 | dependencies = [ 2045 | "cfg-if", 2046 | "wasm-bindgen-macro", 2047 | ] 2048 | 2049 | [[package]] 2050 | name = "wasm-bindgen-backend" 2051 | version = "0.2.83" 2052 | source = "registry+https://github.com/rust-lang/crates.io-index" 2053 | checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" 2054 | dependencies = [ 2055 | "bumpalo", 2056 | "log", 2057 | "once_cell", 2058 | "proc-macro2", 2059 | "quote", 2060 | "syn", 2061 | "wasm-bindgen-shared", 2062 | ] 2063 | 2064 | [[package]] 2065 | name = "wasm-bindgen-futures" 2066 | version = "0.4.33" 2067 | source = "registry+https://github.com/rust-lang/crates.io-index" 2068 | checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" 2069 | dependencies = [ 2070 | "cfg-if", 2071 | "js-sys", 2072 | "wasm-bindgen", 2073 | "web-sys", 2074 | ] 2075 | 2076 | [[package]] 2077 | name = "wasm-bindgen-macro" 2078 | version = "0.2.83" 2079 | source = "registry+https://github.com/rust-lang/crates.io-index" 2080 | checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" 2081 | dependencies = [ 2082 | "quote", 2083 | "wasm-bindgen-macro-support", 2084 | ] 2085 | 2086 | [[package]] 2087 | name = "wasm-bindgen-macro-support" 2088 | version = "0.2.83" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" 2091 | dependencies = [ 2092 | "proc-macro2", 2093 | "quote", 2094 | "syn", 2095 | "wasm-bindgen-backend", 2096 | "wasm-bindgen-shared", 2097 | ] 2098 | 2099 | [[package]] 2100 | name = "wasm-bindgen-shared" 2101 | version = "0.2.83" 2102 | source = "registry+https://github.com/rust-lang/crates.io-index" 2103 | checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" 2104 | 2105 | [[package]] 2106 | name = "wasm-timer" 2107 | version = "0.2.5" 2108 | source = "registry+https://github.com/rust-lang/crates.io-index" 2109 | checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" 2110 | dependencies = [ 2111 | "futures", 2112 | "js-sys", 2113 | "parking_lot 0.11.2", 2114 | "pin-utils", 2115 | "wasm-bindgen", 2116 | "wasm-bindgen-futures", 2117 | "web-sys", 2118 | ] 2119 | 2120 | [[package]] 2121 | name = "wayland-client" 2122 | version = "0.29.5" 2123 | source = "registry+https://github.com/rust-lang/crates.io-index" 2124 | checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" 2125 | dependencies = [ 2126 | "bitflags", 2127 | "downcast-rs", 2128 | "libc", 2129 | "nix 0.24.3", 2130 | "scoped-tls", 2131 | "wayland-commons", 2132 | "wayland-scanner", 2133 | "wayland-sys", 2134 | ] 2135 | 2136 | [[package]] 2137 | name = "wayland-commons" 2138 | version = "0.29.5" 2139 | source = "registry+https://github.com/rust-lang/crates.io-index" 2140 | checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" 2141 | dependencies = [ 2142 | "nix 0.24.3", 2143 | "once_cell", 2144 | "smallvec", 2145 | "wayland-sys", 2146 | ] 2147 | 2148 | [[package]] 2149 | name = "wayland-cursor" 2150 | version = "0.29.5" 2151 | source = "registry+https://github.com/rust-lang/crates.io-index" 2152 | checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" 2153 | dependencies = [ 2154 | "nix 0.24.3", 2155 | "wayland-client", 2156 | "xcursor", 2157 | ] 2158 | 2159 | [[package]] 2160 | name = "wayland-protocols" 2161 | version = "0.29.5" 2162 | source = "registry+https://github.com/rust-lang/crates.io-index" 2163 | checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" 2164 | dependencies = [ 2165 | "bitflags", 2166 | "wayland-client", 2167 | "wayland-commons", 2168 | "wayland-scanner", 2169 | ] 2170 | 2171 | [[package]] 2172 | name = "wayland-scanner" 2173 | version = "0.29.5" 2174 | source = "registry+https://github.com/rust-lang/crates.io-index" 2175 | checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" 2176 | dependencies = [ 2177 | "proc-macro2", 2178 | "quote", 2179 | "xml-rs", 2180 | ] 2181 | 2182 | [[package]] 2183 | name = "wayland-sys" 2184 | version = "0.29.5" 2185 | source = "registry+https://github.com/rust-lang/crates.io-index" 2186 | checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" 2187 | dependencies = [ 2188 | "dlib", 2189 | "lazy_static", 2190 | "pkg-config", 2191 | ] 2192 | 2193 | [[package]] 2194 | name = "web-sys" 2195 | version = "0.3.60" 2196 | source = "registry+https://github.com/rust-lang/crates.io-index" 2197 | checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" 2198 | dependencies = [ 2199 | "js-sys", 2200 | "wasm-bindgen", 2201 | ] 2202 | 2203 | [[package]] 2204 | name = "wgpu" 2205 | version = "0.14.2" 2206 | source = "registry+https://github.com/rust-lang/crates.io-index" 2207 | checksum = "81f643110d228fd62a60c5ed2ab56c4d5b3704520bd50561174ec4ec74932937" 2208 | dependencies = [ 2209 | "arrayvec 0.7.2", 2210 | "js-sys", 2211 | "log", 2212 | "naga", 2213 | "parking_lot 0.12.1", 2214 | "raw-window-handle 0.5.0", 2215 | "smallvec", 2216 | "static_assertions", 2217 | "wasm-bindgen", 2218 | "wasm-bindgen-futures", 2219 | "web-sys", 2220 | "wgpu-core", 2221 | "wgpu-hal", 2222 | "wgpu-types", 2223 | ] 2224 | 2225 | [[package]] 2226 | name = "wgpu-core" 2227 | version = "0.14.2" 2228 | source = "registry+https://github.com/rust-lang/crates.io-index" 2229 | checksum = "6000d1284ef8eec6076fd5544a73125fd7eb9b635f18dceeb829d826f41724ca" 2230 | dependencies = [ 2231 | "arrayvec 0.7.2", 2232 | "bit-vec", 2233 | "bitflags", 2234 | "cfg_aliases", 2235 | "codespan-reporting", 2236 | "fxhash", 2237 | "log", 2238 | "naga", 2239 | "parking_lot 0.12.1", 2240 | "profiling", 2241 | "raw-window-handle 0.5.0", 2242 | "smallvec", 2243 | "thiserror", 2244 | "web-sys", 2245 | "wgpu-hal", 2246 | "wgpu-types", 2247 | ] 2248 | 2249 | [[package]] 2250 | name = "wgpu-hal" 2251 | version = "0.14.1" 2252 | source = "registry+https://github.com/rust-lang/crates.io-index" 2253 | checksum = "3cc320a61acb26be4f549c9b1b53405c10a223fbfea363ec39474c32c348d12f" 2254 | dependencies = [ 2255 | "android_system_properties", 2256 | "arrayvec 0.7.2", 2257 | "ash", 2258 | "bit-set", 2259 | "bitflags", 2260 | "block", 2261 | "core-graphics-types", 2262 | "d3d12", 2263 | "foreign-types 0.3.2", 2264 | "fxhash", 2265 | "glow", 2266 | "gpu-alloc", 2267 | "gpu-descriptor", 2268 | "js-sys", 2269 | "khronos-egl", 2270 | "libloading", 2271 | "log", 2272 | "metal", 2273 | "naga", 2274 | "objc", 2275 | "parking_lot 0.12.1", 2276 | "profiling", 2277 | "range-alloc", 2278 | "raw-window-handle 0.5.0", 2279 | "renderdoc-sys", 2280 | "smallvec", 2281 | "thiserror", 2282 | "wasm-bindgen", 2283 | "web-sys", 2284 | "wgpu-types", 2285 | "winapi", 2286 | ] 2287 | 2288 | [[package]] 2289 | name = "wgpu-types" 2290 | version = "0.14.1" 2291 | source = "registry+https://github.com/rust-lang/crates.io-index" 2292 | checksum = "fb6b28ef22cac17b9109b25b3bf8c9a103eeb293d7c5f78653979b09140375f6" 2293 | dependencies = [ 2294 | "bitflags", 2295 | ] 2296 | 2297 | [[package]] 2298 | name = "wgpu_glyph" 2299 | version = "0.18.0" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "0cafb82773e0f124a33674dab5de4dff73175aeb921949047ab014efb58fb446" 2302 | dependencies = [ 2303 | "bytemuck", 2304 | "glyph_brush", 2305 | "log", 2306 | "wgpu", 2307 | ] 2308 | 2309 | [[package]] 2310 | name = "winapi" 2311 | version = "0.3.9" 2312 | source = "registry+https://github.com/rust-lang/crates.io-index" 2313 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2314 | dependencies = [ 2315 | "winapi-i686-pc-windows-gnu", 2316 | "winapi-x86_64-pc-windows-gnu", 2317 | ] 2318 | 2319 | [[package]] 2320 | name = "winapi-i686-pc-windows-gnu" 2321 | version = "0.4.0" 2322 | source = "registry+https://github.com/rust-lang/crates.io-index" 2323 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2324 | 2325 | [[package]] 2326 | name = "winapi-util" 2327 | version = "0.1.5" 2328 | source = "registry+https://github.com/rust-lang/crates.io-index" 2329 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 2330 | dependencies = [ 2331 | "winapi", 2332 | ] 2333 | 2334 | [[package]] 2335 | name = "winapi-wsapoll" 2336 | version = "0.1.1" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" 2339 | dependencies = [ 2340 | "winapi", 2341 | ] 2342 | 2343 | [[package]] 2344 | name = "winapi-x86_64-pc-windows-gnu" 2345 | version = "0.4.0" 2346 | source = "registry+https://github.com/rust-lang/crates.io-index" 2347 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2348 | 2349 | [[package]] 2350 | name = "window_clipboard" 2351 | version = "0.2.3" 2352 | source = "registry+https://github.com/rust-lang/crates.io-index" 2353 | checksum = "b47d7fb4df5cd1fea61e5ee3841380f54359bac814e227d8f72709f4f193f8cf" 2354 | dependencies = [ 2355 | "clipboard-win", 2356 | "clipboard_macos", 2357 | "clipboard_wayland", 2358 | "clipboard_x11", 2359 | "raw-window-handle 0.3.4", 2360 | "thiserror", 2361 | ] 2362 | 2363 | [[package]] 2364 | name = "windows-sys" 2365 | version = "0.36.1" 2366 | source = "registry+https://github.com/rust-lang/crates.io-index" 2367 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 2368 | dependencies = [ 2369 | "windows_aarch64_msvc 0.36.1", 2370 | "windows_i686_gnu 0.36.1", 2371 | "windows_i686_msvc 0.36.1", 2372 | "windows_x86_64_gnu 0.36.1", 2373 | "windows_x86_64_msvc 0.36.1", 2374 | ] 2375 | 2376 | [[package]] 2377 | name = "windows-sys" 2378 | version = "0.42.0" 2379 | source = "registry+https://github.com/rust-lang/crates.io-index" 2380 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 2381 | dependencies = [ 2382 | "windows_aarch64_gnullvm", 2383 | "windows_aarch64_msvc 0.42.0", 2384 | "windows_i686_gnu 0.42.0", 2385 | "windows_i686_msvc 0.42.0", 2386 | "windows_x86_64_gnu 0.42.0", 2387 | "windows_x86_64_gnullvm", 2388 | "windows_x86_64_msvc 0.42.0", 2389 | ] 2390 | 2391 | [[package]] 2392 | name = "windows_aarch64_gnullvm" 2393 | version = "0.42.0" 2394 | source = "registry+https://github.com/rust-lang/crates.io-index" 2395 | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" 2396 | 2397 | [[package]] 2398 | name = "windows_aarch64_msvc" 2399 | version = "0.36.1" 2400 | source = "registry+https://github.com/rust-lang/crates.io-index" 2401 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 2402 | 2403 | [[package]] 2404 | name = "windows_aarch64_msvc" 2405 | version = "0.42.0" 2406 | source = "registry+https://github.com/rust-lang/crates.io-index" 2407 | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" 2408 | 2409 | [[package]] 2410 | name = "windows_i686_gnu" 2411 | version = "0.36.1" 2412 | source = "registry+https://github.com/rust-lang/crates.io-index" 2413 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 2414 | 2415 | [[package]] 2416 | name = "windows_i686_gnu" 2417 | version = "0.42.0" 2418 | source = "registry+https://github.com/rust-lang/crates.io-index" 2419 | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" 2420 | 2421 | [[package]] 2422 | name = "windows_i686_msvc" 2423 | version = "0.36.1" 2424 | source = "registry+https://github.com/rust-lang/crates.io-index" 2425 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 2426 | 2427 | [[package]] 2428 | name = "windows_i686_msvc" 2429 | version = "0.42.0" 2430 | source = "registry+https://github.com/rust-lang/crates.io-index" 2431 | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" 2432 | 2433 | [[package]] 2434 | name = "windows_x86_64_gnu" 2435 | version = "0.36.1" 2436 | source = "registry+https://github.com/rust-lang/crates.io-index" 2437 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 2438 | 2439 | [[package]] 2440 | name = "windows_x86_64_gnu" 2441 | version = "0.42.0" 2442 | source = "registry+https://github.com/rust-lang/crates.io-index" 2443 | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" 2444 | 2445 | [[package]] 2446 | name = "windows_x86_64_gnullvm" 2447 | version = "0.42.0" 2448 | source = "registry+https://github.com/rust-lang/crates.io-index" 2449 | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" 2450 | 2451 | [[package]] 2452 | name = "windows_x86_64_msvc" 2453 | version = "0.36.1" 2454 | source = "registry+https://github.com/rust-lang/crates.io-index" 2455 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 2456 | 2457 | [[package]] 2458 | name = "windows_x86_64_msvc" 2459 | version = "0.42.0" 2460 | source = "registry+https://github.com/rust-lang/crates.io-index" 2461 | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" 2462 | 2463 | [[package]] 2464 | name = "winit" 2465 | version = "0.27.5" 2466 | source = "registry+https://github.com/rust-lang/crates.io-index" 2467 | checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" 2468 | dependencies = [ 2469 | "bitflags", 2470 | "cocoa", 2471 | "core-foundation", 2472 | "core-graphics", 2473 | "dispatch", 2474 | "instant", 2475 | "libc", 2476 | "log", 2477 | "mio", 2478 | "ndk", 2479 | "ndk-glue", 2480 | "objc", 2481 | "once_cell", 2482 | "parking_lot 0.12.1", 2483 | "percent-encoding", 2484 | "raw-window-handle 0.4.3", 2485 | "raw-window-handle 0.5.0", 2486 | "sctk-adwaita", 2487 | "smithay-client-toolkit", 2488 | "wasm-bindgen", 2489 | "wayland-client", 2490 | "wayland-protocols", 2491 | "web-sys", 2492 | "windows-sys 0.36.1", 2493 | "x11-dl", 2494 | ] 2495 | 2496 | [[package]] 2497 | name = "wio" 2498 | version = "0.2.2" 2499 | source = "registry+https://github.com/rust-lang/crates.io-index" 2500 | checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" 2501 | dependencies = [ 2502 | "winapi", 2503 | ] 2504 | 2505 | [[package]] 2506 | name = "x11-dl" 2507 | version = "2.20.1" 2508 | source = "registry+https://github.com/rust-lang/crates.io-index" 2509 | checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0" 2510 | dependencies = [ 2511 | "lazy_static", 2512 | "libc", 2513 | "pkg-config", 2514 | ] 2515 | 2516 | [[package]] 2517 | name = "x11rb" 2518 | version = "0.9.0" 2519 | source = "registry+https://github.com/rust-lang/crates.io-index" 2520 | checksum = "6e99be55648b3ae2a52342f9a870c0e138709a3493261ce9b469afe6e4df6d8a" 2521 | dependencies = [ 2522 | "gethostname", 2523 | "nix 0.22.3", 2524 | "winapi", 2525 | "winapi-wsapoll", 2526 | ] 2527 | 2528 | [[package]] 2529 | name = "xcursor" 2530 | version = "0.3.4" 2531 | source = "registry+https://github.com/rust-lang/crates.io-index" 2532 | checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" 2533 | dependencies = [ 2534 | "nom", 2535 | ] 2536 | 2537 | [[package]] 2538 | name = "xi-unicode" 2539 | version = "0.3.0" 2540 | source = "registry+https://github.com/rust-lang/crates.io-index" 2541 | checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" 2542 | 2543 | [[package]] 2544 | name = "xml-rs" 2545 | version = "0.8.4" 2546 | source = "registry+https://github.com/rust-lang/crates.io-index" 2547 | checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" 2548 | -------------------------------------------------------------------------------- /examples/search-bar/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "search_bar" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | fuse-rust = { path = "../.." } 10 | iced = "0.13" 11 | once_cell = "1.20" 12 | -------------------------------------------------------------------------------- /examples/search-bar/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::widget::{column, container, row, scrollable, text, text_input}; 2 | use iced::{application, Alignment, Color, Element, Length}; 3 | use once_cell::sync::Lazy; 4 | 5 | use fuse_rust::{Fuse, SearchResult}; 6 | 7 | use std::ops::Range; 8 | 9 | const BOOKS: &'static [&'static str] = &[ 10 | "Angels & Demons", 11 | "Old Man's War", 12 | "The Lock Artist", 13 | "HTML5", 14 | "Right Ho Jeeves", 15 | "The Code of the Wooster", 16 | "Thank You Jeeves", 17 | "The DaVinci Code", 18 | "The Silmarillion", 19 | "Syrup", 20 | "The Lost Symbol", 21 | "The Book of Lies", 22 | "Lamb", 23 | "Fool", 24 | "Incompetence", 25 | "Fat", 26 | "Colony", 27 | "Backwards, Red Dwarf", 28 | "The Grand Design", 29 | "The Book of Samson", 30 | "The Preservationist", 31 | "Fallen", 32 | "Monster 1959", 33 | ]; 34 | 35 | static INPUT_ID: Lazy = Lazy::new(text_input::Id::unique); 36 | 37 | pub fn main() -> iced::Result { 38 | application("Fuse-Rust search bar demo", Example::update, Example::view).run() 39 | } 40 | 41 | struct Example<'a> { 42 | search_query: String, 43 | book_list: Vec<&'a str>, 44 | visible_books: Option>, 45 | fuse_instance: Fuse, 46 | } 47 | 48 | #[derive(Debug, Clone)] 49 | enum Message { 50 | SearchQuery(String), 51 | } 52 | 53 | impl Default for Example<'_> { 54 | fn default() -> Self { 55 | Self { 56 | search_query: String::default(), 57 | book_list: BOOKS.to_vec(), 58 | visible_books: None, 59 | fuse_instance: Fuse::default(), 60 | } 61 | } 62 | } 63 | 64 | impl Example<'_> { 65 | fn update(&mut self, message: Message) { 66 | match message { 67 | Message::SearchQuery(query) => { 68 | self.search_query = query; 69 | self.visible_books = if !self.search_query.is_empty() { 70 | Some( 71 | self.fuse_instance 72 | .search_text_in_iterable(&self.search_query, self.book_list.iter()), 73 | ) 74 | } else { 75 | None 76 | }; 77 | } 78 | } 79 | } 80 | 81 | fn view(&self) -> Element { 82 | let query_box = text_input("Search query:", &self.search_query) 83 | .id(INPUT_ID.clone()) 84 | .on_input(|input| Message::SearchQuery(input)) 85 | .padding(15) 86 | .size(16); 87 | 88 | let books: Element<_> = column(match &self.visible_books { 89 | Some(books) => books 90 | .iter() 91 | .enumerate() 92 | .map(|(i, res)| view_search_result(self.book_list[res.index], res, i + 1)) 93 | .collect::>(), 94 | None => self 95 | .book_list 96 | .iter() 97 | .enumerate() 98 | .map(|(i, res)| view_book(res, i + 1)) 99 | .collect(), 100 | }) 101 | .spacing(10) 102 | .into(); 103 | 104 | let content = column![ 105 | query_box, 106 | scrollable(container(books).width(Length::Fill).padding(40)), 107 | ] 108 | .spacing(10) 109 | .width(Length::Fill) 110 | .height(Length::Fill) 111 | .align_x(Alignment::Center); 112 | 113 | container(content) 114 | .width(Length::Fill) 115 | .height(Length::Fill) 116 | .padding(40) 117 | .center_x(Length::Fill) 118 | .into() 119 | } 120 | } 121 | 122 | fn view_book<'a>(book_name: &'a str, i: usize) -> Element<'a, Message> { 123 | row!(text(format!("{}. {}", i, book_name)).size(20)).into() 124 | } 125 | 126 | fn view_search_result<'a>( 127 | book_name: &'a str, 128 | search_result: &'a SearchResult, 129 | i: usize, 130 | ) -> Element<'a, Message> { 131 | let mut text_elements: Vec> = vec![]; 132 | text_elements.push(text(format!("{}. ", i,)).size(20).into()); 133 | 134 | let mut i = 0usize; 135 | let mut segments: Vec<(Range, bool)> = vec![]; 136 | 137 | search_result.ranges.iter().for_each(|range| { 138 | if i < range.start { 139 | segments.push((i..range.start, false)); 140 | } 141 | segments.push((range.clone(), true)); 142 | i = range.end; 143 | }); 144 | if i < book_name.len() { 145 | segments.push((i..book_name.len(), false)); 146 | } 147 | 148 | text_elements.extend(segments.iter().map(|(range, is_match)| { 149 | let text_label = text(String::from(&book_name[range.clone()])).size(20); 150 | if *is_match { 151 | text_label.color(Color::from_rgb(1.0, 0.2, 0.2)).into() 152 | } else { 153 | text_label.into() 154 | } 155 | })); 156 | 157 | row(text_elements).into() 158 | } 159 | -------------------------------------------------------------------------------- /examples/simple-search.rs: -------------------------------------------------------------------------------- 1 | use fuse_rust::{Fuse, ScoreResult}; 2 | 3 | fn main() { 4 | let fuse = Fuse::default(); 5 | let text = "Old Man's War"; 6 | let search_text = "od mn war"; 7 | 8 | let result = fuse.search_text_in_string(search_text, text); 9 | assert_eq!( 10 | result, 11 | Some(ScoreResult { 12 | score: 0.4444444444444444, 13 | ranges: vec!((0..1), (2..7), (9..13)), 14 | }), 15 | "Simple search returned incorrect results" 16 | ); 17 | dbg!(result); 18 | } 19 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(missing_docs)] 2 | 3 | //! Fuse-RS 4 | //! 5 | //! A super lightweight fuzzy-search library. 6 | //! A port of [Fuse-Swift](https://github.com/krisk/fuse-swift) written purely in rust! 7 | 8 | #[cfg(test)] 9 | mod tests; 10 | mod utils; 11 | 12 | #[cfg(feature = "async")] 13 | use crossbeam_utils::thread; 14 | 15 | #[cfg(any(feature = "async", feature = "rayon"))] 16 | use std::sync::{Arc, Mutex}; 17 | 18 | /// Required for scoped threads 19 | use std::collections::HashMap; 20 | use std::ops::Range; 21 | 22 | /// Defines the fuseproperty object to be returned as part of the list 23 | /// returned by properties() implemented by the Fuseable trait. 24 | /// # Examples: 25 | /// Basic Usage: 26 | /// ```no_run 27 | /// use fuse_rust::{ Fuse, Fuseable, FuseProperty }; 28 | /// struct Book<'a> { 29 | /// title: &'a str, 30 | /// author: &'a str, 31 | /// } 32 | /// 33 | /// impl Fuseable for Book<'_>{ 34 | /// fn properties(&self) -> Vec { 35 | /// return vec!( 36 | /// FuseProperty{value: String::from("title"), weight: 0.3}, 37 | /// FuseProperty{value: String::from("author"), weight: 0.7}, 38 | /// ) 39 | /// } 40 | /// fn lookup(&self, key: &str) -> Option<&str> { 41 | /// return match key { 42 | /// "title" => Some(self.title), 43 | /// "author" => Some(self.author), 44 | /// _ => None 45 | /// } 46 | /// } 47 | /// } 48 | /// ``` 49 | pub struct FuseProperty { 50 | /// The name of the field with an associated weight in the search. 51 | pub value: String, 52 | /// The weight associated with the specified field. 53 | pub weight: f64, 54 | } 55 | 56 | impl FuseProperty { 57 | /// create a fuse property with weight 1.0 and a string reference. 58 | pub fn init(value: &str) -> Self { 59 | Self { 60 | value: String::from(value), 61 | weight: 1.0, 62 | } 63 | } 64 | /// create a fuse property with a specified weight and string reference. 65 | pub fn init_with_weight(value: &str, weight: f64) -> Self { 66 | Self { 67 | value: String::from(value), 68 | weight, 69 | } 70 | } 71 | } 72 | 73 | /// A datatype to store the pattern's text, its length, a mask 74 | /// and a hashmap against each alphabet in the text. 75 | /// Always use fuse.create_pattern("search string") to create a pattern 76 | /// # Examples: 77 | /// Basic usage: 78 | /// ```no_run 79 | /// use fuse_rust::{ Fuse }; 80 | /// let fuse = Fuse::default(); 81 | /// let pattern = fuse.create_pattern("Hello"); 82 | /// ``` 83 | pub struct Pattern { 84 | text: String, 85 | len: usize, 86 | mask: u64, 87 | alphabet: HashMap, 88 | } 89 | 90 | /// Return type for performing a search on a list of strings 91 | #[derive(Debug, PartialEq)] 92 | pub struct SearchResult { 93 | /// corresponding index of the search result in the original list 94 | pub index: usize, 95 | /// Search rating of the search result, 0.0 is a perfect match 1.0 is a perfect mismatch 96 | pub score: f64, 97 | /// Ranges of matches in the search query, useful if you want to hightlight matches. 98 | pub ranges: Vec>, 99 | } 100 | 101 | /// Return type for performing a search on a single string. 102 | #[derive(Debug, PartialEq)] 103 | pub struct ScoreResult { 104 | /// Search rating of the search result, 0.0 is a perfect match 1.0 is a perfect mismatch 105 | pub score: f64, 106 | /// Ranges of matches in the search query, useful if you want to hightlight matches. 107 | pub ranges: Vec>, 108 | } 109 | 110 | /// Return type for performing a search with a single fuseable property of struct 111 | #[derive(Debug, PartialEq)] 112 | pub struct FResult { 113 | /// The corresponding field name for this search result 114 | pub value: String, 115 | /// Search rating of the search result, 0.0 is a perfect match 1.0 is a perfect mismatch 116 | pub score: f64, 117 | /// Ranges of matches in the search query, useful if you want to hightlight matches. 118 | pub ranges: Vec>, 119 | } 120 | 121 | /// Return type for performing a search over a list of Fuseable structs 122 | #[derive(Debug, PartialEq)] 123 | pub struct FuseableSearchResult { 124 | /// corresponding index of the search result in the original list 125 | pub index: usize, 126 | /// Search rating of the search result, 0.0 is a perfect match 1.0 is a perfect mismatch 127 | pub score: f64, 128 | /// Ranges of matches in the search query, useful if you want to hightlight matches. 129 | pub results: Vec, 130 | } 131 | 132 | /// Creates a new fuse object with given config settings 133 | /// Use to create patterns and access the search methods. 134 | /// Also implements a default method to quickly get a fuse 135 | /// object ready with the default config. 136 | /// # Examples: 137 | /// Basic Usage: 138 | /// ```no_run 139 | /// # use fuse_rust::{ Fuse }; 140 | /// let fuse = Fuse{ 141 | /// location: 0, 142 | /// distance: 100, 143 | /// threshold: 0.6, 144 | /// max_pattern_length: 32, 145 | /// is_case_sensitive: false, 146 | /// tokenize: false, 147 | /// }; 148 | /// ``` 149 | pub struct Fuse { 150 | /// location to starting looking for patterns 151 | pub location: i32, 152 | /// maximum distance to look away from the location 153 | pub distance: i32, 154 | /// threshold for the search algorithm to give up at, 0.0 is perfect match 1.0 is imperfect match 155 | pub threshold: f64, 156 | /// maximum allowed pattern length 157 | pub max_pattern_length: i32, 158 | /// check for lowercase and uppercase seperately 159 | pub is_case_sensitive: bool, 160 | /// tokenize search patterns 161 | pub tokenize: bool, 162 | } 163 | 164 | impl std::default::Default for Fuse { 165 | fn default() -> Self { 166 | Self { 167 | location: 0, 168 | distance: 100, 169 | threshold: 0.6, 170 | max_pattern_length: 32, 171 | is_case_sensitive: false, 172 | tokenize: false, 173 | } 174 | } 175 | } 176 | 177 | impl Fuse { 178 | /// Creates a pattern object from input string. 179 | /// 180 | /// - Parameter string: A string from which to create the pattern object 181 | /// - Returns: A tuple containing pattern metadata 182 | pub fn create_pattern(&self, string: &str) -> Option { 183 | let lowercase = string.to_lowercase(); 184 | let pattern = if self.is_case_sensitive { 185 | string 186 | } else { 187 | &lowercase 188 | }; 189 | let pattern_chars = pattern.as_bytes(); 190 | let len = pattern_chars.len(); 191 | 192 | if len == 0 { 193 | None 194 | } else { 195 | let alphabet = utils::calculate_pattern_alphabet(pattern_chars); 196 | let new_pattern = Pattern { 197 | text: String::from(pattern), 198 | len, 199 | mask: 1 << (len - 1), 200 | alphabet, 201 | }; 202 | Some(new_pattern) 203 | } 204 | } 205 | 206 | #[allow(clippy::single_range_in_vec_init)] 207 | fn search_util(&self, pattern: &Pattern, string: &str) -> ScoreResult { 208 | let string = if self.is_case_sensitive { 209 | String::from(string) 210 | } else { 211 | string.to_ascii_lowercase() 212 | }; 213 | 214 | let string_chars = string.as_bytes(); 215 | let text_length = string.len(); 216 | 217 | // Exact match 218 | if pattern.text == string { 219 | return ScoreResult { 220 | score: 0., 221 | ranges: vec![0..text_length], 222 | }; 223 | } 224 | 225 | let location = self.location; 226 | let distance = self.distance; 227 | let mut threshold = self.threshold; 228 | 229 | let mut best_location = string.find(&pattern.text).unwrap_or(0_usize); 230 | 231 | let mut match_mask_arr = vec![0; text_length]; 232 | 233 | let mut index = string[best_location..].find(&pattern.text); 234 | 235 | let mut score; 236 | 237 | while index.is_some() { 238 | let i = best_location + index.unwrap(); 239 | score = utils::calculate_score(pattern.len, 0, i as i32, location, distance); 240 | 241 | threshold = threshold.min(score); 242 | 243 | best_location = i + pattern.len; 244 | 245 | index = string[best_location..].find(&pattern.text); 246 | 247 | for idx in 0..pattern.len { 248 | match_mask_arr[i + idx] = 1; 249 | } 250 | } 251 | 252 | score = 1.; 253 | let mut bin_max = pattern.len + text_length; 254 | let mut last_bit_arr = vec![]; 255 | 256 | let text_count = string_chars.len(); 257 | 258 | for i in 0..pattern.len { 259 | let mut bin_min = 0; 260 | let mut bin_mid = bin_max; 261 | while bin_min < bin_mid { 262 | if utils::calculate_score( 263 | pattern.len, 264 | i as i32, 265 | location, 266 | location + bin_mid as i32, 267 | distance, 268 | ) <= threshold 269 | { 270 | bin_min = bin_mid; 271 | } else { 272 | bin_max = bin_mid; 273 | } 274 | bin_mid = ((bin_max - bin_min) / 2) + bin_min; 275 | } 276 | bin_max = bin_mid; 277 | 278 | let start = 1.max(location - bin_mid as i32 + 1) as usize; 279 | let finish = text_length.min(location as usize + bin_mid) + pattern.len; 280 | 281 | let mut bit_arr = vec![0; finish + 2]; 282 | 283 | bit_arr[finish + 1] = (1 << i) - 1; 284 | 285 | if start > finish { 286 | continue; 287 | }; 288 | 289 | let mut current_location_index: usize = 0; 290 | for j in (start as u64..=finish as u64).rev() { 291 | let current_location: usize = (j - 1) as usize; 292 | let char_match: u64 = *(if current_location < text_count { 293 | current_location_index = current_location_index 294 | .checked_sub(1) 295 | .unwrap_or(current_location); 296 | pattern 297 | .alphabet 298 | .get(string.as_bytes().get(current_location_index).unwrap()) 299 | } else { 300 | None 301 | }) 302 | .unwrap_or(&0); 303 | 304 | if char_match != 0 { 305 | match_mask_arr[current_location] = 1; 306 | } 307 | 308 | let j2 = j as usize; 309 | bit_arr[j2] = ((bit_arr[j2 + 1] << 1) | 1) & char_match; 310 | if i > 0 { 311 | bit_arr[j2] |= (((last_bit_arr[j2 + 1] | last_bit_arr[j2]) << 1_u64) | 1) 312 | | last_bit_arr[j2 + 1]; 313 | }; 314 | 315 | if (bit_arr[j2] & pattern.mask) != 0 { 316 | score = utils::calculate_score( 317 | pattern.len, 318 | i as i32, 319 | location, 320 | current_location as i32, 321 | distance, 322 | ); 323 | 324 | if score <= threshold { 325 | threshold = score; 326 | best_location = current_location; 327 | 328 | if best_location as i32 <= location { 329 | break; 330 | }; 331 | } 332 | } 333 | } 334 | if utils::calculate_score(pattern.len, i as i32 + 1, location, location, distance) 335 | > threshold 336 | { 337 | break; 338 | } 339 | 340 | last_bit_arr = bit_arr.clone(); 341 | } 342 | 343 | ScoreResult { 344 | score, 345 | ranges: utils::find_ranges(&match_mask_arr).unwrap(), 346 | } 347 | } 348 | 349 | /// Searches for a pattern in a given string. 350 | /// - Parameters: 351 | /// - pattern: The pattern to search for. This is created by calling `createPattern` 352 | /// - string: The string in which to search for the pattern 353 | /// - Returns: Some(ScoreResult) if a match is found containing a `score` between `0.0` (exact match) and `1` (not a match), and `ranges` of the matched characters. If no match is found or if search pattern was empty will return None. 354 | /// # Example: 355 | /// ```no_run 356 | /// use fuse_rust::{ Fuse }; 357 | /// let fuse = Fuse::default(); 358 | /// let pattern = fuse.create_pattern("some text"); 359 | /// fuse.search(pattern.as_ref(), "some string"); 360 | /// ``` 361 | pub fn search(&self, pattern: Option<&Pattern>, string: &str) -> Option { 362 | let pattern = pattern?; 363 | 364 | if self.tokenize { 365 | let word_patterns = pattern 366 | .text 367 | .split_whitespace() 368 | .filter_map(|x| self.create_pattern(x)); 369 | 370 | let full_pattern_result = self.search_util(pattern, string); 371 | 372 | let (length, results) = word_patterns.fold( 373 | (0, full_pattern_result), 374 | |(n, mut total_result), pattern| { 375 | let mut result = self.search_util(&pattern, string); 376 | total_result.score += result.score; 377 | total_result.ranges.append(&mut result.ranges); 378 | (n + 1, total_result) 379 | }, 380 | ); 381 | 382 | let averaged_result = ScoreResult { 383 | score: results.score / (length + 1) as f64, 384 | ranges: results.ranges, 385 | }; 386 | 387 | if (averaged_result.score - 1.0).abs() < 0.00001 { 388 | None 389 | } else { 390 | Some(averaged_result) 391 | } 392 | } else { 393 | let result = self.search_util(pattern, string); 394 | if (result.score - 1.0).abs() < 0.00001 { 395 | None 396 | } else { 397 | Some(result) 398 | } 399 | } 400 | } 401 | } 402 | 403 | /// Implementable trait for user defined structs, requires two methods to me implemented. 404 | /// A properties method that should return a list of FuseProperties. 405 | /// and a lookup method which should return the value of field, provided the field name. 406 | /// # Examples: 407 | /// Usage: 408 | /// ```no_run 409 | /// use fuse_rust::{ Fuse, Fuseable, FuseProperty }; 410 | /// struct Book<'a> { 411 | /// title: &'a str, 412 | /// author: &'a str, 413 | /// } 414 | /// 415 | /// impl Fuseable for Book<'_>{ 416 | /// fn properties(&self) -> Vec { 417 | /// return vec!( 418 | /// FuseProperty{value: String::from("title"), weight: 0.3}, 419 | /// FuseProperty{value: String::from("author"), weight: 0.7}, 420 | /// ) 421 | /// } 422 | /// fn lookup(&self, key: &str) -> Option<&str> { 423 | /// return match key { 424 | /// "title" => Some(self.title), 425 | /// "author" => Some(self.author), 426 | /// _ => None 427 | /// } 428 | /// } 429 | /// } 430 | /// ``` 431 | pub trait Fuseable { 432 | /// Returns a list of FuseProperty that contains the field name and its corresponding weight 433 | fn properties(&self) -> Vec; 434 | /// Provided a field name as argument, returns the value of the field. eg book.loopkup("author") === book.author 435 | fn lookup(&self, key: &str) -> Option<&str>; 436 | } 437 | 438 | impl Fuse { 439 | /// Searches for a text pattern in a given string. 440 | /// - Parameters: 441 | /// - text: the text string to search for. 442 | /// - string: The string in which to search for the pattern 443 | /// - Returns: Some(ScoreResult) if a match is found, containing a `score` between `0.0` (exact match) and `1` (not a match), and `ranges` of the matched characters. Otherwise if a match is not found, returns None. 444 | /// # Examples: 445 | /// ```no_run 446 | /// use fuse_rust::{ Fuse }; 447 | /// let fuse = Fuse::default(); 448 | /// fuse.search_text_in_string("some text", "some string"); 449 | /// ``` 450 | /// **Note**: if the same text needs to be searched across many strings, consider creating the pattern once via `createPattern`, and then use the other `search` function. This will improve performance, as the pattern object would only be created once, and re-used across every search call: 451 | /// ```no_run 452 | /// use fuse_rust::{ Fuse }; 453 | /// let fuse = Fuse::default(); 454 | /// let pattern = fuse.create_pattern("some text"); 455 | /// fuse.search(pattern.as_ref(), "some string"); 456 | /// fuse.search(pattern.as_ref(), "another string"); 457 | /// fuse.search(pattern.as_ref(), "yet another string"); 458 | /// ``` 459 | pub fn search_text_in_string(&self, text: &str, string: &str) -> Option { 460 | self.search(self.create_pattern(text).as_ref(), string) 461 | } 462 | 463 | /// Searches for a text pattern in an iterable containing string references. 464 | /// 465 | /// - Parameters: 466 | /// - text: The pattern string to search for 467 | /// - list: Iterable over string references 468 | /// - Returns: Vec containing Search results corresponding to matches found, with its `index`, its `score`, and the `ranges` of the matched characters. 469 | /// 470 | /// # Example: 471 | /// ```no_run 472 | /// use fuse_rust::{ Fuse }; 473 | /// let fuse = Fuse::default(); 474 | /// let books = [ 475 | /// "The Silmarillion", 476 | /// "The Lock Artist", 477 | /// "The Lost Symbol" 478 | /// ]; 479 | /// 480 | /// let results = fuse.search_text_in_iterable("Te silm", books.iter()); 481 | /// ``` 482 | pub fn search_text_in_iterable(&self, text: &str, list: It) -> Vec 483 | where 484 | It: IntoIterator, 485 | It::Item: AsRef, 486 | { 487 | let pattern = self.create_pattern(text); 488 | let mut items = vec![]; 489 | 490 | for (index, item) in list.into_iter().enumerate() { 491 | if let Some(result) = self.search(pattern.as_ref(), item.as_ref()) { 492 | items.push(SearchResult { 493 | index, 494 | score: result.score, 495 | ranges: result.ranges, 496 | }) 497 | } 498 | } 499 | items.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); 500 | items 501 | } 502 | 503 | /// Searches for a text pattern in an array of `Fuseable` objects. 504 | /// - Parameters: 505 | /// - text: The pattern string to search for 506 | /// - list: A list of `Fuseable` objects, i.e. structs implementing the Fuseable trait in which to search 507 | /// - Returns: A list of `FuseableSearchResult` objects 508 | /// Each `Fuseable` object contains a `properties` method which returns `FuseProperty` array. Each `FuseProperty` is a struct containing a `value` (the name of the field which should be included in the search), and a `weight` (how much "weight" to assign to the score) 509 | /// 510 | /// # Example 511 | /// ```no_run 512 | /// # use fuse_rust::{ Fuse, Fuseable, FuseProperty }; 513 | /// 514 | /// struct Book<'a> { 515 | /// title: &'a str, 516 | /// author: &'a str, 517 | /// } 518 | /// 519 | /// impl Fuseable for Book<'_>{ 520 | /// fn properties(&self) -> Vec { 521 | /// return vec!( 522 | /// FuseProperty{value: String::from("title"), weight: 0.3}, 523 | /// FuseProperty{value: String::from("author"), weight: 0.7}, 524 | /// ) 525 | /// } 526 | /// 527 | /// fn lookup(&self, key: &str) -> Option<&str> { 528 | /// return match key { 529 | /// "title" => Some(self.title), 530 | /// "author" => Some(self.author), 531 | /// _ => None 532 | /// } 533 | /// } 534 | /// } 535 | /// let books = [ 536 | /// Book{author: "John X", title: "Old Man's War fiction"}, 537 | /// Book{author: "P.D. Mans", title: "Right Ho Jeeves"}, 538 | /// ]; 539 | /// 540 | /// let fuse = Fuse::default(); 541 | /// let results = fuse.search_text_in_fuse_list("man", &books); 542 | /// 543 | /// ``` 544 | pub fn search_text_in_fuse_list( 545 | &self, 546 | text: &str, 547 | list: &[impl Fuseable], 548 | ) -> Vec { 549 | let pattern = self.create_pattern(text); 550 | let mut result = vec![]; 551 | for (index, item) in list.iter().enumerate() { 552 | let mut scores = vec![]; 553 | let mut total_score = 0.0; 554 | 555 | let mut property_results = vec![]; 556 | item.properties().iter().for_each(|property| { 557 | let value = item.lookup(&property.value).unwrap_or_else(|| { 558 | panic!( 559 | "Lookup Failed: Lookup doesnt contain requested value => {}.", 560 | &property.value 561 | ); 562 | }); 563 | if let Some(result) = self.search(pattern.as_ref(), value) { 564 | let weight = if (property.weight - 1.0).abs() < 0.00001 { 565 | 1.0 566 | } else { 567 | 1.0 - property.weight 568 | }; 569 | let score = if result.score == 0.0 && (weight - 1.0).abs() < f64::EPSILON { 570 | 0.001 571 | } else { 572 | result.score 573 | } * weight; 574 | total_score += score; 575 | 576 | scores.push(score); 577 | 578 | property_results.push(FResult { 579 | value: String::from(&property.value), 580 | score, 581 | ranges: result.ranges, 582 | }); 583 | } 584 | }); 585 | if scores.is_empty() { 586 | continue; 587 | } 588 | 589 | let count = scores.len() as f64; 590 | result.push(FuseableSearchResult { 591 | index, 592 | score: total_score / count, 593 | results: property_results, 594 | }) 595 | } 596 | 597 | result.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); 598 | result 599 | } 600 | } 601 | 602 | #[cfg(feature = "rayon")] 603 | impl Fuse { 604 | /// Asynchronously searches for a text pattern in a slice of string references. 605 | /// 606 | /// - Parameters: 607 | /// - text: The pattern string to search for 608 | /// - list: &[&str] A reference to a slice of string references. 609 | /// - chunkSize: The size of a single chunk of the array. For example, if the slice has `1000` items, it may be useful to split the work into 10 chunks of 100. This should ideally speed up the search logic. 610 | /// - completion: The handler which is executed upon completion 611 | /// 612 | /// # Example: 613 | /// ```no_run 614 | /// use fuse_rust::{ Fuse, SearchResult }; 615 | /// let fuse = Fuse::default(); 616 | /// let books = [ 617 | /// "The Silmarillion", 618 | /// "The Lock Artist", 619 | /// "The Lost Symbol" 620 | /// ]; 621 | /// 622 | /// fuse.search_text_in_string_list_rayon("Te silm", &books, 100 as usize, &|x: Vec| { 623 | /// dbg!(x); 624 | /// }); 625 | /// ``` 626 | pub fn search_text_in_string_list_rayon( 627 | &self, 628 | text: &str, 629 | list: &[&str], 630 | chunk_size: usize, 631 | completion: &dyn Fn(Vec), 632 | ) { 633 | let pattern = Arc::new(self.create_pattern(text)); 634 | 635 | let item_queue = Arc::new(Mutex::new(Some(vec![]))); 636 | let count = list.len(); 637 | 638 | rayon::scope(|scope| { 639 | (0..=count).step_by(chunk_size).for_each(|offset| { 640 | let chunk = &list[offset..count.min(offset + chunk_size)]; 641 | let queue_ref = Arc::clone(&item_queue); 642 | let pattern_ref = Arc::clone(&pattern); 643 | scope.spawn(move |_| { 644 | let mut chunk_items = vec![]; 645 | 646 | for (index, item) in chunk.iter().enumerate() { 647 | if let Some(result) = self.search((*pattern_ref).as_ref(), item) { 648 | chunk_items.push(SearchResult { 649 | index: offset + index, 650 | score: result.score, 651 | ranges: result.ranges, 652 | }); 653 | } 654 | } 655 | 656 | let mut inner_ref = queue_ref.lock().unwrap(); 657 | if let Some(item_queue) = inner_ref.as_mut() { 658 | item_queue.append(&mut chunk_items); 659 | } 660 | }); 661 | }); 662 | }); 663 | 664 | let mut items = Arc::try_unwrap(item_queue) 665 | .ok() 666 | .unwrap() 667 | .into_inner() 668 | .unwrap() 669 | .unwrap(); 670 | items.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); 671 | completion(items); 672 | } 673 | /// Asynchronously searches for a text pattern in an array of `Fuseable` objects. 674 | /// - Parameters: 675 | /// - text: The pattern string to search for 676 | /// - list: A list of `Fuseable` objects, i.e. structs implementing the Fuseable trait in which to search 677 | /// - chunkSize: The size of a single chunk of the array. For example, if the array has `1000` items, it may be useful to split the work into 10 chunks of 100. This should ideally speed up the search logic. Defaults to `100`. 678 | /// - completion: The handler which is executed upon completion 679 | /// Each `Fuseable` object contains a `properties` method which returns `FuseProperty` array. Each `FuseProperty` is a struct containing a `value` (the name of the field which should be included in the search), and a `weight` (how much "weight" to assign to the score) 680 | /// 681 | /// # Example 682 | /// ```no_run 683 | /// # use fuse_rust::{ Fuse, Fuseable, FuseProperty, FuseableSearchResult }; 684 | /// 685 | /// struct Book<'a> { 686 | /// title: &'a str, 687 | /// author: &'a str, 688 | /// } 689 | /// 690 | /// impl Fuseable for Book<'_>{ 691 | /// fn properties(&self) -> Vec { 692 | /// return vec!( 693 | /// FuseProperty{value: String::from("title"), weight: 0.3}, 694 | /// FuseProperty{value: String::from("author"), weight: 0.7}, 695 | /// ) 696 | /// } 697 | /// 698 | /// fn lookup(&self, key: &str) -> Option<&str> { 699 | /// return match key { 700 | /// "title" => Some(self.title), 701 | /// "author" => Some(self.author), 702 | /// _ => None 703 | /// } 704 | /// } 705 | /// } 706 | /// let books = [ 707 | /// Book{author: "John X", title: "Old Man's War fiction"}, 708 | /// Book{author: "P.D. Mans", title: "Right Ho Jeeves"}, 709 | /// ]; 710 | /// 711 | /// let fuse = Fuse::default(); 712 | /// let results = fuse.search_text_in_fuse_list_with_chunk_size_rayon("man", &books, 1, &|x: Vec| { 713 | /// dbg!(x); 714 | /// }); 715 | /// ``` 716 | pub fn search_text_in_fuse_list_with_chunk_size_rayon( 717 | &self, 718 | text: &str, 719 | list: &[T], 720 | chunk_size: usize, 721 | completion: &dyn Fn(Vec), 722 | ) where 723 | T: Fuseable + std::marker::Sync, 724 | { 725 | let pattern = Arc::new(self.create_pattern(text)); 726 | 727 | let item_queue = Arc::new(Mutex::new(Some(vec![]))); 728 | let count = list.len(); 729 | 730 | rayon::scope(|scope| { 731 | (0..=count).step_by(chunk_size).for_each(|offset| { 732 | let chunk = &list[offset..count.min(offset + chunk_size)]; 733 | let queue_ref = Arc::clone(&item_queue); 734 | let pattern_ref = Arc::clone(&pattern); 735 | scope.spawn(move |_| { 736 | let mut chunk_items = vec![]; 737 | 738 | for (index, item) in chunk.iter().enumerate() { 739 | let mut scores = vec![]; 740 | let mut total_score = 0.0; 741 | 742 | let mut property_results = vec![]; 743 | item.properties().iter().for_each(|property| { 744 | let value = item.lookup(&property.value).unwrap_or_else(|| { 745 | panic!( 746 | "Lookup doesnt contain requested value => {}.", 747 | &property.value 748 | ) 749 | }); 750 | if let Some(result) = self.search((*pattern_ref).as_ref(), value) { 751 | let weight = if (property.weight - 1.0).abs() < 0.00001 { 752 | 1.0 753 | } else { 754 | 1.0 - property.weight 755 | }; 756 | // let score = if result.score == 0.0 && weight == 1.0 { 0.001 } else { result.score } * weight; 757 | let score = result.score * weight; 758 | total_score += score; 759 | 760 | scores.push(score); 761 | 762 | property_results.push(FResult { 763 | value: String::from(&property.value), 764 | score, 765 | ranges: result.ranges, 766 | }); 767 | } 768 | }); 769 | 770 | if scores.is_empty() { 771 | continue; 772 | } 773 | 774 | let count = scores.len() as f64; 775 | chunk_items.push(FuseableSearchResult { 776 | index, 777 | score: total_score / count, 778 | results: property_results, 779 | }) 780 | } 781 | 782 | let mut inner_ref = queue_ref.lock().unwrap(); 783 | if let Some(item_queue) = inner_ref.as_mut() { 784 | item_queue.append(&mut chunk_items); 785 | } 786 | }); 787 | }); 788 | }); 789 | 790 | let mut items = Arc::try_unwrap(item_queue) 791 | .ok() 792 | .unwrap() 793 | .into_inner() 794 | .unwrap() 795 | .unwrap(); 796 | items.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); 797 | completion(items); 798 | } 799 | } 800 | 801 | #[cfg(feature = "async")] 802 | impl Fuse { 803 | /// Asynchronously searches for a text pattern in a slice of string references. 804 | /// 805 | /// - Parameters: 806 | /// - text: The pattern string to search for 807 | /// - list: &[&str] A reference to a slice of string references. 808 | /// - chunkSize: The size of a single chunk of the array. For example, if the slice has `1000` items, it may be useful to split the work into 10 chunks of 100. This should ideally speed up the search logic. 809 | /// - completion: The handler which is executed upon completion 810 | /// 811 | /// # Example: 812 | /// ```no_run 813 | /// use fuse_rust::{ Fuse, SearchResult }; 814 | /// let fuse = Fuse::default(); 815 | /// let books = [ 816 | /// "The Silmarillion", 817 | /// "The Lock Artist", 818 | /// "The Lost Symbol" 819 | /// ]; 820 | /// 821 | /// fuse.search_text_in_string_list("Te silm", &books, 100 as usize, &|x: Vec| { 822 | /// dbg!(x); 823 | /// }); 824 | /// ``` 825 | pub fn search_text_in_string_list( 826 | &self, 827 | text: &str, 828 | list: &[&str], 829 | chunk_size: usize, 830 | completion: &dyn Fn(Vec), 831 | ) { 832 | let pattern = Arc::new(self.create_pattern(text)); 833 | 834 | let item_queue = Arc::new(Mutex::new(Some(vec![]))); 835 | let count = list.len(); 836 | 837 | thread::scope(|scope| { 838 | (0..=count).step_by(chunk_size).for_each(|offset| { 839 | let chunk = &list[offset..count.min(offset + chunk_size)]; 840 | let queue_ref = Arc::clone(&item_queue); 841 | let pattern_ref = Arc::clone(&pattern); 842 | scope.spawn(move |_| { 843 | let mut chunk_items = vec![]; 844 | 845 | for (index, item) in chunk.iter().enumerate() { 846 | if let Some(result) = self.search((*pattern_ref).as_ref(), item) { 847 | chunk_items.push(SearchResult { 848 | index: offset + index, 849 | score: result.score, 850 | ranges: result.ranges, 851 | }); 852 | } 853 | } 854 | 855 | let mut inner_ref = queue_ref.lock().unwrap(); 856 | if let Some(item_queue) = inner_ref.as_mut() { 857 | item_queue.append(&mut chunk_items); 858 | } 859 | }); 860 | }); 861 | }) 862 | .unwrap(); 863 | 864 | let mut items = Arc::try_unwrap(item_queue) 865 | .ok() 866 | .unwrap() 867 | .into_inner() 868 | .unwrap() 869 | .unwrap(); 870 | items.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); 871 | completion(items); 872 | } 873 | /// Asynchronously searches for a text pattern in an array of `Fuseable` objects. 874 | /// - Parameters: 875 | /// - text: The pattern string to search for 876 | /// - list: A list of `Fuseable` objects, i.e. structs implementing the Fuseable trait in which to search 877 | /// - chunkSize: The size of a single chunk of the array. For example, if the array has `1000` items, it may be useful to split the work into 10 chunks of 100. This should ideally speed up the search logic. Defaults to `100`. 878 | /// - completion: The handler which is executed upon completion 879 | /// Each `Fuseable` object contains a `properties` method which returns `FuseProperty` array. Each `FuseProperty` is a struct containing a `value` (the name of the field which should be included in the search), and a `weight` (how much "weight" to assign to the score) 880 | /// 881 | /// # Example 882 | /// ```no_run 883 | /// # use fuse_rust::{ Fuse, Fuseable, FuseProperty, FuseableSearchResult }; 884 | /// 885 | /// struct Book<'a> { 886 | /// title: &'a str, 887 | /// author: &'a str, 888 | /// } 889 | /// 890 | /// impl Fuseable for Book<'_>{ 891 | /// fn properties(&self) -> Vec { 892 | /// return vec!( 893 | /// FuseProperty{value: String::from("title"), weight: 0.3}, 894 | /// FuseProperty{value: String::from("author"), weight: 0.7}, 895 | /// ) 896 | /// } 897 | /// 898 | /// fn lookup(&self, key: &str) -> Option<&str> { 899 | /// return match key { 900 | /// "title" => Some(self.title), 901 | /// "author" => Some(self.author), 902 | /// _ => None 903 | /// } 904 | /// } 905 | /// } 906 | /// let books = [ 907 | /// Book{author: "John X", title: "Old Man's War fiction"}, 908 | /// Book{author: "P.D. Mans", title: "Right Ho Jeeves"}, 909 | /// ]; 910 | /// 911 | /// let fuse = Fuse::default(); 912 | /// let results = fuse.search_text_in_fuse_list_with_chunk_size("man", &books, 1, &|x: Vec| { 913 | /// dbg!(x); 914 | /// }); 915 | /// ``` 916 | pub fn search_text_in_fuse_list_with_chunk_size( 917 | &self, 918 | text: &str, 919 | list: &[T], 920 | chunk_size: usize, 921 | completion: &dyn Fn(Vec), 922 | ) where 923 | T: Fuseable + std::marker::Sync, 924 | { 925 | let pattern = Arc::new(self.create_pattern(text)); 926 | 927 | let item_queue = Arc::new(Mutex::new(Some(vec![]))); 928 | let count = list.len(); 929 | 930 | thread::scope(|scope| { 931 | (0..=count).step_by(chunk_size).for_each(|offset| { 932 | let chunk = &list[offset..count.min(offset + chunk_size)]; 933 | let queue_ref = Arc::clone(&item_queue); 934 | let pattern_ref = Arc::clone(&pattern); 935 | scope.spawn(move |_| { 936 | let mut chunk_items = vec![]; 937 | 938 | for (index, item) in chunk.iter().enumerate() { 939 | let mut scores = vec![]; 940 | let mut total_score = 0.0; 941 | 942 | let mut property_results = vec![]; 943 | item.properties().iter().for_each(|property| { 944 | let value = item.lookup(&property.value).unwrap_or_else(|| { 945 | panic!( 946 | "Lookup doesnt contain requested value => {}.", 947 | &property.value 948 | ) 949 | }); 950 | if let Some(result) = self.search((*pattern_ref).as_ref(), &value) { 951 | let weight = if (property.weight - 1.0).abs() < 0.00001 { 952 | 1.0 953 | } else { 954 | 1.0 - property.weight 955 | }; 956 | // let score = if result.score == 0.0 && weight == 1.0 { 0.001 } else { result.score } * weight; 957 | let score = result.score * weight; 958 | total_score += score; 959 | 960 | scores.push(score); 961 | 962 | property_results.push(FResult { 963 | value: String::from(&property.value), 964 | score, 965 | ranges: result.ranges, 966 | }); 967 | } 968 | }); 969 | 970 | if scores.is_empty() { 971 | continue; 972 | } 973 | 974 | let count = scores.len() as f64; 975 | chunk_items.push(FuseableSearchResult { 976 | index, 977 | score: total_score / count, 978 | results: property_results, 979 | }) 980 | } 981 | 982 | let mut inner_ref = queue_ref.lock().unwrap(); 983 | if let Some(item_queue) = inner_ref.as_mut() { 984 | item_queue.append(&mut chunk_items); 985 | } 986 | }); 987 | }); 988 | }) 989 | .unwrap(); 990 | 991 | let mut items = Arc::try_unwrap(item_queue) 992 | .ok() 993 | .unwrap() 994 | .into_inner() 995 | .unwrap() 996 | .unwrap(); 997 | items.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); 998 | completion(items); 999 | } 1000 | } 1001 | -------------------------------------------------------------------------------- /src/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::Fuse; 2 | 3 | #[test] 4 | fn multibyte_chars() { 5 | let pat = "f"; 6 | let s = &[ 7 | "®∮ℕ⊆ℕ₀⊂ℤℚ", 8 | "😊🥺😉😍😘😚", 9 | "⡍⠜⠇⠑⠹ ⠺⠁⠎", 10 | "გთხოვთ", 11 | "ıntəˈnæʃənəl", 12 | "γνωρίζω ἀπὸ", 13 | "コンニチハ", 14 | ]; 15 | 16 | assert!(Fuse::default() 17 | .search_text_in_iterable(pat, s.iter()) 18 | .is_empty()); 19 | } 20 | 21 | #[test] 22 | fn multibyte_chars_indices() { 23 | let needle = "f"; 24 | let s = "®f∮"; 25 | 26 | let fuse = Fuse::default(); 27 | let pat = fuse.create_pattern(needle); 28 | let x = fuse.search(pat.as_ref(), s).unwrap(); 29 | let r = &x.ranges[0]; 30 | 31 | assert_eq!(&s[r.start..r.end], needle); 32 | } 33 | 34 | #[test] 35 | fn full_match_higher() { 36 | let s = &["Syrup", "Syrup2", "Live", "Live2", "Live3"]; 37 | 38 | let fuse = Fuse::default(); 39 | 40 | let result1 = fuse.search_text_in_iterable("Syrup", s.iter()); 41 | 42 | assert_eq!(result1.len(), 2); 43 | assert_eq!(result1[0].index, 0); 44 | assert_eq!(result1[1].index, 1); 45 | 46 | let result2 = fuse.search_text_in_iterable("live", s.iter()); 47 | 48 | assert_eq!(result2.len(), 3); 49 | assert_eq!(result2[0].index, 2); 50 | assert_eq!(result2[1].score, result2[2].score); 51 | } 52 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::ops::Range; 3 | 4 | pub fn calculate_score(pattern_length: usize, e: i32, x: i32, loc: i32, distance: i32) -> f64 { 5 | let accuracy = (e as f64) / (pattern_length as f64); 6 | let proximity = (x - loc).abs(); 7 | if distance == 0 { 8 | return if proximity != 0 { 1. } else { accuracy }; 9 | } 10 | accuracy + (proximity as f64) / (distance as f64) 11 | } 12 | 13 | /// Initializes the alphabet for the Bitap algorithm 14 | /// - Parameter pattern: The text to encode. 15 | /// - Returns: Hashmap of character locations. 16 | pub fn calculate_pattern_alphabet(pattern: &[u8]) -> HashMap { 17 | let len = pattern.len(); 18 | let mut mask = HashMap::new(); 19 | for (i, &c) in pattern.iter().enumerate() { 20 | mask.insert(c, mask.get(&c).unwrap_or(&0) | (1 << (len - i - 1))); 21 | } 22 | mask 23 | } 24 | 25 | /// Returns an array of `Range`, where each range represents a consecutive list of `1`s. 26 | /// - Parameter mask: A string representing the value to search for. 27 | /// - Returns: `Vec`. 28 | pub fn find_ranges(mask: &[u8]) -> Result>, String> { 29 | if mask.is_empty() { 30 | return Err(String::from("Input array is empty")); 31 | } 32 | let mut ranges = vec![]; 33 | let mut start: i32 = -1; 34 | for (n, bit) in mask.iter().enumerate() { 35 | if start == -1 && *bit >= 1 { 36 | start = n as i32; 37 | } else if start != -1 && *bit == 0 { 38 | ranges.push(start as usize..n); 39 | start = -1; 40 | } 41 | } 42 | 43 | if *mask.last().unwrap() == 1 { 44 | ranges.push(start as usize..mask.len()) 45 | } 46 | Ok(ranges) 47 | } 48 | --------------------------------------------------------------------------------