├── .github ├── FUNDING.yml └── workflows │ ├── codeberg-mirror.yml │ ├── nix.yml │ ├── release-plz.yml │ ├── rust.yml │ └── docker-publish.yml ├── .gitignore ├── Dockerfile ├── Cargo.toml ├── LICENSE ├── Taskfile.yml ├── nix └── home-manager.nix ├── CHANGELOG.md ├── src ├── config.rs ├── main.rs ├── utils.rs └── daemon.rs ├── cliff.toml ├── flake.nix ├── flake.lock ├── README.md └── Cargo.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: arcuru 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target 4 | 5 | # These are backup files generated by rustfmt 6 | **/*.rs.bk 7 | 8 | # Nix build files 9 | /result 10 | 11 | # direnv files 12 | /.direnv 13 | 14 | # task files for tracking already run commands 15 | /.task 16 | 17 | # Local cache files for testing 18 | /.cache 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:bookworm AS builder 2 | WORKDIR /usr/src/pokem 3 | COPY . . 4 | RUN cargo build --release 5 | 6 | FROM debian:bookworm-slim 7 | RUN apt-get update && apt-get install -y openssl libsqlite3-dev ca-certificates && rm -rf /var/lib/apt/lists/* 8 | COPY --from=builder /usr/src/pokem/target/release/pokem /usr/local/bin/pokem 9 | CMD ["pokem", "--daemon", "--config", "/config.yaml"] 10 | -------------------------------------------------------------------------------- /.github/workflows/codeberg-mirror.yml: -------------------------------------------------------------------------------- 1 | name: Codeberg Sync 2 | on: 3 | push: 4 | branches: 5 | - "**" 6 | 7 | jobs: 8 | codeberg: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: 13 | fetch-depth: 0 14 | - uses: yesolutions/mirror-action@master 15 | with: 16 | REMOTE: git@codeberg.org:arcuru/pokem.git 17 | GIT_SSH_PRIVATE_KEY: ${{ secrets.GIT_SSH_PRIVATE_KEY }} 18 | GIT_SSH_NO_VERIFY_HOST: "true" 19 | -------------------------------------------------------------------------------- /.github/workflows/nix.yml: -------------------------------------------------------------------------------- 1 | name: Nix 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | - name: Install Nix 17 | uses: DeterminateSystems/nix-installer-action@main 18 | - name: Nix Cache 19 | uses: DeterminateSystems/magic-nix-cache-action@main 20 | 21 | - name: Check 22 | # Runs all flake checks, which includes building the package 23 | run: nix run github:Mic92/nix-fast-build -- --skip-cached --no-nom 24 | -------------------------------------------------------------------------------- /.github/workflows/release-plz.yml: -------------------------------------------------------------------------------- 1 | name: Release Plz 2 | 3 | permissions: 4 | pull-requests: write 5 | contents: write 6 | 7 | on: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | release-plz: 14 | name: Release-plz 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 21 | - name: Install Rust toolchain 22 | uses: dtolnay/rust-toolchain@stable 23 | - name: Run release-plz 24 | uses: MarcoIeni/release-plz-action@v0.5 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }} 27 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 28 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | # Build/Test/Check everything Rust 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | 21 | - name: Install Rust 22 | uses: dtolnay/rust-toolchain@stable 23 | with: 24 | components: clippy, rustfmt 25 | 26 | - name: Rust Cache 27 | uses: Swatinem/rust-cache@v2 28 | 29 | - name: Build 30 | run: cargo build 31 | 32 | - name: Test 33 | run: cargo test 34 | 35 | - name: Format 36 | run: cargo fmt -- --check 37 | 38 | - name: Clippy 39 | run: cargo clippy -- -D warnings 40 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pokem" 3 | version = "1.1.0" 4 | edition = "2021" 5 | authors = ["Patrick Jackson "] 6 | readme = "README.md" 7 | license = "MIT" 8 | description = "Pok'em, a notification helper bot for Matrix." 9 | repository = "https://github.com/arcuru/pokem" 10 | homepage = "https://github.com/arcuru/pokem" 11 | categories =["command-line-utilities"] 12 | 13 | [[bin]] 14 | name = "pokem" 15 | test = false 16 | 17 | [dependencies] 18 | headjack = "0.4" 19 | anyhow = "1" 20 | is-terminal = "0.4" 21 | urlencoding = "2" 22 | tracing-subscriber = "0.3" 23 | tracing = "0.1" 24 | matrix-sdk = "0.7" 25 | serde = { version = "1", features = ["derive"] } 26 | serde_yaml = "0.9" 27 | clap = { version = "4", features = ["derive"] } 28 | lazy_static = "1" 29 | regex = "1" 30 | dirs = "5" 31 | hyper = { version = "1", features = ["full"] } 32 | tokio = { version = "1", features = ["full"] } 33 | http-body-util = "0.1" 34 | hyper-util = { version = "0.1", features = ["full"] } 35 | reqwest = "0.12" 36 | url = "2.5.2" 37 | emojis = "0.6.3" 38 | serde_json = "1.0.128" 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Patrick Jackson 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. 22 | -------------------------------------------------------------------------------- /Taskfile.yml: -------------------------------------------------------------------------------- 1 | # https://taskfile.dev 2 | 3 | version: "3" 4 | 5 | tasks: 6 | default: 7 | cmd: task --list 8 | silent: true 9 | ci:full: 10 | desc: Run CI locally in containers 11 | cmd: act 12 | ci:local: 13 | desc: Run CI locally 14 | aliases: [ci, check] 15 | deps: [doc, fmt, test, nix:check, nix:build, clippy, pre-commit, build] 16 | nix:check: 17 | desc: Run Nix CI checks 18 | sources: 19 | - ./**/* 20 | cmds: 21 | - nix flake check 22 | nix:build: 23 | desc: Run Nix Build 24 | cmds: 25 | - nix build 26 | clippy: 27 | desc: Run clippy 28 | sources: 29 | - ./**/*.rs 30 | cmd: cargo clippy 31 | pre-commit: 32 | desc: Run pre-commit 33 | cmd: pre-commit run --all-files --show-diff-on-failure 34 | fmt: 35 | desc: Run all formatters 36 | sources: 37 | - ./**/*.rs 38 | - ./**/*.nix 39 | cmds: 40 | - cargo fmt --all 41 | - alejandra . 42 | test: 43 | desc: Run all tests 44 | aliases: [t] 45 | sources: 46 | - ./**/*.rs 47 | cmd: cargo nextest run 48 | doc: 49 | desc: Build the documentation 50 | cmd: cargo doc 51 | audit: 52 | desc: Run cargo security audit 53 | sources: 54 | - Cargo.lock 55 | - flake.lock 56 | cmd: cargo audit 57 | build: 58 | desc: Build the project 59 | aliases: [b] 60 | sources: 61 | - ./**/*.rs 62 | - ./Cargo* 63 | cmd: cargo build 64 | -------------------------------------------------------------------------------- /nix/home-manager.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | with lib; let 8 | cfg = config.services.pokem; 9 | yamlFormat = pkgs.formats.yaml {}; 10 | in { 11 | options.services.pokem = { 12 | enable = mkEnableOption "pokem service"; 13 | package = mkOption { 14 | type = types.package; 15 | default = pkgs.pokem; 16 | example = literalExample "pkgs.pokem"; 17 | description = "Package for the pokem service."; 18 | }; 19 | settings = mkOption { 20 | type = yamlFormat.type; 21 | default = {}; 22 | example = literalExpression '' 23 | { 24 | homeserver_url = "https://matrix.jackson.dev"; 25 | username = "pokem"; 26 | password = "hunter2"; 27 | allow_list = "@me:matrix.org|@myfriend:matrix.org"; 28 | } 29 | ''; 30 | description = '' 31 | Configuration file for pokem. See the pokem documentation for more info. 32 | ''; 33 | }; 34 | }; 35 | config = mkIf cfg.enable { 36 | systemd.user.services.pokem = { 37 | Unit = { 38 | Description = "Pokem Service"; 39 | After = ["network-online.target"]; 40 | }; 41 | 42 | Service = { 43 | Environment = "RUST_LOG=error"; 44 | ExecStart = "${cfg.package}/bin/pokem --daemon --config ${yamlFormat.generate "config.yml" (cfg.settings)}"; 45 | Restart = "always"; 46 | }; 47 | 48 | Install.WantedBy = ["default.target"]; 49 | }; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - "main" 8 | tags: 9 | - "v*" 10 | 11 | jobs: 12 | docker: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up QEMU 19 | uses: docker/setup-qemu-action@v3 20 | 21 | - name: Set up Docker Buildx 22 | uses: docker/setup-buildx-action@v3 23 | 24 | - name: Docker Metadata 25 | id: meta 26 | uses: docker/metadata-action@v5 27 | with: 28 | images: arcuru/pokem 29 | 30 | - name: Login to DockerHub 31 | if: github.event_name != 'pull_request' 32 | uses: docker/login-action@v3 33 | with: 34 | username: ${{ secrets.DOCKER_USERNAME }} 35 | password: ${{ secrets.DOCKER_PASSWORD}} 36 | 37 | # Only build amd64 if it's not a release 38 | - name: Determine Platforms 39 | id: platforms 40 | run: | 41 | if [[ ${{ github.ref }} == refs/tags/v* ]]; then 42 | echo "platforms=linux/amd64,linux/arm64" >> $GITHUB_OUTPUT 43 | else 44 | echo "platforms=linux/amd64" >> $GITHUB_OUTPUT 45 | fi 46 | 47 | - name: Build and Push 48 | uses: docker/build-push-action@v6 49 | with: 50 | context: . 51 | platforms: ${{ steps.platforms.outputs.platforms }} 52 | push: ${{ github.event_name != 'pull_request' }} 53 | tags: ${{ steps.meta.outputs.tags }} 54 | labels: ${{ steps.meta.outputs.labels }} 55 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [1.1.0](https://github.com/arcuru/pokem/compare/v1.0.0...v1.1.0) - 2024-10-25 6 | 7 | ### Added 8 | 9 | - list non-emoji tags at the end of the message 10 | 11 | ### Fixed 12 | 13 | - only need to check lowercase HTTP Headers 14 | 15 | ### Other 16 | 17 | - install release-plz 18 | - Merge pull request [#10](https://github.com/arcuru/pokem/pull/10) from lazytanuki/urgent_rooms 19 | 20 | ## [1.0.0] - 2024-05-06 21 | 22 | ### Bug Fixes 23 | 24 | - Fix the poke command 25 | 26 | ### Documentation 27 | 28 | - Add a link to the public room 29 | - Point to example room 30 | - Fix link to example room 31 | - Update docs with alias and password change 32 | - Registering pokem.dev 33 | 34 | ### Features 35 | 36 | - Allow_list the example room to always send 37 | - Allow using the room alias 38 | - Add a way to block/unblock rooms by Matrix message 39 | - Set passwords on rooms 40 | - Set !pokem as the command prefix for the daemon 41 | - Move room size limit checking into headjack 42 | 43 | ### Miscellaneous Tasks 44 | 45 | - Change version to v0.3.0 46 | - Bump to 1.0.0 47 | - Cargo update 48 | - Nix flake update 49 | 50 | ## [0.2.1] - 2024-04-26 51 | 52 | ### Bug Fixes 53 | 54 | - Fix broken stdin handling 55 | 56 | ### Documentation 57 | 58 | - Adding notes on running it privately 59 | - Fix formatting of the settings 60 | - Update README 61 | - Clarify the default room setup 62 | 63 | ### Features 64 | 65 | - Allow multiple room configs 66 | - Add a WebUI 67 | - Add a poke command to the daemon 68 | - Improve the welcome message 69 | - Accept stdin for the message 70 | 71 | ### Miscellaneous Tasks 72 | 73 | - Release v0.2.0 74 | - Release v0.2.1 75 | 76 | ### Styling 77 | 78 | - Spellchecking 79 | 80 | ## [0.1.1] - 2024-04-19 81 | 82 | ### Bug Fixes 83 | 84 | - Update headjack to a named version 85 | - Add category 86 | - Fixing missing config file 87 | 88 | ### Features 89 | 90 | - Add daemon functionality 91 | 92 | ### Miscellaneous Tasks 93 | 94 | - Release v0.1.0 95 | - Release v0.1.1 96 | 97 | ### Styling 98 | 99 | - Formatting 100 | - Formatting 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use headjack::Bot; 2 | /// Common config options for pok'em 3 | use lazy_static::lazy_static; 4 | 5 | use serde::Deserialize; 6 | 7 | use std::collections::HashMap; 8 | 9 | use std::sync::Mutex; 10 | 11 | #[derive(Debug, Deserialize, Clone)] 12 | pub struct ServerConfig { 13 | /// Server URL 14 | pub url: String, 15 | /// Optional port 16 | pub port: Option, 17 | } 18 | 19 | #[derive(Debug, Deserialize, Clone)] 20 | pub struct DaemonConfig { 21 | /// IP to bind on. 22 | /// Defaults to 0.0.0.0 23 | pub addr: Option, 24 | /// Port to bind on. 25 | /// Will default to 80 26 | pub port: Option, 27 | } 28 | 29 | #[derive(Debug, Deserialize, Clone)] 30 | pub struct MatrixConfig { 31 | /// Homeserver for pokem 32 | pub homeserver_url: String, 33 | /// Username for pokem 34 | pub username: String, 35 | /// Optionally specify the password, if not set it will be asked for on cmd line 36 | pub password: Option, 37 | /// Allow list of which accounts we will respond to 38 | pub allow_list: Option, 39 | /// Room size limit to respond to 40 | pub room_size_limit: Option, 41 | /// Set the state directory for pokem 42 | /// Defaults to $XDG_STATE_HOME/pokem 43 | pub state_dir: Option, 44 | /// Set the command prefix. 45 | /// Defaults to "!pokem". 46 | pub command_prefix: Option, 47 | 48 | /// Default format for messages. 49 | /// Will default to markdown text. 50 | pub format: Option, 51 | } 52 | 53 | #[derive(Debug, Deserialize, Clone, Default)] 54 | pub struct Config { 55 | /// Configuration for logging in and messaging on Matrix 56 | pub matrix: Option, 57 | 58 | /// Server config 59 | /// If this is setup, we will use this instead of logging in ourselves 60 | /// It expects the server config to point to a pokem daemon 61 | pub server: Option, 62 | 63 | /// Daemon config 64 | /// Configuration for running as a daemon 65 | pub daemon: Option, 66 | 67 | /// Save different types of rooms 68 | /// Special value default will be used if no room is specified 69 | /// e.g. error/warning/info/default 70 | pub rooms: Option>, 71 | } 72 | 73 | lazy_static! { 74 | /// Holds the config for the bot 75 | pub static ref GLOBAL_CONFIG: Mutex> = Mutex::new(None); 76 | /// Holds the bot 77 | pub static ref GLOBAL_BOT: Mutex> = Mutex::new(None); 78 | } 79 | 80 | /// Config settings in a single room 81 | #[derive(Clone, Debug, Default)] 82 | pub struct RoomConfig { 83 | pub block: bool, 84 | pub auth: Option, 85 | } 86 | -------------------------------------------------------------------------------- /cliff.toml: -------------------------------------------------------------------------------- 1 | # git-cliff ~ default configuration file 2 | # https://git-cliff.org/docs/configuration 3 | # 4 | # Lines starting with "#" are comments. 5 | # Configuration options are organized into tables and keys. 6 | # See documentation for more information on available options. 7 | 8 | [changelog] 9 | # changelog header 10 | header = """ 11 | # Changelog\n 12 | All notable changes to this project will be documented in this file.\n 13 | """ 14 | # template for the changelog body 15 | # https://keats.github.io/tera/docs/#introduction 16 | body = """ 17 | {% if version %}\ 18 | ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} 19 | {% else %}\ 20 | ## [unreleased] 21 | {% endif %}\ 22 | {% for group, commits in commits | group_by(attribute="group") %} 23 | ### {{ group | upper_first }} 24 | {% for commit in commits %} 25 | - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\ 26 | {% endfor %} 27 | {% endfor %}\n 28 | """ 29 | # remove the leading and trailing whitespace from the template 30 | trim = true 31 | # changelog footer 32 | footer = """ 33 | 34 | """ 35 | # postprocessors 36 | postprocessors = [ 37 | # { pattern = '', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL 38 | ] 39 | [git] 40 | # parse the commits based on https://www.conventionalcommits.org 41 | conventional_commits = true 42 | # filter out the commits that are not conventional 43 | filter_unconventional = true 44 | # process each line of a commit as an individual commit 45 | split_commits = false 46 | # regex for preprocessing the commit messages 47 | commit_preprocessors = [ 48 | # { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, # replace issue numbers 49 | ] 50 | # regex for parsing and grouping commits 51 | commit_parsers = [ 52 | { message = "^feat", group = "Features" }, 53 | { message = "^fix", group = "Bug Fixes" }, 54 | { message = "^doc", group = "Documentation" }, 55 | { message = "^perf", group = "Performance" }, 56 | { message = "^refactor", group = "Refactor" }, 57 | { message = "^style", group = "Styling" }, 58 | { message = "^test", group = "Testing" }, 59 | { message = "^chore\\(release\\): prepare for", skip = true }, 60 | { message = "^chore\\(deps\\)", skip = true }, 61 | { message = "^chore\\(pr\\)", skip = true }, 62 | { message = "^chore\\(pull\\)", skip = true }, 63 | { message = "^chore|ci", group = "Miscellaneous Tasks" }, 64 | { body = ".*security", group = "Security" }, 65 | { message = "^revert", group = "Revert" }, 66 | ] 67 | # protect breaking changes from being skipped due to matching a skipping commit_parser 68 | protect_breaking_commits = false 69 | # filter out the commits that are not matched by commit parsers 70 | filter_commits = false 71 | # regex for matching git tags 72 | tag_pattern = "v[0-9].*" 73 | 74 | # regex for skipping tags 75 | skip_tags = "v0.1.0-beta.1" 76 | # regex for ignoring tags 77 | ignore_tags = "" 78 | # sort the tags topologically 79 | topo_order = false 80 | # sort the commits inside sections by oldest/newest order 81 | sort_commits = "oldest" 82 | # limit the number of commits included in the changelog. 83 | # limit_commits = 42 84 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "pokem - Jack some (AI) heads into Matrix."; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 6 | pre-commit-hooks = { 7 | url = "github:cachix/pre-commit-hooks.nix"; 8 | inputs = { 9 | nixpkgs.follows = "nixpkgs"; 10 | nixpkgs-stable.follows = "nixpkgs"; 11 | }; 12 | }; 13 | 14 | crane.url = "github:ipetkov/crane"; 15 | 16 | flake-utils.url = "github:numtide/flake-utils"; 17 | 18 | fenix = { 19 | # Needed because rust-overlay, normally used by crane, doesn't have llvm-tools for coverage 20 | url = "github:nix-community/fenix"; 21 | inputs.nixpkgs.follows = "nixpkgs"; 22 | inputs.rust-analyzer-src.follows = ""; 23 | }; 24 | 25 | advisory-db = { 26 | # Rust dependency security advisories 27 | url = "github:rustsec/advisory-db"; 28 | flake = false; 29 | }; 30 | 31 | # A faster nix flake check command 32 | nix-fast-build = { 33 | url = "github:Mic92/nix-fast-build"; 34 | inputs.nixpkgs.follows = "nixpkgs"; 35 | }; 36 | }; 37 | 38 | outputs = {self, ...} @ inputs: 39 | inputs.flake-utils.lib.eachDefaultSystem (system: let 40 | pkgs = import inputs.nixpkgs { 41 | inherit system; 42 | }; 43 | 44 | inherit (pkgs) lib; 45 | 46 | # Use the stable rust tools from fenix 47 | fenixStable = inputs.fenix.packages.${system}.stable; 48 | rustSrc = fenixStable.rust-src; 49 | toolChain = fenixStable.completeToolchain; 50 | 51 | # Use the toolchain with the crane helper functions 52 | craneLib = (inputs.crane.mkLib pkgs).overrideToolchain toolChain; 53 | 54 | # Clean the src to only have the Rust-relevant files 55 | # src = let 56 | # # We need to keep the yaml files because they are used for the build defaults 57 | # yamlFilter = path: _type: builtins.match ".*defaults.yaml$" path != null; 58 | # yamlOrCargo = path: type: 59 | # (yamlFilter path type) || (craneLib.filterCargoSources path type); 60 | # in 61 | # lib.cleanSourceWith { 62 | # src = craneLib.path ./.; 63 | # filter = yamlOrCargo; 64 | # }; 65 | src = ./.; 66 | 67 | # Common arguments for mkCargoDerivation, a helper for the crane functions 68 | # Arguments can be included here even if they aren't used, but we only 69 | # place them here if they would otherwise show up in multiple places 70 | commonArgs = { 71 | inherit src cargoArtifacts; 72 | nativeBuildInputs = with pkgs; [ 73 | pkg-config 74 | ]; 75 | buildInputs = with pkgs; [ 76 | openssl 77 | sqlite 78 | ]; 79 | }; 80 | 81 | # Build only the cargo dependencies so we can cache them all when running in CI 82 | cargoArtifacts = craneLib.buildDepsOnly commonArgs; 83 | 84 | # Build the actual crate itself, reusing the cargoArtifacts 85 | pokem = craneLib.buildPackage commonArgs; 86 | in { 87 | checks = 88 | { 89 | # Build the final package as part of `nix flake check` for convenience 90 | inherit (self.packages.${system}) pokem; 91 | 92 | # Run clippy (and deny all warnings) on the crate source 93 | pokem-clippy = 94 | craneLib.cargoClippy 95 | (commonArgs 96 | // { 97 | cargoClippyExtraArgs = "--all-targets -- --deny warnings"; 98 | }); 99 | 100 | # Check docs build successfully 101 | pokem-doc = craneLib.cargoDoc commonArgs; 102 | 103 | # Check formatting 104 | pokem-fmt = craneLib.cargoFmt commonArgs; 105 | 106 | # Run tests with cargo-nextest 107 | # Note: This provides limited value, as tests are already run in the build 108 | pokem-nextest = craneLib.cargoNextest commonArgs; 109 | 110 | # Audit dependencies 111 | crate-audit = craneLib.cargoAudit (commonArgs 112 | // { 113 | inherit (inputs) advisory-db; 114 | }); 115 | } 116 | // lib.optionalAttrs (system == "x86_64-linux") { 117 | # Check code coverage with tarpaulin runs 118 | pokem-tarpaulin = craneLib.cargoTarpaulin commonArgs; 119 | } 120 | // { 121 | # Run formatting checks before commit 122 | # Can be run manually with `pre-commit run -a` 123 | pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run { 124 | src = ./.; 125 | tools.rustfmt = toolChain; 126 | hooks = { 127 | alejandra.enable = true; # Nix formatting 128 | prettier.enable = true; # Markdown formatting 129 | rustfmt.enable = true; # Rust formatting 130 | }; 131 | }; 132 | }; 133 | 134 | packages = rec { 135 | inherit pokem; 136 | default = pokem; 137 | }; 138 | 139 | apps = rec { 140 | default = pokem; 141 | pokem = inputs.flake-utils.lib.mkApp { 142 | drv = self.packages.${system}.pokem; 143 | }; 144 | }; 145 | 146 | devShells.default = pkgs.mkShell { 147 | name = "pokem"; 148 | shellHook = '' 149 | ${self.checks.${system}.pre-commit-check.shellHook} 150 | echo --------------------- 151 | task --list 152 | echo --------------------- 153 | ''; 154 | 155 | # Include the packages from the defined checks and packages 156 | inputsFrom = 157 | (builtins.attrValues self.checks.${system}) 158 | ++ (builtins.attrValues self.packages.${system}); 159 | 160 | nativeBuildInputs = with pkgs; [ 161 | act # For running Github Actions locally 162 | alejandra 163 | deadnix 164 | git-cliff 165 | go-task 166 | gum # Pretty printing in scripts 167 | nodePackages.prettier 168 | statix 169 | 170 | # Code coverage 171 | cargo-tarpaulin 172 | 173 | # Speed up nix builds 174 | inputs.nix-fast-build.packages.${system}.nix-fast-build 175 | ]; 176 | 177 | # Many tools read this to find the sources for rust stdlib 178 | RUST_SRC_PATH = "${rustSrc}/lib/rustlib/src/rust/library"; 179 | }; 180 | }) 181 | // { 182 | overlays.default = final: prev: { 183 | pokem = self.packages.${final.system}.pokem; 184 | }; 185 | homeManagerModules.default = import ./nix/home-manager.nix; 186 | }; 187 | } 188 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "advisory-db": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1726496182, 7 | "narHash": "sha256-V5193OeAuy0smfeOF2omeJXk+kq+tlEzcpk2MrUpai0=", 8 | "owner": "rustsec", 9 | "repo": "advisory-db", 10 | "rev": "3cae2352cf82b5815b98aa309e0f4df6aa737cec", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "rustsec", 15 | "repo": "advisory-db", 16 | "type": "github" 17 | } 18 | }, 19 | "crane": { 20 | "locked": { 21 | "lastModified": 1725409566, 22 | "narHash": "sha256-PrtLmqhM6UtJP7v7IGyzjBFhbG4eOAHT6LPYOFmYfbk=", 23 | "owner": "ipetkov", 24 | "repo": "crane", 25 | "rev": "7e4586bad4e3f8f97a9271def747cf58c4b68f3c", 26 | "type": "github" 27 | }, 28 | "original": { 29 | "owner": "ipetkov", 30 | "repo": "crane", 31 | "type": "github" 32 | } 33 | }, 34 | "fenix": { 35 | "inputs": { 36 | "nixpkgs": ["nixpkgs"], 37 | "rust-analyzer-src": [] 38 | }, 39 | "locked": { 40 | "lastModified": 1726468443, 41 | "narHash": "sha256-O1VcbVBrqIf58U05yFXl9+J7XM2qh0I+7vqMbNwZPq0=", 42 | "owner": "nix-community", 43 | "repo": "fenix", 44 | "rev": "effac20e9560aab202e82b6d833f685163a9c138", 45 | "type": "github" 46 | }, 47 | "original": { 48 | "owner": "nix-community", 49 | "repo": "fenix", 50 | "type": "github" 51 | } 52 | }, 53 | "flake-compat": { 54 | "flake": false, 55 | "locked": { 56 | "lastModified": 1696426674, 57 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 58 | "owner": "edolstra", 59 | "repo": "flake-compat", 60 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 61 | "type": "github" 62 | }, 63 | "original": { 64 | "owner": "edolstra", 65 | "repo": "flake-compat", 66 | "type": "github" 67 | } 68 | }, 69 | "flake-parts": { 70 | "inputs": { 71 | "nixpkgs-lib": "nixpkgs-lib" 72 | }, 73 | "locked": { 74 | "lastModified": 1714641030, 75 | "narHash": "sha256-yzcRNDoyVP7+SCNX0wmuDju1NUCt8Dz9+lyUXEI0dbI=", 76 | "owner": "hercules-ci", 77 | "repo": "flake-parts", 78 | "rev": "e5d10a24b66c3ea8f150e47dfdb0416ab7c3390e", 79 | "type": "github" 80 | }, 81 | "original": { 82 | "owner": "hercules-ci", 83 | "repo": "flake-parts", 84 | "type": "github" 85 | } 86 | }, 87 | "flake-utils": { 88 | "inputs": { 89 | "systems": "systems" 90 | }, 91 | "locked": { 92 | "lastModified": 1710146030, 93 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 94 | "owner": "numtide", 95 | "repo": "flake-utils", 96 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 97 | "type": "github" 98 | }, 99 | "original": { 100 | "owner": "numtide", 101 | "repo": "flake-utils", 102 | "type": "github" 103 | } 104 | }, 105 | "gitignore": { 106 | "inputs": { 107 | "nixpkgs": ["pre-commit-hooks", "nixpkgs"] 108 | }, 109 | "locked": { 110 | "lastModified": 1709087332, 111 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", 112 | "owner": "hercules-ci", 113 | "repo": "gitignore.nix", 114 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 115 | "type": "github" 116 | }, 117 | "original": { 118 | "owner": "hercules-ci", 119 | "repo": "gitignore.nix", 120 | "type": "github" 121 | } 122 | }, 123 | "nix-fast-build": { 124 | "inputs": { 125 | "flake-parts": "flake-parts", 126 | "nixpkgs": ["nixpkgs"], 127 | "treefmt-nix": "treefmt-nix" 128 | }, 129 | "locked": { 130 | "lastModified": 1719475157, 131 | "narHash": "sha256-8zW6eWvE9T03cMpo/hY8RRZIsSCfs1zmsJOkEZzuYwM=", 132 | "owner": "Mic92", 133 | "repo": "nix-fast-build", 134 | "rev": "030e586195c97424844965d2ce680140f6565c02", 135 | "type": "github" 136 | }, 137 | "original": { 138 | "owner": "Mic92", 139 | "repo": "nix-fast-build", 140 | "type": "github" 141 | } 142 | }, 143 | "nixpkgs": { 144 | "locked": { 145 | "lastModified": 1726243404, 146 | "narHash": "sha256-sjiGsMh+1cWXb53Tecsm4skyFNag33GPbVgCdfj3n9I=", 147 | "owner": "nixos", 148 | "repo": "nixpkgs", 149 | "rev": "345c263f2f53a3710abe117f28a5cb86d0ba4059", 150 | "type": "github" 151 | }, 152 | "original": { 153 | "owner": "nixos", 154 | "ref": "nixos-unstable", 155 | "repo": "nixpkgs", 156 | "type": "github" 157 | } 158 | }, 159 | "nixpkgs-lib": { 160 | "locked": { 161 | "lastModified": 1714640452, 162 | "narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=", 163 | "type": "tarball", 164 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 165 | }, 166 | "original": { 167 | "type": "tarball", 168 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 169 | } 170 | }, 171 | "pre-commit-hooks": { 172 | "inputs": { 173 | "flake-compat": "flake-compat", 174 | "gitignore": "gitignore", 175 | "nixpkgs": ["nixpkgs"], 176 | "nixpkgs-stable": ["nixpkgs"] 177 | }, 178 | "locked": { 179 | "lastModified": 1725513492, 180 | "narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=", 181 | "owner": "cachix", 182 | "repo": "pre-commit-hooks.nix", 183 | "rev": "7570de7b9b504cfe92025dd1be797bf546f66528", 184 | "type": "github" 185 | }, 186 | "original": { 187 | "owner": "cachix", 188 | "repo": "pre-commit-hooks.nix", 189 | "type": "github" 190 | } 191 | }, 192 | "root": { 193 | "inputs": { 194 | "advisory-db": "advisory-db", 195 | "crane": "crane", 196 | "fenix": "fenix", 197 | "flake-utils": "flake-utils", 198 | "nix-fast-build": "nix-fast-build", 199 | "nixpkgs": "nixpkgs", 200 | "pre-commit-hooks": "pre-commit-hooks" 201 | } 202 | }, 203 | "systems": { 204 | "locked": { 205 | "lastModified": 1681028828, 206 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 207 | "owner": "nix-systems", 208 | "repo": "default", 209 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 210 | "type": "github" 211 | }, 212 | "original": { 213 | "owner": "nix-systems", 214 | "repo": "default", 215 | "type": "github" 216 | } 217 | }, 218 | "treefmt-nix": { 219 | "inputs": { 220 | "nixpkgs": ["nix-fast-build", "nixpkgs"] 221 | }, 222 | "locked": { 223 | "lastModified": 1714058656, 224 | "narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=", 225 | "owner": "numtide", 226 | "repo": "treefmt-nix", 227 | "rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f", 228 | "type": "github" 229 | }, 230 | "original": { 231 | "owner": "numtide", 232 | "repo": "treefmt-nix", 233 | "type": "github" 234 | } 235 | } 236 | }, 237 | "root": "root", 238 | "version": 7 239 | } 240 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use reqwest::header::HeaderMap; 3 | 4 | mod config; 5 | mod daemon; 6 | mod utils; 7 | 8 | use crate::config::*; 9 | use crate::daemon::daemon; 10 | use crate::utils::*; 11 | 12 | use is_terminal::IsTerminal; 13 | use std::{fs::File, io::Read, path::PathBuf}; 14 | use tracing::{error, info}; 15 | 16 | #[derive(Parser)] 17 | #[command(author, version, about, long_about = None)] 18 | struct PokemArgs { 19 | /// Path to config file 20 | #[arg(short, long)] 21 | config: Option, 22 | 23 | /// Room ID to send the message to 24 | #[arg(short, long)] 25 | room: Option, 26 | 27 | /// Run in daemon mode 28 | #[arg(short, long)] 29 | daemon: bool, 30 | 31 | /// Authentication token 32 | #[arg(long, visible_alias = "auth")] 33 | authentication: Option, 34 | 35 | /// Formatting for the message. "markdown" or "plain". 36 | #[arg(long)] 37 | format: Option, 38 | 39 | /// Message to send 40 | #[arg()] 41 | message: Option>, 42 | } 43 | 44 | /// Get the config from the file or load the default config 45 | fn get_config_or_default(path: &Option) -> Config { 46 | let mut file = { 47 | if let Some(config) = path { 48 | match File::open(config) { 49 | Ok(file) => file, 50 | Err(_) => { 51 | return Config::default(); 52 | } 53 | } 54 | } else { 55 | let mut config = dirs::config_dir().unwrap(); 56 | config.push("pokem"); 57 | config.push("config.yaml"); 58 | match File::open(config) { 59 | Ok(file) => file, 60 | Err(_) => { 61 | return Config::default(); 62 | } 63 | } 64 | } 65 | }; 66 | let mut contents = String::new(); 67 | file.read_to_string(&mut contents).unwrap(); 68 | 69 | serde_yaml::from_str(&contents).unwrap() 70 | } 71 | 72 | #[tokio::main] 73 | async fn main() -> anyhow::Result<()> { 74 | tracing_subscriber::fmt::init(); 75 | 76 | // Read in the config file 77 | let args = PokemArgs::parse(); 78 | let config: Config = get_config_or_default(&args.config); 79 | *GLOBAL_CONFIG.lock().unwrap() = Some(config.clone()); 80 | 81 | if args.daemon { 82 | // Daemon mode ignores all the other arguments 83 | info!("Running in daemon mode"); 84 | return daemon(config.daemon, config.rooms).await; 85 | } 86 | 87 | let headers = { 88 | let mut headers = HeaderMap::new(); 89 | if let Some(auth) = args.authentication.clone() { 90 | headers.insert("Authentication", auth.parse().unwrap()); 91 | } 92 | if let Some(format) = args.format.clone() { 93 | headers.insert("Format", format.parse().unwrap()); 94 | } 95 | headers 96 | }; 97 | 98 | let mut messages = args.message.clone().unwrap_or_default(); 99 | let room = { 100 | let rooms = config.rooms.unwrap_or_default(); 101 | match args.room.clone() { 102 | Some(room) => { 103 | // If the room is a room name in the config, we'll transform it to the room id 104 | if let Some(room_id) = rooms.get(&room) { 105 | room_id.clone() 106 | } else { 107 | room 108 | } 109 | } 110 | None => { 111 | // Create a regex to see if the first argument looks like a room name 112 | let re = regex::Regex::new(r"^.*:.*\..*").unwrap(); 113 | if messages.is_empty() { 114 | // Check if there is a default room configured 115 | // That room will be pinged with no message 116 | if let Some(room_id) = rooms.get("default") { 117 | room_id.clone() 118 | } else { 119 | return Err(anyhow::anyhow!("No room specified")); 120 | } 121 | } else if re.is_match(&messages[0]) { 122 | // Use the first arg if it's a raw room id 123 | // TODO: This has surprising behavior if this isn't an intended room, we'd want to fall back to the configured default room 124 | // I suppose we could fallback in this CLI? e.g. if the command fails to identify a room, then try the default room 125 | messages.remove(0) 126 | } else if let Some(room_id) = rooms.get(&messages[0]) { 127 | // Check for a room name in the config 128 | messages.remove(0); 129 | room_id.clone() 130 | } else if let Some(room_id) = rooms.get("default") { 131 | // Check if a default room exists 132 | room_id.clone() 133 | } else { 134 | return Err(anyhow::anyhow!("No room specified")); 135 | } 136 | } 137 | } 138 | }; 139 | error!("Room: {:?}, Message: {:?}", room, messages); 140 | 141 | // Append any stdin content to the message 142 | let mut input = String::new(); 143 | if !std::io::stdin().is_terminal() { 144 | std::io::stdin().read_to_string(&mut input).unwrap(); 145 | if !input.is_empty() { 146 | messages.push(input.trim().to_string()); 147 | } 148 | } 149 | 150 | if config.server.is_none() && config.matrix.is_none() { 151 | // The user has set neither server nor matrix config 152 | // Assume they want to use the public instance 153 | info!("Sending request to pokem.dev"); 154 | let server = ServerConfig { 155 | url: "https://pokem.dev".to_string(), 156 | port: None, 157 | }; 158 | match poke_server(&server, &room, &headers, &messages.join(" ")).await { 159 | Ok(_) => { 160 | info!("Successfully sent message"); 161 | return Ok(()); 162 | } 163 | Err(e) => { 164 | error!("Failed to send message: {:?}", e); 165 | } 166 | } 167 | } 168 | 169 | if let Some(server) = config.server { 170 | info!("Sending request to server"); 171 | match poke_server(&server, &room, &headers, &messages.join(" ")).await { 172 | Ok(_) => { 173 | info!("Successfully sent message"); 174 | return Ok(()); 175 | } 176 | Err(e) => { 177 | error!("Failed to send message: {:?}", e); 178 | } 179 | } 180 | } 181 | 182 | if let Some(matrix) = config.matrix { 183 | info!("Running as a Matrix client"); 184 | // Login to matrix 185 | let bot = connect(matrix).await?; 186 | GLOBAL_BOT.lock().unwrap().replace(bot.clone()); 187 | // Ping the room 188 | return ping_room(&bot, &room, &headers, &messages.join(" "), false).await; 189 | } 190 | 191 | return Err(anyhow::anyhow!("Unable to send message")); 192 | } 193 | 194 | /// Send a message to the server. 195 | async fn poke_server( 196 | server: &ServerConfig, 197 | room: &str, 198 | headers: &reqwest::header::HeaderMap, 199 | message: &str, 200 | ) -> anyhow::Result<()> { 201 | // URI encode the room 202 | let room = urlencoding::encode(room).to_string(); 203 | 204 | let url = { 205 | if server.port.is_none() { 206 | format!("{}/{}", server.url, room) 207 | } else { 208 | format!("{}:{}/{}", server.url, server.port.unwrap(), room) 209 | } 210 | }; 211 | // if url doesn't start with "http://" or "https://", add "http://" to the beginning 212 | let url = if url.starts_with("http://") || url.starts_with("https://") { 213 | url 214 | } else { 215 | // https by default, don't encourage unencrypted traffic 216 | format!("https://{}", url) 217 | }; 218 | 219 | let client = reqwest::Client::new(); 220 | let res = client 221 | .post(&url) 222 | .body(message.to_owned()) 223 | .headers(headers.clone()) 224 | .send() 225 | .await?; 226 | 227 | if res.status().is_success() { 228 | let body = res.text().await?; 229 | error!("Response: {:?}", body); 230 | Ok(()) 231 | } else { 232 | error!("Failed to send message: {:?}", res.status()); 233 | Err(anyhow::anyhow!("Failed to send message")) 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pok'em 2 | 3 | Send a Matrix message using the CLI or an HTTP PUT/POST request. 4 | It's intended to support easy scripting to send yourself or a team notifications over Matrix. 5 | 6 | This runs a Matrix bot account that pings you on Matrix when it's called. 7 | It can be run standalone, or it can run as a daemon and listen for HTTP requests. 8 | 9 | That's it. 10 | 11 | If you want to use my default instance at [pokem.dev](https://pokem.dev), you don't need to install anything. 12 | 13 | It is built using [headjack](https://github.com/arcuru/headjack), a Matrix bot framework in Rust. 14 | 15 | If this seems familiar, that's because it's a clone of the core feature of [ntfy.sh](https://ntfy.sh), but only using Matrix. 16 | I'd encourage you to check out that project to see if it better suits your needs. 17 | 18 | ## Repository 19 | 20 | **Mirrored on [GitHub](https://github.com/arcuru/pokem) and [Codeberg](https://codeberg.org/arcuru/pokem). GitHub is the official repo, but use either repo to contribute. Issues can't be synced so there may be some duplicates.** 21 | 22 | ## Getting Help 23 | 24 | There is a public Matrix room available at [#pokem:jackson.dev](https://matrix.to/#/#pokem:jackson.dev) 25 | 26 | ## Usage 27 | 28 | ### Using the public server 29 | 30 | I run an endpoint and associated bot account accessible at [pokem.dev](https://pokem.dev), with the bot running on my homeserver on [jackson.dev](https://jackson.dev). 31 | `pokem.dev` is usually running the git main branch, instead of the latest release. 32 | `pokem` will default to that instance if you have not configured the server settings. 33 | 34 | You can run your own instance (using `pokem --daemon`), but here I'll describe using pokem.dev 35 | 36 | 1. On Matrix, create a room and invite the bot account, [@pokem:jackson.dev](https://matrix.to/#/@pokem:jackson.dev). 37 | 2. Grab the Matrix Room Alias or ID from the welcome message or from your client. 38 | 3. Run `curl --fail -d "Backup successful 😀" pokem.dev/`. Or use `pokem `. 39 | 4. The `curl` or `pokem` commands will block until the message is sent, and will return an error if there is a problem. 40 | 41 | `pokem`, like `ntfy`, listens to HTTP PUT/POST requests, so it's easy to send a message. 42 | If you'd like more examples of how to send messages, just look at the [ntfy docs](https://docs.ntfy.sh/#step-2-send-a-message) and use the Matrix Room ID instead of the ntfy "topic". 43 | 44 | If you use the `pokem` CLI, you can set a default room in the config file, and then you don't need to specify it in commands. 45 | `pokem Backup Successful 😀` will be all you need. 46 | 47 | The daemon also provides a webpage that will send messages for you, e.g. [pokem.dev](https://pokem.dev). 48 | For ease of use, you can use URLs with the Room ID so that you can generate easy links. 49 | 50 | Try it out! Send a message to https://pokem.dev/pokem-example:jackson.dev and you can see it in [#pokem-example:jackson.dev](https://matrix.to/#/#pokem-example:jackson.dev). 51 | 52 | You can also use the unique room id: https://pokem.dev/!JYrjsPjErpFSDdpwpI:jackson.dev, or a URI-encoded room-alias (with the Matrix standard '#') https://pokem.dev/%23pokem-example:jackson.dev. 53 | '#' is a special URL character, you need to URI Encode it (as "%23") or just remove it from your request, as we will support "pokem-example:jackson.dev" as a room name. 54 | 55 | #### Limitations of [@pokem:jackson.dev](https://matrix.to/#/@pokem:jackson.dev) 56 | 57 | 1. You should not rely on it to have more than 1 9 of reliability. 58 | 2. There may be usage limits in the future. 59 | 60 | ### CLI Usage 61 | 62 | The `pokem` tool comes with several convenience features to help with sending messages. 63 | 64 | You can configure a default room, and setup shorthand room names, to make things easier to use. 65 | 66 | Here are some example calls: 67 | 68 | ```bash 69 | # These three commands are all equivalent 70 | pokem !RoomID:jackson.dev Backup failed! 71 | pokem --room !RoomID:jackson.dev Backup failed! 72 | curl --fail -d "Backup failed!" pokem.dev/!RoomID:jackson.dev 73 | 74 | pokem Backup failed! # Will send to your configured default room 75 | pokem error Backup failed! # Will send to your configured room named "error" 76 | pokem --room error Backup failed! # Same as above 77 | 78 | # It also accepts stdin as the room message 79 | echo "Backup failed!" | pokem error # Sends to the room named "error" 80 | cat README.md | pokem # Send the contents of a file to the default room 81 | ``` 82 | 83 | See the [Setup](#setup) section for config options. 84 | 85 | ### Running A Private Bot Account 86 | 87 | If you don't want to use [@pokem:jackson.dev](https://matrix.to/#/@pokem:jackson.dev), there are 2 ways to still use Pok'em. 88 | 89 | You can either: 90 | 91 | 1. Host your own bot using `pokem --daemon`, and access just as described above. 92 | 2. Use the Pok'em CLI with the Bot login configured. The app will login to the Matrix bot account and send the ping locally. 93 | 94 | Running Pok'em as a daemon has several advantages, but it is perfectly usable to just use local login. 95 | 96 | 1. The daemon will be much more responsive, since it takes a while to login and sync up on Matrix. 97 | 2. It will also be continuously available to respond to Room Invites and help request messages. 98 | 3. You can skip installing `pokem` locally, which is especially useful to be pinged from a CI job. 99 | 100 | #### Docker Setup 101 | 102 | The Pok'em daemon is available as a Docker image on [Docker Hub](https://hub.docker.com/r/arcuru/pokem). 103 | Here's a Docker Compose example: 104 | 105 | ```yaml 106 | services: 107 | pokem: 108 | image: arcuru/pokem:main # Set to your desired version 109 | volumes: 110 | # Mount your config file to /config.yaml 111 | - ./config.yaml:/config.yaml 112 | # Recommended: Persist the logged in session 113 | # You will need to set the state directory to this location in the config file 114 | # e.g. 115 | # matrix: 116 | # state_dir: /state 117 | - pokem-state:/state 118 | network_mode: host 119 | logging: 120 | driver: "json-file" 121 | options: 122 | max-size: "1m" 123 | max-file: "1" 124 | 125 | volumes: 126 | # Persists the logged in session 127 | pokem-state: 128 | ``` 129 | 130 | ## Install 131 | 132 | `pokem` is only packaged on crates.io, so installing it needs to be done via `cargo install pokem` or from git. 133 | 134 | For [Nix](https://nixos.org/) users, this repo contains a Nix flake. See the [setup section](#nix) for details on configuring. 135 | 136 | ## Setup 137 | 138 | Using your own bot account will require setup, otherwise there is no setup required. 139 | 140 | `pokem` the CLI tool runs down this list until it finds something to do: 141 | 142 | 1. `pokem --daemon` runs it as a daemon, listening for HTTP messages. 143 | 2. If there is no server or matrix login configured, it will send the request to the `pokem.dev` instance. 144 | 3. `pokem` with a server configured will send a PUT request to the server. 145 | 4. If there is a Matrix login configured, the CLI will attempt to login to Matrix itself. 146 | 147 | Here is the config file skeleton. 148 | It can be placed in $XDG_CONFIG_HOME/pokem/config.yaml or passed via `pokem --config ~/path/to/config.yaml`. 149 | 150 | ```yaml 151 | # Optional, for creating room shorthands 152 | # These can be used in place of the raw room IDs 153 | # e.g. `pokem error The backup failed!` will send "The backup failed!" to the room named "error" 154 | rooms: 155 | # Default is a special value, and will be used if no room is specified 156 | # e.g. `pokem The backup failed!` will send to the default room 157 | default: "!RoomID:jackson.dev" 158 | error: "!ErrorRoom:jackson.dev" 159 | discord: "!RoomBridgedToDiscord:jackson.dev" 160 | fullteam: "!RoomWithFullTeam:jackson.dev" 161 | # Messages that come with the "urgent" tag sent to "fullteam" will go to "fullteam-urgent", if 162 | # it exists, otherwise they will be sent to "fullteam" with a "@room" ping 163 | fullteam-urgent: "!RoomWithFullTeamUrgent:jackson.dev" 164 | 165 | # Optional, define the server to send messages to 166 | # If configured, `pokem` will first try to query this server to send the message 167 | # Will use pokem.dev by default 168 | server: 169 | url: https://pokem.dev 170 | # Optional, customize the port if necessary 171 | port: 80 172 | 173 | # Optional, if you want to login to your own Matrix account 174 | # You will need to create the bot account manually 175 | matrix: 176 | homeserver_url: https://matrix.jackson.dev 177 | username: "pokem" 178 | # Optional, will ask on first run 179 | #password: "" 180 | # Optional, but necessary for use 181 | #allow_list: ".*" 182 | # Optional, the max size of the room to join 183 | #room_size_limit: 5 184 | # Optional, customize the state directory for the Matrix login data 185 | # Defaults to $XDG_STATE_HOME/pokem 186 | #state_dir: 187 | # Optional, customize the default format used for messages 188 | # Defaults to markdown, but can also be set to plain 189 | #format: markdown 190 | 191 | # Optional, to define the bindings when running as a service 192 | daemon: 193 | addr: "0.0.0.0" 194 | port: 80 195 | ``` 196 | 197 | ## Authentication 198 | 199 | You can configure an Authentication token from the Matrix side, so that poking a Matrix room would require knowing the token. 200 | 201 | Sending `!pokem set auth pokempassword` to the Matrix bot will set the token to "pokempassword". 202 | 203 | Once the token is set, the room will not be pinged unless the token is given in the HTTP headers, for example: 204 | 205 | ```bash 206 | curl --fail pokem.dev/roomid -d "poke the room" -H "Authentication: pokempassword" 207 | pokem --auth pokempassword --room roomid poke the room 208 | ``` 209 | 210 | If the token matches the message will be sent to the room, otherwise the request will fail. 211 | 212 | The token can be seen by anyone in the room by sending `!pokem info`, and it can be removed with `!pokem set auth off`. 213 | 214 | ## Alternative Ideas 215 | 216 | Here are some non-standard things you could do with this: 217 | 218 | ### Alert Everywhere 219 | 220 | 1. Run the bot account on a homeserver with bridges configured. 221 | 2. Have the bot account login to anywhere else with a bridge (Discord, Slack, IRC, iMessage, etc). 222 | 3. Use this to ping the Discord/Slack/IRC room using the bridge. 223 | 224 | ### Script Your Own Messages 225 | 226 | 1. Give `pokem` _your_ login info. 227 | 2. Send any message to a room of your choice as yourself. e.g. `pokem I'm running late` 228 | 229 | ## Comparison with ntfy.sh 230 | 231 | ### Cons 232 | 233 | 1. Way fewer features. `pokem` only does text pings on Matrix. 234 | 2. Fewer integrations. `pokem` is limited to only Matrix and things bridged to Matrix. 235 | 236 | ### Pros 237 | 238 | 1. Secure room topics by default. Nobody else can subscribe to the messages even with the key. 239 | 2. You don't need a separate app, just use your existing Matrix client. 240 | 3. Support for authentication tokens, so that nobody else can send messages to your room. 241 | 242 | ## Nix 243 | 244 | Development is being done using a [Nix flake](https://nixos.wiki/wiki/Flakes). 245 | The easiest way to install pokem is to use nix flakes. 246 | 247 | ```bash 248 | ❯ nix run github:arcuru/pokem 249 | ``` 250 | 251 | The flake contains an [overlay](https://nixos.wiki/wiki/Overlays) to make it easier to import into your own flake config. 252 | To use, add it to your inputs: 253 | 254 | ```nix 255 | inputs.pokem.url = "github:arcuru/pokem"; 256 | ``` 257 | 258 | And then add the overlay `inputs.pokem.overlays.default` to your pkgs. 259 | 260 | The flake also contains a home-manager module for installing the daemon as a service. 261 | Import the module into your home-manager config and you can configure `pokem` all from within nix: 262 | 263 | ```nix 264 | {inputs, ... }: { 265 | imports = [ inputs.pokem.homeManagerModules.default ]; 266 | services.pokem = { 267 | enable = true; 268 | settings = { 269 | homeserver_url = "https://matrix.jackson.dev"; 270 | username = "pokem"; 271 | password = "hunter2"; 272 | allow_list = "@me:matrix.org|@myfriend:matrix.org"; 273 | }; 274 | }; 275 | } 276 | ``` 277 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | /// Common utils for pok'em 2 | use crate::config::*; 3 | use headjack::*; 4 | 5 | use matrix_sdk::ruma::events::room::message::RoomMessageEventContent; 6 | 7 | use matrix_sdk::ruma::events::tag::TagInfo; 8 | use matrix_sdk::ruma::events::Mentions; 9 | use matrix_sdk::{Room, RoomMemberships, RoomState}; 10 | 11 | use tracing::{error, info}; 12 | 13 | use hyper::HeaderMap; 14 | 15 | /// Write the Room config into the tags 16 | pub async fn set_room_config(room: &Room, config: RoomConfig) { 17 | if config.block { 18 | room.set_tag("dev.pokem.block".into(), TagInfo::default()) 19 | .await 20 | .unwrap(); 21 | } else { 22 | room.remove_tag("dev.pokem.block".into()).await.unwrap(); 23 | } 24 | // Grab the auth token from the option for ergonomics 25 | let auth_token = config.auth.clone().unwrap_or("".to_string()); 26 | // Remove any existing auth token 27 | let mut placed = false; 28 | let tags = room.tags().await.unwrap_or_default(); 29 | for (tag, _) in tags.unwrap_or_default() { 30 | if tag.to_string().starts_with("dev.pokem.pass.") { 31 | // Old format, remove it, we'll be replacing with the new value 32 | room.remove_tag(tag).await.unwrap(); 33 | } else if tag.to_string().starts_with("dev.pokem.auth.") { 34 | if config.auth.is_some() 35 | && tag.to_string().trim_start_matches("dev.pokem.auth.") == auth_token 36 | { 37 | // Already in place 38 | placed = true; 39 | } else { 40 | // If this tag doesn't match the new one, remove it 41 | room.remove_tag(tag).await.unwrap(); 42 | } 43 | }; 44 | } 45 | if config.auth.is_some() && !placed { 46 | room.set_tag( 47 | format!("dev.pokem.auth.{}", auth_token).into(), 48 | TagInfo::default(), 49 | ) 50 | .await 51 | .unwrap(); 52 | } 53 | } 54 | 55 | // Get all the current set room configs from the tags. 56 | pub async fn get_room_config(room: &Room) -> RoomConfig { 57 | let mut config = RoomConfig::default(); 58 | let tags = room.tags().await.unwrap_or_default(); 59 | let mut should_update = false; 60 | for (tag, _) in tags.unwrap_or_default() { 61 | if tag.to_string() == "dev.pokem.block" { 62 | config.block = true; 63 | } else if tag.to_string().starts_with("dev.pokem.auth.") { 64 | if config.auth.is_some() { 65 | // We only want one auth token, this is a warning 66 | // It probably means we failed to remove a token on a change 67 | error!( 68 | "Multiple Auth Tokens set for room: {}", 69 | room.room_id().as_str() 70 | ); 71 | continue; 72 | } 73 | // Get the auth token 74 | config.auth = Some( 75 | tag.to_string() 76 | .trim_start_matches("dev.pokem.auth.") 77 | .to_string(), 78 | ); 79 | } else if tag.to_string().starts_with("dev.pokem.pass.") { 80 | // TODO(2.0): Remove this in 2.0 81 | // Old format, support for now 82 | // It will be removed immediately and replaced 83 | should_update = true; 84 | if config.auth.is_some() { 85 | // We only want one password, this is a warning 86 | // It probably means we failed to remove a password on a password change 87 | error!( 88 | "Multiple Auth Tokens set for room: {}", 89 | room.room_id().as_str() 90 | ); 91 | continue; 92 | } 93 | // Get the auth token 94 | config.auth = Some( 95 | tag.to_string() 96 | .trim_start_matches("dev.pokem.pass.") 97 | .to_string(), 98 | ); 99 | } 100 | } 101 | // Update the settings if there are old formatted auth tokens 102 | if should_update { 103 | set_room_config(room, config.clone()).await; 104 | } 105 | config 106 | } 107 | 108 | /// Get command prefix 109 | pub fn get_command_prefix() -> String { 110 | GLOBAL_BOT 111 | .lock() 112 | .unwrap() 113 | .as_ref() 114 | .unwrap() 115 | .command_prefix() 116 | } 117 | 118 | /// Check if we can message the room 119 | pub async fn can_message_room(room: &Room) -> bool { 120 | // Always send to the example room 121 | if room.room_id().as_str() == "!JYrjsPjErpFSDdpwpI:jackson.dev" { 122 | error!("Sending to example room"); 123 | return true; 124 | } 125 | 126 | // Check if we're blocked from sending messages 127 | if room 128 | .tags() 129 | .await 130 | .unwrap_or_default() 131 | .is_some_and(|x| x.contains_key(&"dev.pokem.block".into())) 132 | { 133 | error!( 134 | "Blocked from sending messages to {}", 135 | room.room_id().as_str() 136 | ); 137 | return false; 138 | } 139 | true 140 | } 141 | 142 | /// Send the help message with the room id 143 | pub async fn send_help(room: &Room) { 144 | if can_message_room(room).await { 145 | if let Some(alias) = room.canonical_alias() { 146 | room.send(RoomMessageEventContent::text_plain(format!( 147 | "This Room's Alias is: {}", 148 | alias.as_str() 149 | ))) 150 | .await 151 | .expect("Failed to send message"); 152 | } 153 | room.send(RoomMessageEventContent::text_plain(format!( 154 | "This Room's ID is: {}", 155 | room.room_id().as_str() 156 | ))) 157 | .await 158 | .expect("Failed to send message"); 159 | let config = get_room_config(room).await; 160 | if let Some(pass) = config.auth { 161 | room.send(RoomMessageEventContent::text_plain(format!( 162 | "This Room's Authentication token is: {}", 163 | pass 164 | ))) 165 | .await 166 | .expect("Failed to send message"); 167 | } 168 | } 169 | } 170 | 171 | /// Send a message to a room. 172 | pub async fn ping_room( 173 | bot: &Bot, 174 | room_id: &str, 175 | headers: &HeaderMap, 176 | message: &str, 177 | mention_room: bool, 178 | ) -> anyhow::Result<()> { 179 | let r = get_room_from_name(bot, room_id).await; 180 | if r.is_none() { 181 | error!("Failed to find room with name: {}", room_id); 182 | return Err(anyhow::anyhow!( 183 | "Failed to find room with name: {}", 184 | room_id 185 | )); 186 | } 187 | let r = r.unwrap(); 188 | 189 | // If we're in an invited state, we need to wait for the invite to be accepted 190 | let mut delay = 2; 191 | while r.state() == RoomState::Invited { 192 | if delay > 60 { 193 | return Err(anyhow::anyhow!("Failed to join room")); 194 | } 195 | tokio::time::sleep(std::time::Duration::from_secs(delay)).await; 196 | delay *= 2; 197 | } 198 | 199 | let mut msg: String = message.to_string(); 200 | 201 | let room_config = get_room_config(&r).await; 202 | 203 | // Validate the authentication token and remove it from the message 204 | if let Ok(cleaned_msg) = validate_authentication(room_config, headers, &msg) { 205 | msg = cleaned_msg; 206 | } else { 207 | return Err(anyhow::anyhow!("Incorrect Authentication Token")); 208 | } 209 | 210 | // Get the message formatting 211 | let mut msg = format_message(headers, &msg); 212 | if mention_room { 213 | msg = msg.add_mentions(Mentions::with_room_mention()); 214 | } 215 | 216 | if can_message_room(&r).await { 217 | if let Err(e) = r.send(msg).await { 218 | return Err(anyhow::anyhow!("Failed to send message: {}", e)); 219 | } 220 | } else { 221 | error!("Failed to send message"); 222 | } 223 | Ok(()) 224 | } 225 | 226 | /// Get the appropriate message formatting. 227 | fn format_message(headers: &HeaderMap, msg: &str) -> RoomMessageEventContent { 228 | // Get the default format from the config 229 | let mut format = if let Some(default_format) = GLOBAL_CONFIG 230 | .lock() 231 | .unwrap() 232 | .as_ref() 233 | .unwrap() 234 | .matrix 235 | .as_ref() 236 | .unwrap() 237 | .format 238 | .clone() 239 | { 240 | default_format 241 | } else { 242 | "markdown".to_string() 243 | }; 244 | if let Some(header_format) = headers.get("format") { 245 | format = header_format.to_str().unwrap_or_default().to_string(); 246 | }; 247 | match format.to_lowercase().as_str() { 248 | "markdown" => RoomMessageEventContent::text_markdown(msg), 249 | "plain" => RoomMessageEventContent::text_plain(msg), 250 | _ => { 251 | error!("Unknown format: {}", format); 252 | RoomMessageEventContent::text_markdown(msg) 253 | } 254 | } 255 | } 256 | 257 | /// Translate a provided room name into an actual Room struct. 258 | /// This looks up by either the Room Internal ID or the Room Alias. 259 | /// Any alias, main or alt, will be checked. 260 | pub async fn get_room_from_name(bot: &Bot, name: &str) -> Option { 261 | if name.is_empty() { 262 | return None; 263 | } 264 | 265 | // Is this a room internal id? 266 | if let Ok(id) = matrix_sdk::ruma::RoomId::parse(name) { 267 | return bot.client().get_room(&id); 268 | } 269 | 270 | // Is this a user address? 271 | let re = regex::Regex::new(r"^@.*:.*\..*").unwrap(); 272 | if re.is_match(name) { 273 | // This looks like a user name 274 | // unsupported at this time 275 | return None; 276 | } 277 | 278 | // #@patrick:jackson.dev is a valid _room_ name 279 | // We will be careful to not allow that, and ignore all room names that look like user names 280 | 281 | // If name does not start with a '#', add it 282 | // This is to get around oddities with specifying the '#' in the URL 283 | // It's annoying to reference it, so we support the room name without the '#' 284 | let name = if name.starts_with('#') { 285 | name.to_string() 286 | } else { 287 | format!("#{}", name) 288 | }; 289 | 290 | // Is this a room address? 291 | let re = regex::Regex::new(r"^#.*:.*\..*").unwrap(); 292 | if re.is_match(&name) { 293 | // We're just going to scan every room we're in to look for this room name 294 | // Effective? Sure. 295 | // Efficient? Absolutely not. 296 | let rooms = bot.client().joined_rooms(); 297 | for r in &rooms { 298 | let room_alias = r.canonical_alias(); 299 | if let Some(alias) = room_alias { 300 | if alias.as_str() == name { 301 | return Some(r.clone()); 302 | } 303 | } 304 | // Check the alt aliases 305 | for alias in r.alt_aliases() { 306 | if alias.as_str() == name { 307 | return Some(r.clone()); 308 | } 309 | } 310 | } 311 | return None; 312 | } 313 | error!("Failed to find room: {}", name); 314 | None 315 | } 316 | 317 | /// Validate the authentication token 318 | /// 319 | /// Returns the message with the authentication token removed 320 | pub fn validate_authentication( 321 | room_config: RoomConfig, 322 | headers: &HeaderMap, 323 | msg: &str, 324 | ) -> anyhow::Result { 325 | if room_config.auth.is_some() { 326 | // Check if the authentication token is in the headers 327 | let token = { 328 | // Allow both "authentication" and "auth" 329 | if let Some(auth) = headers.get("authentication") { 330 | auth.to_str().unwrap_or_default() 331 | } else if let Some(auth) = headers.get("auth") { 332 | auth.to_str().unwrap_or_default() 333 | } else { 334 | "" 335 | } 336 | }; 337 | if token == room_config.auth.clone().unwrap() { 338 | return Ok(msg.to_string()); 339 | } 340 | 341 | // Allow the authentication token to be the first word in the message 342 | 343 | // Check if the message starts with the password 344 | if !msg.starts_with(&room_config.auth.clone().unwrap()) { 345 | return Err(anyhow::anyhow!("Incorrect Authentication Token")); 346 | } 347 | // Remove the password and any leading whitespace 348 | Ok(msg 349 | .trim_start_matches(&room_config.auth.unwrap()) 350 | .trim_start() 351 | .to_string()) 352 | } else { 353 | Ok(msg.to_string()) 354 | } 355 | } 356 | 357 | /// Check a room to see if we should leave it. 358 | /// It applies if we're the only ones left in the room. 359 | #[allow(dead_code)] 360 | async fn should_leave_room(room: &Room) -> bool { 361 | // Check if we are joined to the room, and there is only 1 member 362 | // This means we are the only member 363 | if let Ok(members) = room.members(RoomMemberships::ACTIVE).await { 364 | // We'd be the only member 365 | if members.len() == 1 { 366 | error!("Found empty room"); 367 | true 368 | } else { 369 | false 370 | } 371 | } else { 372 | false 373 | } 374 | } 375 | 376 | /// Login as a bot 377 | pub async fn connect(config: MatrixConfig) -> anyhow::Result { 378 | // The config file is read, now we can start up 379 | let mut bot = Bot::new(BotConfig { 380 | login: Login { 381 | homeserver_url: config.homeserver_url, 382 | username: config.username.clone(), 383 | password: config.password, 384 | }, 385 | name: Some(config.username.clone()), 386 | allow_list: config.allow_list, 387 | state_dir: config.state_dir, 388 | command_prefix: if config.command_prefix.is_none() { 389 | Some("!pokem".to_string()) 390 | } else { 391 | config.command_prefix 392 | }, 393 | room_size_limit: config.room_size_limit, 394 | }) 395 | .await; 396 | 397 | if let Err(e) = bot.login().await { 398 | error!("Error logging in: {e}"); 399 | } 400 | 401 | // React to invites. 402 | bot.join_rooms_callback(Some(|room: matrix_sdk::Room| async move { 403 | error!("Joined room: {}", room.room_id().as_str()); 404 | if can_message_room(&room).await { 405 | room.send(RoomMessageEventContent::text_markdown( 406 | "Welcome to Pok'em!\n\nSend `!pokem help` to see available commands.", 407 | )) 408 | .await 409 | .expect("Failed to send message"); 410 | } 411 | send_help(&room).await; 412 | Ok(()) 413 | })); 414 | 415 | // Syncs to the current state 416 | if let Err(e) = bot.sync().await { 417 | error!("Error syncing: {e}"); 418 | } 419 | 420 | info!("The client is ready! Listening to new messages…"); 421 | 422 | Ok(bot) 423 | } 424 | -------------------------------------------------------------------------------- /src/daemon.rs: -------------------------------------------------------------------------------- 1 | /// Run Pok'em as a daemon 2 | use crate::config::*; 3 | use crate::utils::*; 4 | 5 | use anyhow::Context; 6 | use clap::error::Result; 7 | use matrix_sdk::ruma::events::room::message::RoomMessageEventContent; 8 | 9 | use matrix_sdk::ruma::events::tag::TagInfo; 10 | use matrix_sdk::Room; 11 | 12 | use serde::Deserialize; 13 | use tokio::sync::RwLock; 14 | use tracing::{debug, error}; 15 | 16 | use std::collections::HashMap; 17 | use std::net::{IpAddr, SocketAddr}; 18 | use std::sync::Arc; 19 | 20 | use http_body_util::BodyExt; 21 | use http_body_util::Full; 22 | use hyper::body::Bytes; 23 | 24 | use hyper::server::conn::http1; 25 | use hyper::service::service_fn; 26 | use hyper::StatusCode; 27 | use hyper::{Request, Response}; 28 | use hyper_util::rt::TokioIo; 29 | use tokio::net::TcpListener; 30 | 31 | #[derive(Debug, Clone, Deserialize)] 32 | struct PokeRequest { 33 | topic: String, 34 | title: Option, 35 | message: String, 36 | priority: Option, 37 | tags: Option>, 38 | } 39 | 40 | impl PokeRequest { 41 | /// Try to deserialize the request from JSON, otherwise build it from headers and body. 42 | pub async fn from_request(request: Request) -> anyhow::Result { 43 | // Try JSON deserialization 44 | let headers = request.headers().clone(); 45 | let uri = request.uri().clone(); 46 | 47 | let body_bytes = request.collect().await?.to_bytes(); 48 | let body_str = 49 | String::from_utf8(body_bytes.to_vec()).with_context(|| "error while decoding UTF-8")?; 50 | let Ok(poke_request) = serde_json::from_str::(&body_str) else { 51 | // Build from headers and body 52 | let query_params: HashMap = uri 53 | .query() 54 | .map(|v| { 55 | url::form_urlencoded::parse(v.as_bytes()) 56 | .map(|(a, b)| (a.to_lowercase(), b.to_string())) 57 | .collect() 58 | }) 59 | .unwrap_or_default(); 60 | return Ok(PokeRequest { 61 | // The uri without the leading / will be the room id 62 | topic: uri.path().trim_start_matches('/').to_string(), 63 | title: query_params.get("title").cloned().or_else(|| { 64 | headers 65 | .get("x-title") 66 | .or_else(|| headers.get("title")) 67 | .or_else(|| headers.get("ti")) 68 | .or_else(|| headers.get("t")) 69 | .and_then(|tags| tags.to_str().ok().map(String::from)) 70 | }), 71 | message: query_params 72 | .get("message") 73 | .cloned() 74 | .or_else(|| { 75 | headers 76 | .get("x-message") 77 | .or_else(|| headers.get("message")) 78 | .or_else(|| headers.get("m")) 79 | .and_then(|msg| msg.to_str().ok().map(String::from)) 80 | }) 81 | .unwrap_or(body_str), 82 | priority: query_params 83 | .get("priority") 84 | .and_then(|p| p.parse().ok()) 85 | .or_else(|| { 86 | headers 87 | .get("x-priority") 88 | .or_else(|| headers.get("priority")) 89 | .or_else(|| headers.get("prio")) 90 | .or_else(|| headers.get("p")) 91 | .and_then(|priority_header| { 92 | priority_header.to_str().ok().map(|header_str| { 93 | header_str.parse().unwrap_or_else(|_| { 94 | match &header_str.to_lowercase()[..] { 95 | "min" => 1, 96 | "low" => 2, 97 | "default" => 3, 98 | "high" => 4, 99 | "urgent" | "max" => 5, 100 | _ => 3, 101 | } 102 | }) 103 | }) 104 | }) 105 | }), 106 | tags: query_params 107 | .get("tags") 108 | .cloned() 109 | .or_else(|| { 110 | headers 111 | .get("x-tags") 112 | .or_else(|| headers.get("tags")) 113 | .or_else(|| headers.get("tag")) 114 | .or_else(|| headers.get("ta")) 115 | .and_then(|tags| tags.to_str().ok().map(String::from)) 116 | }) 117 | .map(|tags_str| tags_str.split(',').map(String::from).collect()), 118 | }); 119 | }; 120 | Ok(poke_request) 121 | } 122 | } 123 | 124 | /// Run in daemon mode 125 | /// This binds to a port and listens for incoming requests, and sends them to the Matrix room 126 | pub async fn daemon( 127 | config: Option, 128 | rooms: Option>, 129 | ) -> anyhow::Result<()> { 130 | let addr = { 131 | if let Some(daemon) = &config { 132 | let ip_addr: IpAddr = daemon 133 | .addr 134 | .clone() 135 | .unwrap_or("0.0.0.0".to_string()) 136 | .parse() 137 | .expect("Invalid IP address"); 138 | SocketAddr::from((ip_addr, daemon.port.unwrap_or(80))) 139 | } else { 140 | SocketAddr::from(([0, 0, 0, 0], 80)) 141 | } 142 | }; 143 | 144 | // We create a TcpListener and bind it to 127.0.0.1:3000 145 | let listener = TcpListener::bind(addr).await?; 146 | 147 | // Login to the bot and store it 148 | let matrix_config = GLOBAL_CONFIG 149 | .lock() 150 | .unwrap() 151 | .as_ref() 152 | .unwrap() 153 | .matrix 154 | .clone() 155 | .unwrap(); 156 | let bot = connect(matrix_config).await?; 157 | GLOBAL_BOT.lock().unwrap().replace(bot.clone()); 158 | 159 | // Register an info command to echo the room info 160 | bot.register_text_command( 161 | "info", 162 | None, 163 | Some("Print room info".to_string()), 164 | |_, _, room| async move { 165 | if can_message_room(&room).await { 166 | send_help(&room).await; 167 | } 168 | Ok(()) 169 | }, 170 | ) 171 | .await; 172 | 173 | // Register a poke command that will send a poke 174 | bot.register_text_command( 175 | "poke", 176 | Some(" ".to_string()), 177 | Some("Poke the room".to_string()), 178 | |_, msg, room| async move { 179 | // Get the room and message 180 | let mut args = msg 181 | .trim_start_matches(&get_command_prefix()) 182 | .split_whitespace(); 183 | args.next(); // Ignore the "poke" 184 | let room_id = args.next().unwrap_or_default(); 185 | let message = args.collect::>().join(" "); 186 | debug!("Room: {:?}, Message: {:?}", room_id, message); 187 | 188 | // Get a copy of the bot 189 | let bot = GLOBAL_BOT.lock().unwrap().as_ref().unwrap().clone(); 190 | 191 | if let Err(e) = ping_room( 192 | &bot, 193 | room_id, 194 | &reqwest::header::HeaderMap::new(), 195 | &message, 196 | false, 197 | ) 198 | .await 199 | { 200 | error!("Failed to send message: {:?}", e); 201 | if can_message_room(&room).await { 202 | room.send(RoomMessageEventContent::text_plain(format!( 203 | "Failed to send message: {:?}", 204 | e 205 | ))) 206 | .await 207 | .expect("Failed to send message"); 208 | } 209 | return Err(()); 210 | } 211 | Ok(()) 212 | }, 213 | ) 214 | .await; 215 | 216 | // Block Pok'em from sending messages to this room 217 | bot.register_text_command( 218 | "block", 219 | None, 220 | Some("Block Pok'em from sending messages to this room".to_string()), 221 | |_, _, room| async move { 222 | if can_message_room(&room).await { 223 | // If we can't message the room we won't make any changes here 224 | if room.set_tag("dev.pokem.block".into(), TagInfo::default()).await.is_ok() { 225 | room.send(RoomMessageEventContent::text_plain("Pok'em has been blocked from sending messages to this room.\nSend `.unblock` to allow messages again.")) 226 | .await 227 | .expect("Failed to send message"); 228 | } else { 229 | room.send(RoomMessageEventContent::text_plain("ERROR: Failed to block myself.")) 230 | .await 231 | .expect("Failed to send message"); 232 | } 233 | } 234 | Ok(()) 235 | }, 236 | ) 237 | .await; 238 | 239 | // Unblock Pok'em from sending messages to this room 240 | bot.register_text_command( 241 | "unblock", 242 | None, 243 | Some("Unblock Pok'em to allow notifications to this room".to_string()), 244 | |_, _, room| async move { 245 | if room.remove_tag("dev.pokem.block".into()).await.is_ok() { 246 | room.send(RoomMessageEventContent::text_plain( 247 | "Pok'em has been unblocked from sending messages to this room.", 248 | )) 249 | .await 250 | .expect("Failed to send message"); 251 | } else { 252 | room.send(RoomMessageEventContent::text_plain( 253 | "ERROR: Failed to unblock myself.", 254 | )) 255 | .await 256 | .expect("Failed to send message"); 257 | } 258 | Ok(()) 259 | }, 260 | ) 261 | .await; 262 | 263 | // Register command to set variables 264 | bot.register_text_command( 265 | "set", 266 | Some(" ".to_string()), 267 | Some("Configure settings for Pok'em in this room".to_string()), 268 | set_command, 269 | ) 270 | .await; 271 | 272 | // Spawn a tokio task to continuously accept incoming connections 273 | let rooms = Arc::new(RwLock::new(rooms)); 274 | tokio::task::spawn(async move { 275 | // We start a loop to continuously accept incoming connections 276 | loop { 277 | let (stream, _) = match listener.accept().await { 278 | Ok(result) => result, 279 | Err(err) => { 280 | error!("Error accepting connection: {:?}", err); 281 | error!("Exiting daemon"); 282 | return; 283 | } 284 | }; 285 | 286 | // Use an adapter to access something implementing `tokio::io` traits as if they implement 287 | // `hyper::rt` IO traits. 288 | let io = TokioIo::new(stream); 289 | 290 | // Spawn a tokio task to serve each connection concurrently 291 | let cloned_rooms = rooms.clone(); 292 | tokio::task::spawn(async move { 293 | if let Err(err) = http1::Builder::new() 294 | .serve_connection(io, service_fn(|req| daemon_poke(req, cloned_rooms.clone()))) 295 | .await 296 | { 297 | eprintln!("Error serving connection: {:?}", err); 298 | } 299 | }); 300 | } 301 | }); 302 | 303 | // Run the bot and block 304 | // It never exits 305 | loop { 306 | if let Err(e) = bot.run().await { 307 | error!("Bot restarting after it exited with error: {e}"); 308 | } 309 | } 310 | } 311 | 312 | /// Sets config options for the room 313 | async fn set_command(_: matrix_sdk::ruma::OwnedUserId, msg: String, room: Room) -> Result<(), ()> { 314 | let mut room_config = get_room_config(&room).await; 315 | let command = msg.trim_start_matches(&get_command_prefix()); 316 | let key = command.split_whitespace().nth(1).unwrap_or_default(); 317 | let value = command.split_whitespace().nth(2).unwrap_or_default(); 318 | error!("Setting room config: {} {}", key, value); 319 | 320 | let response = match key { 321 | "block" => { 322 | if value.is_empty() { 323 | format!( 324 | "Block cannot be empty\n`{}set block [on|off]`", 325 | get_command_prefix() 326 | ) 327 | } else if value.to_lowercase() == "on" { 328 | room_config.block = true; 329 | "Blocking messages".to_string() 330 | } else if value.to_lowercase() == "off" { 331 | room_config.block = false; 332 | "Unblocking messages".to_string() 333 | } else { 334 | "Invalid value, use 'on' or 'off'".to_string() 335 | } 336 | } 337 | // TODO(2.0): Remove the pass/password allowances in 2.0, it's here for backwards compatibility 338 | "auth" | "authentication" | "password" | "pass" => { 339 | // Set an auth token necessary to send a message. 340 | if value.is_empty() { 341 | format!( 342 | "Token cannot be empty\n`{}set auth [off|token]`", 343 | get_command_prefix() 344 | ) 345 | } else if value.to_lowercase() == "on" { 346 | "Tried setting the Auth Token to 'on', that was probably an accident".to_string() 347 | } else if value.to_lowercase() == "off" { 348 | room_config.auth = None; 349 | "Auth Token removed".to_string() 350 | } else { 351 | room_config.auth = Some(value.to_string()); 352 | format!("Auth Token set to {}", value).to_string() 353 | } 354 | } 355 | _ => { 356 | let block_status = if room_config.block { "on" } else { "off" }; 357 | format!( 358 | "Usage: 359 | `{}set [block|auth] ` 360 | Current values:\n- block: {}{}", 361 | get_command_prefix(), 362 | block_status, 363 | if let Some(token) = room_config.auth.clone() { 364 | format!("\n- Authentication Token: {}", token) 365 | } else { 366 | "".to_string() 367 | } 368 | ) 369 | } 370 | }; 371 | set_room_config(&room, room_config).await; 372 | room.send(RoomMessageEventContent::text_markdown(&response)) 373 | .await 374 | .expect("Failed to send message"); 375 | Ok(()) 376 | } 377 | 378 | /// Poke the room from an http request 379 | async fn daemon_poke( 380 | request: Request, 381 | rooms: Arc>>>, 382 | ) -> anyhow::Result>> { 383 | let headers = request.headers().clone(); 384 | let is_get = request.method() == hyper::Method::GET; 385 | let mut poke_request = PokeRequest::from_request(request).await?; 386 | 387 | // The room_id may be URI encoded 388 | let mut room_id = match urlencoding::decode(&poke_request.topic) { 389 | Ok(room) => room.to_string(), 390 | Err(_) => poke_request.topic, 391 | }; 392 | 393 | let urgent = poke_request.priority.is_some_and(|p| p > 3); 394 | 395 | // Add title 396 | if let Some(title) = poke_request.title { 397 | poke_request.message = format!("**{title}**\n\n{}", poke_request.message); 398 | } 399 | 400 | // Add emojis 401 | if let Some(tags) = poke_request.tags { 402 | let mut emojis_str = String::new(); 403 | let mut non_emojis = Vec::new(); 404 | for shortcode in tags { 405 | if let Some(emoji) = emojis::get_by_shortcode(shortcode.as_str()) { 406 | emojis_str.push_str(emoji.as_ref()); 407 | } else { 408 | non_emojis.push(shortcode); 409 | } 410 | } 411 | if !emojis_str.is_empty() { 412 | poke_request.message = format!("{emojis_str} {}", poke_request.message); 413 | } 414 | if !non_emojis.is_empty() { 415 | poke_request.message = 416 | format!("{}\nTags: {}", poke_request.message, non_emojis.join(", ")); 417 | } 418 | } 419 | 420 | // If the room is a room name in the config, we'll transform it to the room id. 421 | // If the message is urgent and -urgent exists, it will got there, otherwise 422 | // we mention the entire @room. 423 | let mut mention_room = false; 424 | room_id = match &rooms.read().await.as_ref().and_then(|r| { 425 | if urgent { 426 | r.get(&format!("{}-urgent", room_id)).or_else(|| { 427 | // No urgent room found, pinging @room 428 | mention_room = true; 429 | r.get(&room_id) 430 | }) 431 | } else { 432 | r.get(&room_id) 433 | } 434 | }) { 435 | Some(room_id) => room_id.to_string(), 436 | _ => { 437 | // No urgent room found, pinging @room 438 | if urgent { 439 | mention_room = true; 440 | } 441 | room_id 442 | } 443 | }; 444 | 445 | // If it's a GET request, we'll serve a WebUI 446 | if is_get { 447 | // Create the webpage with the room id filled in 448 | let page = r#" 449 | 450 | 451 | 452 | 453 | 454 | Pok'em 455 | 520 | 521 | 522 | 523 |

Pok'em!

524 |

Provide the Room and Message and we'll Poke Them for you.

525 | 526 |
527 |
528 |
529 |
530 |

531 | 532 |
533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | "# 541 | .to_string(); 542 | return Ok(Response::builder() 543 | .status(StatusCode::OK) 544 | .body(Full::new(Bytes::from(page))) 545 | .unwrap()); 546 | } 547 | 548 | // Get a copy of the bot 549 | let bot = GLOBAL_BOT.lock().unwrap().as_ref().unwrap().clone(); 550 | 551 | if let Err(e) = ping_room( 552 | &bot, 553 | &room_id, 554 | &headers, 555 | &poke_request.message, 556 | mention_room, 557 | ) 558 | .await 559 | { 560 | error!("Failed to send message: {:?}", e); 561 | return Ok(Response::builder() 562 | .status(StatusCode::NOT_FOUND) 563 | .body(Full::new(Bytes::from_static(b"Failed to send message"))) 564 | .unwrap()); 565 | } 566 | 567 | Ok(Response::builder() 568 | .status(StatusCode::OK) 569 | .body(Full::new(Bytes::from_static(b"OK"))) 570 | .unwrap()) 571 | } 572 | -------------------------------------------------------------------------------- /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 = "accessory" 7 | version = "1.3.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "87537f9ae7cfa78d5b8ebd1a1db25959f5e737126be4d8eb44a5452fc4b63cde" 10 | dependencies = [ 11 | "macroific", 12 | "proc-macro2", 13 | "quote", 14 | "syn 2.0.77", 15 | ] 16 | 17 | [[package]] 18 | name = "addr2line" 19 | version = "0.24.1" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" 22 | dependencies = [ 23 | "gimli", 24 | ] 25 | 26 | [[package]] 27 | name = "adler2" 28 | version = "2.0.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 31 | 32 | [[package]] 33 | name = "aead" 34 | version = "0.5.2" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" 37 | dependencies = [ 38 | "crypto-common", 39 | "generic-array", 40 | ] 41 | 42 | [[package]] 43 | name = "aes" 44 | version = "0.8.4" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" 47 | dependencies = [ 48 | "cfg-if", 49 | "cipher", 50 | "cpufeatures", 51 | ] 52 | 53 | [[package]] 54 | name = "ahash" 55 | version = "0.8.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 58 | dependencies = [ 59 | "cfg-if", 60 | "once_cell", 61 | "version_check", 62 | "zerocopy", 63 | ] 64 | 65 | [[package]] 66 | name = "aho-corasick" 67 | version = "1.1.3" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 70 | dependencies = [ 71 | "memchr", 72 | ] 73 | 74 | [[package]] 75 | name = "allocator-api2" 76 | version = "0.2.18" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" 79 | 80 | [[package]] 81 | name = "anstream" 82 | version = "0.6.15" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 85 | dependencies = [ 86 | "anstyle", 87 | "anstyle-parse", 88 | "anstyle-query", 89 | "anstyle-wincon", 90 | "colorchoice", 91 | "is_terminal_polyfill", 92 | "utf8parse", 93 | ] 94 | 95 | [[package]] 96 | name = "anstyle" 97 | version = "1.0.8" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 100 | 101 | [[package]] 102 | name = "anstyle-parse" 103 | version = "0.2.5" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 106 | dependencies = [ 107 | "utf8parse", 108 | ] 109 | 110 | [[package]] 111 | name = "anstyle-query" 112 | version = "1.1.1" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 115 | dependencies = [ 116 | "windows-sys 0.52.0", 117 | ] 118 | 119 | [[package]] 120 | name = "anstyle-wincon" 121 | version = "3.0.4" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 124 | dependencies = [ 125 | "anstyle", 126 | "windows-sys 0.52.0", 127 | ] 128 | 129 | [[package]] 130 | name = "anyhow" 131 | version = "1.0.89" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" 134 | 135 | [[package]] 136 | name = "anymap2" 137 | version = "0.13.0" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" 140 | 141 | [[package]] 142 | name = "aquamarine" 143 | version = "0.5.0" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" 146 | dependencies = [ 147 | "include_dir", 148 | "itertools 0.10.5", 149 | "proc-macro-error", 150 | "proc-macro2", 151 | "quote", 152 | "syn 2.0.77", 153 | ] 154 | 155 | [[package]] 156 | name = "arrayref" 157 | version = "0.3.9" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" 160 | 161 | [[package]] 162 | name = "arrayvec" 163 | version = "0.7.6" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 166 | dependencies = [ 167 | "serde", 168 | ] 169 | 170 | [[package]] 171 | name = "as_variant" 172 | version = "1.2.0" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "f38fa22307249f86fb7fad906fcae77f2564caeb56d7209103c551cd1cf4798f" 175 | 176 | [[package]] 177 | name = "assign" 178 | version = "1.1.1" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" 181 | 182 | [[package]] 183 | name = "async-channel" 184 | version = "2.3.1" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 187 | dependencies = [ 188 | "concurrent-queue", 189 | "event-listener-strategy", 190 | "futures-core", 191 | "pin-project-lite", 192 | ] 193 | 194 | [[package]] 195 | name = "async-stream" 196 | version = "0.3.5" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 199 | dependencies = [ 200 | "async-stream-impl", 201 | "futures-core", 202 | "pin-project-lite", 203 | ] 204 | 205 | [[package]] 206 | name = "async-stream-impl" 207 | version = "0.3.5" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 210 | dependencies = [ 211 | "proc-macro2", 212 | "quote", 213 | "syn 2.0.77", 214 | ] 215 | 216 | [[package]] 217 | name = "async-trait" 218 | version = "0.1.82" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" 221 | dependencies = [ 222 | "proc-macro2", 223 | "quote", 224 | "syn 2.0.77", 225 | ] 226 | 227 | [[package]] 228 | name = "atomic-waker" 229 | version = "1.1.2" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 232 | 233 | [[package]] 234 | name = "autocfg" 235 | version = "1.3.0" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 238 | 239 | [[package]] 240 | name = "backoff" 241 | version = "0.4.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" 244 | dependencies = [ 245 | "futures-core", 246 | "getrandom", 247 | "instant", 248 | "pin-project-lite", 249 | "rand", 250 | "tokio", 251 | ] 252 | 253 | [[package]] 254 | name = "backtrace" 255 | version = "0.3.74" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 258 | dependencies = [ 259 | "addr2line", 260 | "cfg-if", 261 | "libc", 262 | "miniz_oxide", 263 | "object", 264 | "rustc-demangle", 265 | "windows-targets 0.52.6", 266 | ] 267 | 268 | [[package]] 269 | name = "base64" 270 | version = "0.21.7" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 273 | 274 | [[package]] 275 | name = "base64" 276 | version = "0.22.1" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 279 | 280 | [[package]] 281 | name = "base64ct" 282 | version = "1.6.0" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" 285 | 286 | [[package]] 287 | name = "bitflags" 288 | version = "1.3.2" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 291 | 292 | [[package]] 293 | name = "bitflags" 294 | version = "2.6.0" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 297 | 298 | [[package]] 299 | name = "bitmaps" 300 | version = "3.2.1" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" 303 | 304 | [[package]] 305 | name = "blake3" 306 | version = "1.5.4" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" 309 | dependencies = [ 310 | "arrayref", 311 | "arrayvec", 312 | "cc", 313 | "cfg-if", 314 | "constant_time_eq", 315 | ] 316 | 317 | [[package]] 318 | name = "block-buffer" 319 | version = "0.10.4" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 322 | dependencies = [ 323 | "generic-array", 324 | ] 325 | 326 | [[package]] 327 | name = "block-padding" 328 | version = "0.3.3" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" 331 | dependencies = [ 332 | "generic-array", 333 | ] 334 | 335 | [[package]] 336 | name = "bs58" 337 | version = "0.5.1" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" 340 | dependencies = [ 341 | "tinyvec", 342 | ] 343 | 344 | [[package]] 345 | name = "bumpalo" 346 | version = "3.16.0" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 349 | 350 | [[package]] 351 | name = "byteorder" 352 | version = "1.5.0" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 355 | 356 | [[package]] 357 | name = "bytes" 358 | version = "1.7.1" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" 361 | 362 | [[package]] 363 | name = "bytesize" 364 | version = "1.3.0" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" 367 | 368 | [[package]] 369 | name = "cbc" 370 | version = "0.1.2" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" 373 | dependencies = [ 374 | "cipher", 375 | ] 376 | 377 | [[package]] 378 | name = "cc" 379 | version = "1.1.19" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" 382 | dependencies = [ 383 | "shlex", 384 | ] 385 | 386 | [[package]] 387 | name = "cfg-if" 388 | version = "1.0.0" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 391 | 392 | [[package]] 393 | name = "cfg-vis" 394 | version = "0.3.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "c3a2c3bf5fc10fe2ca157564fbe08a4cb2b0a7d2ff3fe2f9683e65d5e7c7859c" 397 | dependencies = [ 398 | "proc-macro-crate 1.3.1", 399 | "proc-macro2", 400 | "quote", 401 | "syn 1.0.109", 402 | ] 403 | 404 | [[package]] 405 | name = "chacha20" 406 | version = "0.9.1" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" 409 | dependencies = [ 410 | "cfg-if", 411 | "cipher", 412 | "cpufeatures", 413 | ] 414 | 415 | [[package]] 416 | name = "chacha20poly1305" 417 | version = "0.10.1" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" 420 | dependencies = [ 421 | "aead", 422 | "chacha20", 423 | "cipher", 424 | "poly1305", 425 | "zeroize", 426 | ] 427 | 428 | [[package]] 429 | name = "cipher" 430 | version = "0.4.4" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 433 | dependencies = [ 434 | "crypto-common", 435 | "inout", 436 | "zeroize", 437 | ] 438 | 439 | [[package]] 440 | name = "clap" 441 | version = "4.5.17" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" 444 | dependencies = [ 445 | "clap_builder", 446 | "clap_derive", 447 | ] 448 | 449 | [[package]] 450 | name = "clap_builder" 451 | version = "4.5.17" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" 454 | dependencies = [ 455 | "anstream", 456 | "anstyle", 457 | "clap_lex", 458 | "strsim", 459 | ] 460 | 461 | [[package]] 462 | name = "clap_derive" 463 | version = "4.5.13" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" 466 | dependencies = [ 467 | "heck", 468 | "proc-macro2", 469 | "quote", 470 | "syn 2.0.77", 471 | ] 472 | 473 | [[package]] 474 | name = "clap_lex" 475 | version = "0.7.2" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 478 | 479 | [[package]] 480 | name = "colorchoice" 481 | version = "1.0.2" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 484 | 485 | [[package]] 486 | name = "concurrent-queue" 487 | version = "2.5.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 490 | dependencies = [ 491 | "crossbeam-utils", 492 | ] 493 | 494 | [[package]] 495 | name = "const-oid" 496 | version = "0.9.6" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" 499 | 500 | [[package]] 501 | name = "const_panic" 502 | version = "0.2.9" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "7782af8f90fe69a4bb41e460abe1727d493403d8b2cc43201a3a3e906b24379f" 505 | 506 | [[package]] 507 | name = "constant_time_eq" 508 | version = "0.3.1" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" 511 | 512 | [[package]] 513 | name = "core-foundation" 514 | version = "0.9.4" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 517 | dependencies = [ 518 | "core-foundation-sys", 519 | "libc", 520 | ] 521 | 522 | [[package]] 523 | name = "core-foundation-sys" 524 | version = "0.8.7" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 527 | 528 | [[package]] 529 | name = "cpufeatures" 530 | version = "0.2.14" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 533 | dependencies = [ 534 | "libc", 535 | ] 536 | 537 | [[package]] 538 | name = "crossbeam-utils" 539 | version = "0.8.20" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 542 | 543 | [[package]] 544 | name = "crypto-common" 545 | version = "0.1.6" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 548 | dependencies = [ 549 | "generic-array", 550 | "rand_core", 551 | "typenum", 552 | ] 553 | 554 | [[package]] 555 | name = "ctr" 556 | version = "0.9.2" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" 559 | dependencies = [ 560 | "cipher", 561 | ] 562 | 563 | [[package]] 564 | name = "curve25519-dalek" 565 | version = "4.1.3" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" 568 | dependencies = [ 569 | "cfg-if", 570 | "cpufeatures", 571 | "curve25519-dalek-derive", 572 | "digest", 573 | "fiat-crypto", 574 | "rustc_version", 575 | "serde", 576 | "subtle", 577 | "zeroize", 578 | ] 579 | 580 | [[package]] 581 | name = "curve25519-dalek-derive" 582 | version = "0.1.1" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" 585 | dependencies = [ 586 | "proc-macro2", 587 | "quote", 588 | "syn 2.0.77", 589 | ] 590 | 591 | [[package]] 592 | name = "deadpool" 593 | version = "0.10.0" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" 596 | dependencies = [ 597 | "async-trait", 598 | "deadpool-runtime", 599 | "num_cpus", 600 | "tokio", 601 | ] 602 | 603 | [[package]] 604 | name = "deadpool-runtime" 605 | version = "0.1.4" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" 608 | dependencies = [ 609 | "tokio", 610 | ] 611 | 612 | [[package]] 613 | name = "deadpool-sqlite" 614 | version = "0.7.0" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "b8010e36e12f3be22543a5e478b4af20aeead9a700dd69581a5e050a070fc22c" 617 | dependencies = [ 618 | "deadpool", 619 | "deadpool-sync", 620 | "rusqlite", 621 | ] 622 | 623 | [[package]] 624 | name = "deadpool-sync" 625 | version = "0.1.4" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "524bc3df0d57e98ecd022e21ba31166c2625e7d3e5bcc4510efaeeab4abcab04" 628 | dependencies = [ 629 | "deadpool-runtime", 630 | ] 631 | 632 | [[package]] 633 | name = "delegate-display" 634 | version = "2.1.1" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "98a85201f233142ac819bbf6226e36d0b5e129a47bd325084674261c82d4cd66" 637 | dependencies = [ 638 | "macroific", 639 | "proc-macro2", 640 | "quote", 641 | "syn 2.0.77", 642 | ] 643 | 644 | [[package]] 645 | name = "der" 646 | version = "0.7.9" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" 649 | dependencies = [ 650 | "const-oid", 651 | "der_derive", 652 | "flagset", 653 | "zeroize", 654 | ] 655 | 656 | [[package]] 657 | name = "der_derive" 658 | version = "0.7.3" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" 661 | dependencies = [ 662 | "proc-macro2", 663 | "quote", 664 | "syn 2.0.77", 665 | ] 666 | 667 | [[package]] 668 | name = "digest" 669 | version = "0.10.7" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 672 | dependencies = [ 673 | "block-buffer", 674 | "crypto-common", 675 | "subtle", 676 | ] 677 | 678 | [[package]] 679 | name = "dirs" 680 | version = "5.0.1" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" 683 | dependencies = [ 684 | "dirs-sys", 685 | ] 686 | 687 | [[package]] 688 | name = "dirs-sys" 689 | version = "0.4.1" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" 692 | dependencies = [ 693 | "libc", 694 | "option-ext", 695 | "redox_users", 696 | "windows-sys 0.48.0", 697 | ] 698 | 699 | [[package]] 700 | name = "displaydoc" 701 | version = "0.2.5" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 704 | dependencies = [ 705 | "proc-macro2", 706 | "quote", 707 | "syn 2.0.77", 708 | ] 709 | 710 | [[package]] 711 | name = "ed25519" 712 | version = "2.2.3" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" 715 | dependencies = [ 716 | "pkcs8", 717 | "serde", 718 | "signature", 719 | ] 720 | 721 | [[package]] 722 | name = "ed25519-dalek" 723 | version = "2.1.1" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" 726 | dependencies = [ 727 | "curve25519-dalek", 728 | "ed25519", 729 | "rand_core", 730 | "serde", 731 | "sha2", 732 | "subtle", 733 | "zeroize", 734 | ] 735 | 736 | [[package]] 737 | name = "either" 738 | version = "1.13.0" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 741 | 742 | [[package]] 743 | name = "emojis" 744 | version = "0.6.3" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "e72f23d65b46527e461b161ab9a126c378aa2249d8a8d15718d23ab1fb4d8786" 747 | dependencies = [ 748 | "phf", 749 | ] 750 | 751 | [[package]] 752 | name = "encoding_rs" 753 | version = "0.8.34" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 756 | dependencies = [ 757 | "cfg-if", 758 | ] 759 | 760 | [[package]] 761 | name = "equivalent" 762 | version = "1.0.1" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 765 | 766 | [[package]] 767 | name = "errno" 768 | version = "0.3.9" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 771 | dependencies = [ 772 | "libc", 773 | "windows-sys 0.52.0", 774 | ] 775 | 776 | [[package]] 777 | name = "event-listener" 778 | version = "4.0.3" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" 781 | dependencies = [ 782 | "concurrent-queue", 783 | "parking", 784 | "pin-project-lite", 785 | ] 786 | 787 | [[package]] 788 | name = "event-listener" 789 | version = "5.3.1" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 792 | dependencies = [ 793 | "concurrent-queue", 794 | "parking", 795 | "pin-project-lite", 796 | ] 797 | 798 | [[package]] 799 | name = "event-listener-strategy" 800 | version = "0.5.2" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" 803 | dependencies = [ 804 | "event-listener 5.3.1", 805 | "pin-project-lite", 806 | ] 807 | 808 | [[package]] 809 | name = "eyeball" 810 | version = "0.8.8" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "d93bd0ebf93d61d6332d3c09a96e97975968a44e19a64c947bde06e6baff383f" 813 | dependencies = [ 814 | "futures-core", 815 | "readlock", 816 | "tracing", 817 | ] 818 | 819 | [[package]] 820 | name = "eyeball-im" 821 | version = "0.4.3" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "9326c8d9f6d59d18935412608b4514cc661e4e068011bb2f523f6c8b1cfa3bd4" 824 | dependencies = [ 825 | "futures-core", 826 | "imbl", 827 | "tokio", 828 | "tokio-util", 829 | "tracing", 830 | ] 831 | 832 | [[package]] 833 | name = "fallible-iterator" 834 | version = "0.3.0" 835 | source = "registry+https://github.com/rust-lang/crates.io-index" 836 | checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" 837 | 838 | [[package]] 839 | name = "fallible-streaming-iterator" 840 | version = "0.1.9" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 843 | 844 | [[package]] 845 | name = "fancy_constructor" 846 | version = "1.3.0" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "07b19d0e43eae2bfbafe4931b5e79c73fb1a849ca15cd41a761a7b8587f9a1a2" 849 | dependencies = [ 850 | "macroific", 851 | "proc-macro2", 852 | "quote", 853 | "syn 2.0.77", 854 | ] 855 | 856 | [[package]] 857 | name = "fastrand" 858 | version = "2.1.1" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" 861 | 862 | [[package]] 863 | name = "fiat-crypto" 864 | version = "0.2.9" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" 867 | 868 | [[package]] 869 | name = "flagset" 870 | version = "0.4.6" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec" 873 | 874 | [[package]] 875 | name = "fnv" 876 | version = "1.0.7" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 879 | 880 | [[package]] 881 | name = "foreign-types" 882 | version = "0.3.2" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 885 | dependencies = [ 886 | "foreign-types-shared", 887 | ] 888 | 889 | [[package]] 890 | name = "foreign-types-shared" 891 | version = "0.1.1" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 894 | 895 | [[package]] 896 | name = "form_urlencoded" 897 | version = "1.2.1" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 900 | dependencies = [ 901 | "percent-encoding", 902 | ] 903 | 904 | [[package]] 905 | name = "futures-channel" 906 | version = "0.3.30" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 909 | dependencies = [ 910 | "futures-core", 911 | ] 912 | 913 | [[package]] 914 | name = "futures-core" 915 | version = "0.3.30" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 918 | 919 | [[package]] 920 | name = "futures-io" 921 | version = "0.3.30" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 924 | 925 | [[package]] 926 | name = "futures-macro" 927 | version = "0.3.30" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 930 | dependencies = [ 931 | "proc-macro2", 932 | "quote", 933 | "syn 2.0.77", 934 | ] 935 | 936 | [[package]] 937 | name = "futures-sink" 938 | version = "0.3.30" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 941 | 942 | [[package]] 943 | name = "futures-task" 944 | version = "0.3.30" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 947 | 948 | [[package]] 949 | name = "futures-util" 950 | version = "0.3.30" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 953 | dependencies = [ 954 | "futures-channel", 955 | "futures-core", 956 | "futures-io", 957 | "futures-macro", 958 | "futures-sink", 959 | "futures-task", 960 | "memchr", 961 | "pin-project-lite", 962 | "pin-utils", 963 | "slab", 964 | ] 965 | 966 | [[package]] 967 | name = "generic-array" 968 | version = "0.14.7" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 971 | dependencies = [ 972 | "typenum", 973 | "version_check", 974 | ] 975 | 976 | [[package]] 977 | name = "getrandom" 978 | version = "0.2.15" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 981 | dependencies = [ 982 | "cfg-if", 983 | "js-sys", 984 | "libc", 985 | "wasi", 986 | "wasm-bindgen", 987 | ] 988 | 989 | [[package]] 990 | name = "gimli" 991 | version = "0.31.0" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" 994 | 995 | [[package]] 996 | name = "gloo-timers" 997 | version = "0.3.0" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" 1000 | dependencies = [ 1001 | "futures-channel", 1002 | "futures-core", 1003 | "js-sys", 1004 | "wasm-bindgen", 1005 | ] 1006 | 1007 | [[package]] 1008 | name = "gloo-utils" 1009 | version = "0.2.0" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" 1012 | dependencies = [ 1013 | "js-sys", 1014 | "serde", 1015 | "serde_json", 1016 | "wasm-bindgen", 1017 | "web-sys", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "h2" 1022 | version = "0.3.26" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 1025 | dependencies = [ 1026 | "bytes", 1027 | "fnv", 1028 | "futures-core", 1029 | "futures-sink", 1030 | "futures-util", 1031 | "http 0.2.12", 1032 | "indexmap", 1033 | "slab", 1034 | "tokio", 1035 | "tokio-util", 1036 | "tracing", 1037 | ] 1038 | 1039 | [[package]] 1040 | name = "h2" 1041 | version = "0.4.6" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" 1044 | dependencies = [ 1045 | "atomic-waker", 1046 | "bytes", 1047 | "fnv", 1048 | "futures-core", 1049 | "futures-sink", 1050 | "http 1.1.0", 1051 | "indexmap", 1052 | "slab", 1053 | "tokio", 1054 | "tokio-util", 1055 | "tracing", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "hashbrown" 1060 | version = "0.14.5" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1063 | dependencies = [ 1064 | "ahash", 1065 | "allocator-api2", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "hashlink" 1070 | version = "0.8.4" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" 1073 | dependencies = [ 1074 | "hashbrown", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "headjack" 1079 | version = "0.4.0" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "a056f945e90d6af1eb06fccfe12f99208380d40a9fc5e4d749b925de3afba76c" 1082 | dependencies = [ 1083 | "anyhow", 1084 | "dirs", 1085 | "lazy_static", 1086 | "matrix-sdk", 1087 | "rand", 1088 | "regex", 1089 | "serde", 1090 | "serde_json", 1091 | "tokio", 1092 | "tracing", 1093 | ] 1094 | 1095 | [[package]] 1096 | name = "heck" 1097 | version = "0.5.0" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1100 | 1101 | [[package]] 1102 | name = "hermit-abi" 1103 | version = "0.3.9" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 1106 | 1107 | [[package]] 1108 | name = "hermit-abi" 1109 | version = "0.4.0" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 1112 | 1113 | [[package]] 1114 | name = "hkdf" 1115 | version = "0.12.4" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" 1118 | dependencies = [ 1119 | "hmac", 1120 | ] 1121 | 1122 | [[package]] 1123 | name = "hmac" 1124 | version = "0.12.1" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1127 | dependencies = [ 1128 | "digest", 1129 | ] 1130 | 1131 | [[package]] 1132 | name = "http" 1133 | version = "0.2.12" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 1136 | dependencies = [ 1137 | "bytes", 1138 | "fnv", 1139 | "itoa", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "http" 1144 | version = "1.1.0" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 1147 | dependencies = [ 1148 | "bytes", 1149 | "fnv", 1150 | "itoa", 1151 | ] 1152 | 1153 | [[package]] 1154 | name = "http-body" 1155 | version = "0.4.6" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 1158 | dependencies = [ 1159 | "bytes", 1160 | "http 0.2.12", 1161 | "pin-project-lite", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "http-body" 1166 | version = "1.0.1" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 1169 | dependencies = [ 1170 | "bytes", 1171 | "http 1.1.0", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "http-body-util" 1176 | version = "0.1.2" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 1179 | dependencies = [ 1180 | "bytes", 1181 | "futures-util", 1182 | "http 1.1.0", 1183 | "http-body 1.0.1", 1184 | "pin-project-lite", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "httparse" 1189 | version = "1.9.4" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" 1192 | 1193 | [[package]] 1194 | name = "httpdate" 1195 | version = "1.0.3" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1198 | 1199 | [[package]] 1200 | name = "hyper" 1201 | version = "0.14.30" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" 1204 | dependencies = [ 1205 | "bytes", 1206 | "futures-channel", 1207 | "futures-core", 1208 | "futures-util", 1209 | "h2 0.3.26", 1210 | "http 0.2.12", 1211 | "http-body 0.4.6", 1212 | "httparse", 1213 | "httpdate", 1214 | "itoa", 1215 | "pin-project-lite", 1216 | "socket2", 1217 | "tokio", 1218 | "tower-service", 1219 | "tracing", 1220 | "want", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "hyper" 1225 | version = "1.4.1" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" 1228 | dependencies = [ 1229 | "bytes", 1230 | "futures-channel", 1231 | "futures-util", 1232 | "h2 0.4.6", 1233 | "http 1.1.0", 1234 | "http-body 1.0.1", 1235 | "httparse", 1236 | "httpdate", 1237 | "itoa", 1238 | "pin-project-lite", 1239 | "smallvec", 1240 | "tokio", 1241 | "want", 1242 | ] 1243 | 1244 | [[package]] 1245 | name = "hyper-rustls" 1246 | version = "0.27.3" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" 1249 | dependencies = [ 1250 | "futures-util", 1251 | "http 1.1.0", 1252 | "hyper 1.4.1", 1253 | "hyper-util", 1254 | "rustls", 1255 | "rustls-pki-types", 1256 | "tokio", 1257 | "tokio-rustls", 1258 | "tower-service", 1259 | ] 1260 | 1261 | [[package]] 1262 | name = "hyper-tls" 1263 | version = "0.5.0" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 1266 | dependencies = [ 1267 | "bytes", 1268 | "hyper 0.14.30", 1269 | "native-tls", 1270 | "tokio", 1271 | "tokio-native-tls", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "hyper-tls" 1276 | version = "0.6.0" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 1279 | dependencies = [ 1280 | "bytes", 1281 | "http-body-util", 1282 | "hyper 1.4.1", 1283 | "hyper-util", 1284 | "native-tls", 1285 | "tokio", 1286 | "tokio-native-tls", 1287 | "tower-service", 1288 | ] 1289 | 1290 | [[package]] 1291 | name = "hyper-util" 1292 | version = "0.1.8" 1293 | source = "registry+https://github.com/rust-lang/crates.io-index" 1294 | checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" 1295 | dependencies = [ 1296 | "bytes", 1297 | "futures-channel", 1298 | "futures-util", 1299 | "http 1.1.0", 1300 | "http-body 1.0.1", 1301 | "hyper 1.4.1", 1302 | "pin-project-lite", 1303 | "socket2", 1304 | "tokio", 1305 | "tower", 1306 | "tower-service", 1307 | "tracing", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "idna" 1312 | version = "0.5.0" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 1315 | dependencies = [ 1316 | "unicode-bidi", 1317 | "unicode-normalization", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "imbl" 1322 | version = "2.0.3" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "978d142c8028edf52095703af2fad11d6f611af1246685725d6b850634647085" 1325 | dependencies = [ 1326 | "bitmaps", 1327 | "imbl-sized-chunks", 1328 | "rand_core", 1329 | "rand_xoshiro", 1330 | "serde", 1331 | "version_check", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "imbl-sized-chunks" 1336 | version = "0.1.2" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "144006fb58ed787dcae3f54575ff4349755b00ccc99f4b4873860b654be1ed63" 1339 | dependencies = [ 1340 | "bitmaps", 1341 | ] 1342 | 1343 | [[package]] 1344 | name = "include_dir" 1345 | version = "0.7.4" 1346 | source = "registry+https://github.com/rust-lang/crates.io-index" 1347 | checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" 1348 | dependencies = [ 1349 | "include_dir_macros", 1350 | ] 1351 | 1352 | [[package]] 1353 | name = "include_dir_macros" 1354 | version = "0.7.4" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" 1357 | dependencies = [ 1358 | "proc-macro2", 1359 | "quote", 1360 | ] 1361 | 1362 | [[package]] 1363 | name = "indexed_db_futures" 1364 | version = "0.4.2" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "0704b71f13f81b5933d791abf2de26b33c40935143985220299a357721166706" 1367 | dependencies = [ 1368 | "accessory", 1369 | "cfg-if", 1370 | "delegate-display", 1371 | "fancy_constructor", 1372 | "js-sys", 1373 | "uuid", 1374 | "wasm-bindgen", 1375 | "wasm-bindgen-futures", 1376 | "web-sys", 1377 | ] 1378 | 1379 | [[package]] 1380 | name = "indexmap" 1381 | version = "2.5.0" 1382 | source = "registry+https://github.com/rust-lang/crates.io-index" 1383 | checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" 1384 | dependencies = [ 1385 | "equivalent", 1386 | "hashbrown", 1387 | "serde", 1388 | ] 1389 | 1390 | [[package]] 1391 | name = "inout" 1392 | version = "0.1.3" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" 1395 | dependencies = [ 1396 | "block-padding", 1397 | "generic-array", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "instant" 1402 | version = "0.1.13" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" 1405 | dependencies = [ 1406 | "cfg-if", 1407 | "js-sys", 1408 | "wasm-bindgen", 1409 | "web-sys", 1410 | ] 1411 | 1412 | [[package]] 1413 | name = "ipnet" 1414 | version = "2.10.0" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" 1417 | 1418 | [[package]] 1419 | name = "is-terminal" 1420 | version = "0.4.13" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" 1423 | dependencies = [ 1424 | "hermit-abi 0.4.0", 1425 | "libc", 1426 | "windows-sys 0.52.0", 1427 | ] 1428 | 1429 | [[package]] 1430 | name = "is_terminal_polyfill" 1431 | version = "1.70.1" 1432 | source = "registry+https://github.com/rust-lang/crates.io-index" 1433 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1434 | 1435 | [[package]] 1436 | name = "itertools" 1437 | version = "0.10.5" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1440 | dependencies = [ 1441 | "either", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "itertools" 1446 | version = "0.12.1" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 1449 | dependencies = [ 1450 | "either", 1451 | ] 1452 | 1453 | [[package]] 1454 | name = "itertools" 1455 | version = "0.13.0" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" 1458 | dependencies = [ 1459 | "either", 1460 | ] 1461 | 1462 | [[package]] 1463 | name = "itoa" 1464 | version = "1.0.11" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 1467 | 1468 | [[package]] 1469 | name = "js-sys" 1470 | version = "0.3.70" 1471 | source = "registry+https://github.com/rust-lang/crates.io-index" 1472 | checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" 1473 | dependencies = [ 1474 | "wasm-bindgen", 1475 | ] 1476 | 1477 | [[package]] 1478 | name = "js_int" 1479 | version = "0.2.2" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "d937f95470b270ce8b8950207715d71aa8e153c0d44c6684d59397ed4949160a" 1482 | dependencies = [ 1483 | "serde", 1484 | ] 1485 | 1486 | [[package]] 1487 | name = "js_option" 1488 | version = "0.1.1" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | checksum = "68421373957a1593a767013698dbf206e2b221eefe97a44d98d18672ff38423c" 1491 | dependencies = [ 1492 | "serde", 1493 | ] 1494 | 1495 | [[package]] 1496 | name = "konst" 1497 | version = "0.3.9" 1498 | source = "registry+https://github.com/rust-lang/crates.io-index" 1499 | checksum = "50a0ba6de5f7af397afff922f22c149ff605c766cd3269cf6c1cd5e466dbe3b9" 1500 | dependencies = [ 1501 | "const_panic", 1502 | "konst_kernel", 1503 | "typewit", 1504 | ] 1505 | 1506 | [[package]] 1507 | name = "konst_kernel" 1508 | version = "0.3.9" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "be0a455a1719220fd6adf756088e1c69a85bf14b6a9e24537a5cc04f503edb2b" 1511 | dependencies = [ 1512 | "typewit", 1513 | ] 1514 | 1515 | [[package]] 1516 | name = "lazy_static" 1517 | version = "1.5.0" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1520 | 1521 | [[package]] 1522 | name = "libc" 1523 | version = "0.2.158" 1524 | source = "registry+https://github.com/rust-lang/crates.io-index" 1525 | checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" 1526 | 1527 | [[package]] 1528 | name = "libredox" 1529 | version = "0.1.3" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 1532 | dependencies = [ 1533 | "bitflags 2.6.0", 1534 | "libc", 1535 | ] 1536 | 1537 | [[package]] 1538 | name = "libsqlite3-sys" 1539 | version = "0.27.0" 1540 | source = "registry+https://github.com/rust-lang/crates.io-index" 1541 | checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" 1542 | dependencies = [ 1543 | "pkg-config", 1544 | "vcpkg", 1545 | ] 1546 | 1547 | [[package]] 1548 | name = "linux-raw-sys" 1549 | version = "0.4.14" 1550 | source = "registry+https://github.com/rust-lang/crates.io-index" 1551 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1552 | 1553 | [[package]] 1554 | name = "lock_api" 1555 | version = "0.4.12" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1558 | dependencies = [ 1559 | "autocfg", 1560 | "scopeguard", 1561 | ] 1562 | 1563 | [[package]] 1564 | name = "log" 1565 | version = "0.4.22" 1566 | source = "registry+https://github.com/rust-lang/crates.io-index" 1567 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1568 | 1569 | [[package]] 1570 | name = "macroific" 1571 | version = "1.3.1" 1572 | source = "registry+https://github.com/rust-lang/crates.io-index" 1573 | checksum = "f05c00ac596022625d01047c421a0d97d7f09a18e429187b341c201cb631b9dd" 1574 | dependencies = [ 1575 | "macroific_attr_parse", 1576 | "macroific_core", 1577 | "macroific_macro", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "macroific_attr_parse" 1582 | version = "1.3.0" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "fd94d5da95b30ae6e10621ad02340909346ad91661f3f8c0f2b62345e46a2f67" 1585 | dependencies = [ 1586 | "cfg-if", 1587 | "proc-macro2", 1588 | "quote", 1589 | "syn 2.0.77", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "macroific_core" 1594 | version = "1.0.2" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "13198c120864097a565ccb3ff947672d969932b7975ebd4085732c9f09435e55" 1597 | dependencies = [ 1598 | "proc-macro2", 1599 | "quote", 1600 | "syn 2.0.77", 1601 | ] 1602 | 1603 | [[package]] 1604 | name = "macroific_macro" 1605 | version = "1.1.0" 1606 | source = "registry+https://github.com/rust-lang/crates.io-index" 1607 | checksum = "b0c9853143cbed7f1e41dc39fee95f9b361bec65c8dc2a01bf609be01b61f5ae" 1608 | dependencies = [ 1609 | "macroific_attr_parse", 1610 | "macroific_core", 1611 | "proc-macro2", 1612 | "quote", 1613 | "syn 2.0.77", 1614 | ] 1615 | 1616 | [[package]] 1617 | name = "maplit" 1618 | version = "1.0.2" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 1621 | 1622 | [[package]] 1623 | name = "matrix-pickle" 1624 | version = "0.2.1" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | checksum = "4e2551de3bba2cc65b52dc6b268df6114011fe118ac24870fbcf1b35537bd721" 1627 | dependencies = [ 1628 | "matrix-pickle-derive", 1629 | "thiserror", 1630 | ] 1631 | 1632 | [[package]] 1633 | name = "matrix-pickle-derive" 1634 | version = "0.2.1" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | checksum = "f75de44c3120d78e978adbcf6d453b20ba011f3c46363e52d1dbbc72f545e9fb" 1637 | dependencies = [ 1638 | "proc-macro-crate 3.2.0", 1639 | "proc-macro-error2", 1640 | "proc-macro2", 1641 | "quote", 1642 | "syn 2.0.77", 1643 | ] 1644 | 1645 | [[package]] 1646 | name = "matrix-sdk" 1647 | version = "0.7.1" 1648 | source = "registry+https://github.com/rust-lang/crates.io-index" 1649 | checksum = "336687e5fc8b33661a31681e988a67e9a3090c7fb1a8323a7f71eeaabad642ec" 1650 | dependencies = [ 1651 | "anymap2", 1652 | "aquamarine", 1653 | "as_variant", 1654 | "async-channel", 1655 | "async-stream", 1656 | "async-trait", 1657 | "backoff", 1658 | "bytes", 1659 | "bytesize", 1660 | "cfg-vis", 1661 | "event-listener 4.0.3", 1662 | "eyeball", 1663 | "eyeball-im", 1664 | "futures-core", 1665 | "futures-util", 1666 | "gloo-timers", 1667 | "http 0.2.12", 1668 | "imbl", 1669 | "indexmap", 1670 | "matrix-sdk-base", 1671 | "matrix-sdk-common", 1672 | "matrix-sdk-indexeddb", 1673 | "matrix-sdk-sqlite", 1674 | "mime", 1675 | "mime2ext", 1676 | "reqwest 0.11.27", 1677 | "ruma", 1678 | "serde", 1679 | "serde_html_form", 1680 | "serde_json", 1681 | "tempfile", 1682 | "thiserror", 1683 | "tokio", 1684 | "tokio-stream", 1685 | "tokio-util", 1686 | "tracing", 1687 | "url", 1688 | "urlencoding", 1689 | "zeroize", 1690 | ] 1691 | 1692 | [[package]] 1693 | name = "matrix-sdk-base" 1694 | version = "0.7.0" 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" 1696 | checksum = "00891954d0826a94f1d130f46cbca64176003a234c1be5d9d282970d31cf0c87" 1697 | dependencies = [ 1698 | "as_variant", 1699 | "async-trait", 1700 | "bitflags 2.6.0", 1701 | "eyeball", 1702 | "eyeball-im", 1703 | "futures-util", 1704 | "matrix-sdk-common", 1705 | "matrix-sdk-crypto", 1706 | "matrix-sdk-store-encryption", 1707 | "once_cell", 1708 | "ruma", 1709 | "serde", 1710 | "serde_json", 1711 | "thiserror", 1712 | "tokio", 1713 | "tracing", 1714 | ] 1715 | 1716 | [[package]] 1717 | name = "matrix-sdk-common" 1718 | version = "0.7.0" 1719 | source = "registry+https://github.com/rust-lang/crates.io-index" 1720 | checksum = "bb365a626ab6f6c6a2422cfe2565522f19accb06706c6d04bca8f0f71df29c9f" 1721 | dependencies = [ 1722 | "async-trait", 1723 | "futures-core", 1724 | "futures-util", 1725 | "gloo-timers", 1726 | "instant", 1727 | "ruma", 1728 | "serde", 1729 | "serde_json", 1730 | "thiserror", 1731 | "tokio", 1732 | "tracing", 1733 | "tracing-subscriber", 1734 | "wasm-bindgen", 1735 | "wasm-bindgen-futures", 1736 | "web-sys", 1737 | ] 1738 | 1739 | [[package]] 1740 | name = "matrix-sdk-crypto" 1741 | version = "0.7.2" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "e03a64d12a83ebe33bb55de9b77faef4ce27006f946f8468c3311f311f39ab8b" 1744 | dependencies = [ 1745 | "aes", 1746 | "as_variant", 1747 | "async-trait", 1748 | "bs58", 1749 | "byteorder", 1750 | "cbc", 1751 | "cfg-if", 1752 | "ctr", 1753 | "eyeball", 1754 | "futures-core", 1755 | "futures-util", 1756 | "hkdf", 1757 | "hmac", 1758 | "itertools 0.12.1", 1759 | "matrix-sdk-common", 1760 | "pbkdf2", 1761 | "rand", 1762 | "rmp-serde", 1763 | "ruma", 1764 | "serde", 1765 | "serde_json", 1766 | "sha2", 1767 | "subtle", 1768 | "thiserror", 1769 | "tokio", 1770 | "tokio-stream", 1771 | "tracing", 1772 | "ulid", 1773 | "vodozemac", 1774 | "zeroize", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "matrix-sdk-indexeddb" 1779 | version = "0.7.0" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "ad388005c5d4ed2ff38f405d52aa7fa606f4e1ab51baf5f2504721124ed4a58b" 1782 | dependencies = [ 1783 | "anyhow", 1784 | "async-trait", 1785 | "base64 0.21.7", 1786 | "getrandom", 1787 | "gloo-utils", 1788 | "indexed_db_futures", 1789 | "js-sys", 1790 | "matrix-sdk-base", 1791 | "matrix-sdk-crypto", 1792 | "matrix-sdk-store-encryption", 1793 | "ruma", 1794 | "serde", 1795 | "serde-wasm-bindgen", 1796 | "serde_json", 1797 | "thiserror", 1798 | "tokio", 1799 | "tracing", 1800 | "wasm-bindgen", 1801 | "web-sys", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "matrix-sdk-sqlite" 1806 | version = "0.7.1" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "77a98d034dd5aa85b4da6500e60c7d5b9328a37632cf40ba38bbe2c77cea3f14" 1809 | dependencies = [ 1810 | "async-trait", 1811 | "deadpool-sqlite", 1812 | "itertools 0.12.1", 1813 | "matrix-sdk-base", 1814 | "matrix-sdk-crypto", 1815 | "matrix-sdk-store-encryption", 1816 | "rmp-serde", 1817 | "ruma", 1818 | "rusqlite", 1819 | "serde", 1820 | "serde_json", 1821 | "thiserror", 1822 | "tokio", 1823 | "tracing", 1824 | "vodozemac", 1825 | ] 1826 | 1827 | [[package]] 1828 | name = "matrix-sdk-store-encryption" 1829 | version = "0.7.0" 1830 | source = "registry+https://github.com/rust-lang/crates.io-index" 1831 | checksum = "6a7e3162e9f982a4c57ab46df01a4775f697dec8899738bf62d7e97b63faa61c" 1832 | dependencies = [ 1833 | "blake3", 1834 | "chacha20poly1305", 1835 | "displaydoc", 1836 | "getrandom", 1837 | "hmac", 1838 | "pbkdf2", 1839 | "rand", 1840 | "rmp-serde", 1841 | "serde", 1842 | "serde_json", 1843 | "sha2", 1844 | "thiserror", 1845 | "zeroize", 1846 | ] 1847 | 1848 | [[package]] 1849 | name = "memchr" 1850 | version = "2.7.4" 1851 | source = "registry+https://github.com/rust-lang/crates.io-index" 1852 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1853 | 1854 | [[package]] 1855 | name = "mime" 1856 | version = "0.3.17" 1857 | source = "registry+https://github.com/rust-lang/crates.io-index" 1858 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1859 | 1860 | [[package]] 1861 | name = "mime2ext" 1862 | version = "0.1.53" 1863 | source = "registry+https://github.com/rust-lang/crates.io-index" 1864 | checksum = "515a63dc9666c865e848b043ab52fe9a5c713ae89cde4b5fbaae67cfd614b93a" 1865 | 1866 | [[package]] 1867 | name = "miniz_oxide" 1868 | version = "0.8.0" 1869 | source = "registry+https://github.com/rust-lang/crates.io-index" 1870 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 1871 | dependencies = [ 1872 | "adler2", 1873 | ] 1874 | 1875 | [[package]] 1876 | name = "mio" 1877 | version = "1.0.2" 1878 | source = "registry+https://github.com/rust-lang/crates.io-index" 1879 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1880 | dependencies = [ 1881 | "hermit-abi 0.3.9", 1882 | "libc", 1883 | "wasi", 1884 | "windows-sys 0.52.0", 1885 | ] 1886 | 1887 | [[package]] 1888 | name = "native-tls" 1889 | version = "0.2.12" 1890 | source = "registry+https://github.com/rust-lang/crates.io-index" 1891 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 1892 | dependencies = [ 1893 | "libc", 1894 | "log", 1895 | "openssl", 1896 | "openssl-probe", 1897 | "openssl-sys", 1898 | "schannel", 1899 | "security-framework", 1900 | "security-framework-sys", 1901 | "tempfile", 1902 | ] 1903 | 1904 | [[package]] 1905 | name = "nu-ansi-term" 1906 | version = "0.46.0" 1907 | source = "registry+https://github.com/rust-lang/crates.io-index" 1908 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1909 | dependencies = [ 1910 | "overload", 1911 | "winapi", 1912 | ] 1913 | 1914 | [[package]] 1915 | name = "num-traits" 1916 | version = "0.2.19" 1917 | source = "registry+https://github.com/rust-lang/crates.io-index" 1918 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1919 | dependencies = [ 1920 | "autocfg", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "num_cpus" 1925 | version = "1.16.0" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1928 | dependencies = [ 1929 | "hermit-abi 0.3.9", 1930 | "libc", 1931 | ] 1932 | 1933 | [[package]] 1934 | name = "object" 1935 | version = "0.36.4" 1936 | source = "registry+https://github.com/rust-lang/crates.io-index" 1937 | checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" 1938 | dependencies = [ 1939 | "memchr", 1940 | ] 1941 | 1942 | [[package]] 1943 | name = "once_cell" 1944 | version = "1.19.0" 1945 | source = "registry+https://github.com/rust-lang/crates.io-index" 1946 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1947 | 1948 | [[package]] 1949 | name = "opaque-debug" 1950 | version = "0.3.1" 1951 | source = "registry+https://github.com/rust-lang/crates.io-index" 1952 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 1953 | 1954 | [[package]] 1955 | name = "openssl" 1956 | version = "0.10.66" 1957 | source = "registry+https://github.com/rust-lang/crates.io-index" 1958 | checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" 1959 | dependencies = [ 1960 | "bitflags 2.6.0", 1961 | "cfg-if", 1962 | "foreign-types", 1963 | "libc", 1964 | "once_cell", 1965 | "openssl-macros", 1966 | "openssl-sys", 1967 | ] 1968 | 1969 | [[package]] 1970 | name = "openssl-macros" 1971 | version = "0.1.1" 1972 | source = "registry+https://github.com/rust-lang/crates.io-index" 1973 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1974 | dependencies = [ 1975 | "proc-macro2", 1976 | "quote", 1977 | "syn 2.0.77", 1978 | ] 1979 | 1980 | [[package]] 1981 | name = "openssl-probe" 1982 | version = "0.1.5" 1983 | source = "registry+https://github.com/rust-lang/crates.io-index" 1984 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1985 | 1986 | [[package]] 1987 | name = "openssl-sys" 1988 | version = "0.9.103" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" 1991 | dependencies = [ 1992 | "cc", 1993 | "libc", 1994 | "pkg-config", 1995 | "vcpkg", 1996 | ] 1997 | 1998 | [[package]] 1999 | name = "option-ext" 2000 | version = "0.2.0" 2001 | source = "registry+https://github.com/rust-lang/crates.io-index" 2002 | checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" 2003 | 2004 | [[package]] 2005 | name = "overload" 2006 | version = "0.1.1" 2007 | source = "registry+https://github.com/rust-lang/crates.io-index" 2008 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 2009 | 2010 | [[package]] 2011 | name = "parking" 2012 | version = "2.2.1" 2013 | source = "registry+https://github.com/rust-lang/crates.io-index" 2014 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 2015 | 2016 | [[package]] 2017 | name = "parking_lot" 2018 | version = "0.12.3" 2019 | source = "registry+https://github.com/rust-lang/crates.io-index" 2020 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 2021 | dependencies = [ 2022 | "lock_api", 2023 | "parking_lot_core", 2024 | ] 2025 | 2026 | [[package]] 2027 | name = "parking_lot_core" 2028 | version = "0.9.10" 2029 | source = "registry+https://github.com/rust-lang/crates.io-index" 2030 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 2031 | dependencies = [ 2032 | "cfg-if", 2033 | "libc", 2034 | "redox_syscall", 2035 | "smallvec", 2036 | "windows-targets 0.52.6", 2037 | ] 2038 | 2039 | [[package]] 2040 | name = "paste" 2041 | version = "1.0.15" 2042 | source = "registry+https://github.com/rust-lang/crates.io-index" 2043 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 2044 | 2045 | [[package]] 2046 | name = "pbkdf2" 2047 | version = "0.12.2" 2048 | source = "registry+https://github.com/rust-lang/crates.io-index" 2049 | checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" 2050 | dependencies = [ 2051 | "digest", 2052 | "hmac", 2053 | ] 2054 | 2055 | [[package]] 2056 | name = "percent-encoding" 2057 | version = "2.3.1" 2058 | source = "registry+https://github.com/rust-lang/crates.io-index" 2059 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 2060 | 2061 | [[package]] 2062 | name = "phf" 2063 | version = "0.11.2" 2064 | source = "registry+https://github.com/rust-lang/crates.io-index" 2065 | checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" 2066 | dependencies = [ 2067 | "phf_shared", 2068 | ] 2069 | 2070 | [[package]] 2071 | name = "phf_shared" 2072 | version = "0.11.2" 2073 | source = "registry+https://github.com/rust-lang/crates.io-index" 2074 | checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" 2075 | dependencies = [ 2076 | "siphasher", 2077 | ] 2078 | 2079 | [[package]] 2080 | name = "pin-project" 2081 | version = "1.1.5" 2082 | source = "registry+https://github.com/rust-lang/crates.io-index" 2083 | checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" 2084 | dependencies = [ 2085 | "pin-project-internal", 2086 | ] 2087 | 2088 | [[package]] 2089 | name = "pin-project-internal" 2090 | version = "1.1.5" 2091 | source = "registry+https://github.com/rust-lang/crates.io-index" 2092 | checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" 2093 | dependencies = [ 2094 | "proc-macro2", 2095 | "quote", 2096 | "syn 2.0.77", 2097 | ] 2098 | 2099 | [[package]] 2100 | name = "pin-project-lite" 2101 | version = "0.2.14" 2102 | source = "registry+https://github.com/rust-lang/crates.io-index" 2103 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 2104 | 2105 | [[package]] 2106 | name = "pin-utils" 2107 | version = "0.1.0" 2108 | source = "registry+https://github.com/rust-lang/crates.io-index" 2109 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2110 | 2111 | [[package]] 2112 | name = "pkcs7" 2113 | version = "0.4.1" 2114 | source = "registry+https://github.com/rust-lang/crates.io-index" 2115 | checksum = "d79178be066405e0602bf3035946edef6b11b3f9dde46dfe5f8bfd7dea4b77e7" 2116 | dependencies = [ 2117 | "der", 2118 | "spki", 2119 | "x509-cert", 2120 | ] 2121 | 2122 | [[package]] 2123 | name = "pkcs8" 2124 | version = "0.10.2" 2125 | source = "registry+https://github.com/rust-lang/crates.io-index" 2126 | checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" 2127 | dependencies = [ 2128 | "der", 2129 | "spki", 2130 | ] 2131 | 2132 | [[package]] 2133 | name = "pkg-config" 2134 | version = "0.3.30" 2135 | source = "registry+https://github.com/rust-lang/crates.io-index" 2136 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 2137 | 2138 | [[package]] 2139 | name = "pokem" 2140 | version = "1.1.0" 2141 | dependencies = [ 2142 | "anyhow", 2143 | "clap", 2144 | "dirs", 2145 | "emojis", 2146 | "headjack", 2147 | "http-body-util", 2148 | "hyper 1.4.1", 2149 | "hyper-util", 2150 | "is-terminal", 2151 | "lazy_static", 2152 | "matrix-sdk", 2153 | "regex", 2154 | "reqwest 0.12.7", 2155 | "serde", 2156 | "serde_json", 2157 | "serde_yaml", 2158 | "tokio", 2159 | "tracing", 2160 | "tracing-subscriber", 2161 | "url", 2162 | "urlencoding", 2163 | ] 2164 | 2165 | [[package]] 2166 | name = "poly1305" 2167 | version = "0.8.0" 2168 | source = "registry+https://github.com/rust-lang/crates.io-index" 2169 | checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" 2170 | dependencies = [ 2171 | "cpufeatures", 2172 | "opaque-debug", 2173 | "universal-hash", 2174 | ] 2175 | 2176 | [[package]] 2177 | name = "ppv-lite86" 2178 | version = "0.2.20" 2179 | source = "registry+https://github.com/rust-lang/crates.io-index" 2180 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 2181 | dependencies = [ 2182 | "zerocopy", 2183 | ] 2184 | 2185 | [[package]] 2186 | name = "proc-macro-crate" 2187 | version = "1.3.1" 2188 | source = "registry+https://github.com/rust-lang/crates.io-index" 2189 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 2190 | dependencies = [ 2191 | "once_cell", 2192 | "toml_edit 0.19.15", 2193 | ] 2194 | 2195 | [[package]] 2196 | name = "proc-macro-crate" 2197 | version = "2.0.0" 2198 | source = "registry+https://github.com/rust-lang/crates.io-index" 2199 | checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" 2200 | dependencies = [ 2201 | "toml_edit 0.20.7", 2202 | ] 2203 | 2204 | [[package]] 2205 | name = "proc-macro-crate" 2206 | version = "3.2.0" 2207 | source = "registry+https://github.com/rust-lang/crates.io-index" 2208 | checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" 2209 | dependencies = [ 2210 | "toml_edit 0.22.20", 2211 | ] 2212 | 2213 | [[package]] 2214 | name = "proc-macro-error" 2215 | version = "1.0.4" 2216 | source = "registry+https://github.com/rust-lang/crates.io-index" 2217 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 2218 | dependencies = [ 2219 | "proc-macro-error-attr", 2220 | "proc-macro2", 2221 | "quote", 2222 | "syn 1.0.109", 2223 | "version_check", 2224 | ] 2225 | 2226 | [[package]] 2227 | name = "proc-macro-error-attr" 2228 | version = "1.0.4" 2229 | source = "registry+https://github.com/rust-lang/crates.io-index" 2230 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 2231 | dependencies = [ 2232 | "proc-macro2", 2233 | "quote", 2234 | "version_check", 2235 | ] 2236 | 2237 | [[package]] 2238 | name = "proc-macro-error-attr2" 2239 | version = "2.0.0" 2240 | source = "registry+https://github.com/rust-lang/crates.io-index" 2241 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 2242 | dependencies = [ 2243 | "proc-macro2", 2244 | "quote", 2245 | ] 2246 | 2247 | [[package]] 2248 | name = "proc-macro-error2" 2249 | version = "2.0.1" 2250 | source = "registry+https://github.com/rust-lang/crates.io-index" 2251 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 2252 | dependencies = [ 2253 | "proc-macro-error-attr2", 2254 | "proc-macro2", 2255 | "quote", 2256 | ] 2257 | 2258 | [[package]] 2259 | name = "proc-macro2" 2260 | version = "1.0.86" 2261 | source = "registry+https://github.com/rust-lang/crates.io-index" 2262 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 2263 | dependencies = [ 2264 | "unicode-ident", 2265 | ] 2266 | 2267 | [[package]] 2268 | name = "prost" 2269 | version = "0.13.2" 2270 | source = "registry+https://github.com/rust-lang/crates.io-index" 2271 | checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" 2272 | dependencies = [ 2273 | "bytes", 2274 | "prost-derive", 2275 | ] 2276 | 2277 | [[package]] 2278 | name = "prost-derive" 2279 | version = "0.13.2" 2280 | source = "registry+https://github.com/rust-lang/crates.io-index" 2281 | checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" 2282 | dependencies = [ 2283 | "anyhow", 2284 | "itertools 0.13.0", 2285 | "proc-macro2", 2286 | "quote", 2287 | "syn 2.0.77", 2288 | ] 2289 | 2290 | [[package]] 2291 | name = "pulldown-cmark" 2292 | version = "0.9.6" 2293 | source = "registry+https://github.com/rust-lang/crates.io-index" 2294 | checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" 2295 | dependencies = [ 2296 | "bitflags 2.6.0", 2297 | "memchr", 2298 | "unicase", 2299 | ] 2300 | 2301 | [[package]] 2302 | name = "quote" 2303 | version = "1.0.37" 2304 | source = "registry+https://github.com/rust-lang/crates.io-index" 2305 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 2306 | dependencies = [ 2307 | "proc-macro2", 2308 | ] 2309 | 2310 | [[package]] 2311 | name = "rand" 2312 | version = "0.8.5" 2313 | source = "registry+https://github.com/rust-lang/crates.io-index" 2314 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 2315 | dependencies = [ 2316 | "libc", 2317 | "rand_chacha", 2318 | "rand_core", 2319 | ] 2320 | 2321 | [[package]] 2322 | name = "rand_chacha" 2323 | version = "0.3.1" 2324 | source = "registry+https://github.com/rust-lang/crates.io-index" 2325 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2326 | dependencies = [ 2327 | "ppv-lite86", 2328 | "rand_core", 2329 | ] 2330 | 2331 | [[package]] 2332 | name = "rand_core" 2333 | version = "0.6.4" 2334 | source = "registry+https://github.com/rust-lang/crates.io-index" 2335 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2336 | dependencies = [ 2337 | "getrandom", 2338 | ] 2339 | 2340 | [[package]] 2341 | name = "rand_xoshiro" 2342 | version = "0.6.0" 2343 | source = "registry+https://github.com/rust-lang/crates.io-index" 2344 | checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" 2345 | dependencies = [ 2346 | "rand_core", 2347 | ] 2348 | 2349 | [[package]] 2350 | name = "readlock" 2351 | version = "0.1.8" 2352 | source = "registry+https://github.com/rust-lang/crates.io-index" 2353 | checksum = "072cfe5b1d2dcd38d20e18f85e9c9978b6cc08f0b373e9f1fff1541335622974" 2354 | 2355 | [[package]] 2356 | name = "redox_syscall" 2357 | version = "0.5.4" 2358 | source = "registry+https://github.com/rust-lang/crates.io-index" 2359 | checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" 2360 | dependencies = [ 2361 | "bitflags 2.6.0", 2362 | ] 2363 | 2364 | [[package]] 2365 | name = "redox_users" 2366 | version = "0.4.6" 2367 | source = "registry+https://github.com/rust-lang/crates.io-index" 2368 | checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" 2369 | dependencies = [ 2370 | "getrandom", 2371 | "libredox", 2372 | "thiserror", 2373 | ] 2374 | 2375 | [[package]] 2376 | name = "regex" 2377 | version = "1.10.6" 2378 | source = "registry+https://github.com/rust-lang/crates.io-index" 2379 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 2380 | dependencies = [ 2381 | "aho-corasick", 2382 | "memchr", 2383 | "regex-automata", 2384 | "regex-syntax", 2385 | ] 2386 | 2387 | [[package]] 2388 | name = "regex-automata" 2389 | version = "0.4.7" 2390 | source = "registry+https://github.com/rust-lang/crates.io-index" 2391 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 2392 | dependencies = [ 2393 | "aho-corasick", 2394 | "memchr", 2395 | "regex-syntax", 2396 | ] 2397 | 2398 | [[package]] 2399 | name = "regex-syntax" 2400 | version = "0.8.4" 2401 | source = "registry+https://github.com/rust-lang/crates.io-index" 2402 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 2403 | 2404 | [[package]] 2405 | name = "reqwest" 2406 | version = "0.11.27" 2407 | source = "registry+https://github.com/rust-lang/crates.io-index" 2408 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" 2409 | dependencies = [ 2410 | "base64 0.21.7", 2411 | "bytes", 2412 | "encoding_rs", 2413 | "futures-core", 2414 | "futures-util", 2415 | "h2 0.3.26", 2416 | "http 0.2.12", 2417 | "http-body 0.4.6", 2418 | "hyper 0.14.30", 2419 | "hyper-tls 0.5.0", 2420 | "ipnet", 2421 | "js-sys", 2422 | "log", 2423 | "mime", 2424 | "native-tls", 2425 | "once_cell", 2426 | "percent-encoding", 2427 | "pin-project-lite", 2428 | "rustls-pemfile 1.0.4", 2429 | "serde", 2430 | "serde_json", 2431 | "serde_urlencoded", 2432 | "sync_wrapper 0.1.2", 2433 | "system-configuration 0.5.1", 2434 | "tokio", 2435 | "tokio-native-tls", 2436 | "tokio-util", 2437 | "tower-service", 2438 | "url", 2439 | "wasm-bindgen", 2440 | "wasm-bindgen-futures", 2441 | "wasm-streams", 2442 | "web-sys", 2443 | "winreg", 2444 | ] 2445 | 2446 | [[package]] 2447 | name = "reqwest" 2448 | version = "0.12.7" 2449 | source = "registry+https://github.com/rust-lang/crates.io-index" 2450 | checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" 2451 | dependencies = [ 2452 | "base64 0.22.1", 2453 | "bytes", 2454 | "encoding_rs", 2455 | "futures-core", 2456 | "futures-util", 2457 | "h2 0.4.6", 2458 | "http 1.1.0", 2459 | "http-body 1.0.1", 2460 | "http-body-util", 2461 | "hyper 1.4.1", 2462 | "hyper-rustls", 2463 | "hyper-tls 0.6.0", 2464 | "hyper-util", 2465 | "ipnet", 2466 | "js-sys", 2467 | "log", 2468 | "mime", 2469 | "native-tls", 2470 | "once_cell", 2471 | "percent-encoding", 2472 | "pin-project-lite", 2473 | "rustls-pemfile 2.1.3", 2474 | "serde", 2475 | "serde_json", 2476 | "serde_urlencoded", 2477 | "sync_wrapper 1.0.1", 2478 | "system-configuration 0.6.1", 2479 | "tokio", 2480 | "tokio-native-tls", 2481 | "tower-service", 2482 | "url", 2483 | "wasm-bindgen", 2484 | "wasm-bindgen-futures", 2485 | "web-sys", 2486 | "windows-registry", 2487 | ] 2488 | 2489 | [[package]] 2490 | name = "ring" 2491 | version = "0.17.8" 2492 | source = "registry+https://github.com/rust-lang/crates.io-index" 2493 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 2494 | dependencies = [ 2495 | "cc", 2496 | "cfg-if", 2497 | "getrandom", 2498 | "libc", 2499 | "spin", 2500 | "untrusted", 2501 | "windows-sys 0.52.0", 2502 | ] 2503 | 2504 | [[package]] 2505 | name = "rmp" 2506 | version = "0.8.14" 2507 | source = "registry+https://github.com/rust-lang/crates.io-index" 2508 | checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" 2509 | dependencies = [ 2510 | "byteorder", 2511 | "num-traits", 2512 | "paste", 2513 | ] 2514 | 2515 | [[package]] 2516 | name = "rmp-serde" 2517 | version = "1.3.0" 2518 | source = "registry+https://github.com/rust-lang/crates.io-index" 2519 | checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" 2520 | dependencies = [ 2521 | "byteorder", 2522 | "rmp", 2523 | "serde", 2524 | ] 2525 | 2526 | [[package]] 2527 | name = "ruma" 2528 | version = "0.9.4" 2529 | source = "registry+https://github.com/rust-lang/crates.io-index" 2530 | checksum = "2779c38df072964c63476259d9300efb07d0d1a7178c6469893636ce0c547a36" 2531 | dependencies = [ 2532 | "assign", 2533 | "js_int", 2534 | "js_option", 2535 | "ruma-client-api", 2536 | "ruma-common", 2537 | "ruma-events", 2538 | "ruma-federation-api", 2539 | ] 2540 | 2541 | [[package]] 2542 | name = "ruma-client-api" 2543 | version = "0.17.4" 2544 | source = "registry+https://github.com/rust-lang/crates.io-index" 2545 | checksum = "641837258fa214a70823477514954ef0f5d3bc6ae8e1d5d85081856a33103386" 2546 | dependencies = [ 2547 | "assign", 2548 | "bytes", 2549 | "http 0.2.12", 2550 | "js_int", 2551 | "js_option", 2552 | "maplit", 2553 | "ruma-common", 2554 | "ruma-events", 2555 | "serde", 2556 | "serde_html_form", 2557 | "serde_json", 2558 | ] 2559 | 2560 | [[package]] 2561 | name = "ruma-common" 2562 | version = "0.12.1" 2563 | source = "registry+https://github.com/rust-lang/crates.io-index" 2564 | checksum = "3bca4c33c50e47b4cdceeac71bdef0c04153b0e29aa992d9030ec14a62323e85" 2565 | dependencies = [ 2566 | "as_variant", 2567 | "base64 0.21.7", 2568 | "bytes", 2569 | "form_urlencoded", 2570 | "getrandom", 2571 | "http 0.2.12", 2572 | "indexmap", 2573 | "js-sys", 2574 | "js_int", 2575 | "konst", 2576 | "percent-encoding", 2577 | "rand", 2578 | "regex", 2579 | "ruma-identifiers-validation", 2580 | "ruma-macros", 2581 | "serde", 2582 | "serde_html_form", 2583 | "serde_json", 2584 | "thiserror", 2585 | "tracing", 2586 | "url", 2587 | "uuid", 2588 | "wildmatch", 2589 | ] 2590 | 2591 | [[package]] 2592 | name = "ruma-events" 2593 | version = "0.27.11" 2594 | source = "registry+https://github.com/rust-lang/crates.io-index" 2595 | checksum = "d20a52770e5a9fb30b7a1c14ba8b3dcf76dadc01674e58e40094f78e6bd5e3f1" 2596 | dependencies = [ 2597 | "as_variant", 2598 | "indexmap", 2599 | "js_int", 2600 | "js_option", 2601 | "percent-encoding", 2602 | "pulldown-cmark", 2603 | "regex", 2604 | "ruma-common", 2605 | "ruma-identifiers-validation", 2606 | "ruma-macros", 2607 | "serde", 2608 | "serde_json", 2609 | "thiserror", 2610 | "tracing", 2611 | "url", 2612 | "wildmatch", 2613 | ] 2614 | 2615 | [[package]] 2616 | name = "ruma-federation-api" 2617 | version = "0.8.0" 2618 | source = "registry+https://github.com/rust-lang/crates.io-index" 2619 | checksum = "e1901c1f27bc327652d58af2a130c73acef3198abeccd24cee97f7267fdf3fe7" 2620 | dependencies = [ 2621 | "js_int", 2622 | "ruma-common", 2623 | "ruma-events", 2624 | "serde", 2625 | "serde_json", 2626 | ] 2627 | 2628 | [[package]] 2629 | name = "ruma-identifiers-validation" 2630 | version = "0.9.5" 2631 | source = "registry+https://github.com/rust-lang/crates.io-index" 2632 | checksum = "9fa38974f5901ed4e00e10aec57b9ad3b4d6d6c1a1ae683c51b88700b9f4ffba" 2633 | dependencies = [ 2634 | "js_int", 2635 | "thiserror", 2636 | ] 2637 | 2638 | [[package]] 2639 | name = "ruma-macros" 2640 | version = "0.12.0" 2641 | source = "registry+https://github.com/rust-lang/crates.io-index" 2642 | checksum = "0280534a4b3e34416f883285fac4f9c408cd0b737890ae66f3e7a7056d14be80" 2643 | dependencies = [ 2644 | "once_cell", 2645 | "proc-macro-crate 2.0.0", 2646 | "proc-macro2", 2647 | "quote", 2648 | "ruma-identifiers-validation", 2649 | "serde", 2650 | "syn 2.0.77", 2651 | "toml", 2652 | ] 2653 | 2654 | [[package]] 2655 | name = "rusqlite" 2656 | version = "0.30.0" 2657 | source = "registry+https://github.com/rust-lang/crates.io-index" 2658 | checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" 2659 | dependencies = [ 2660 | "bitflags 2.6.0", 2661 | "fallible-iterator", 2662 | "fallible-streaming-iterator", 2663 | "hashlink", 2664 | "libsqlite3-sys", 2665 | "smallvec", 2666 | ] 2667 | 2668 | [[package]] 2669 | name = "rustc-demangle" 2670 | version = "0.1.24" 2671 | source = "registry+https://github.com/rust-lang/crates.io-index" 2672 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 2673 | 2674 | [[package]] 2675 | name = "rustc_version" 2676 | version = "0.4.1" 2677 | source = "registry+https://github.com/rust-lang/crates.io-index" 2678 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 2679 | dependencies = [ 2680 | "semver", 2681 | ] 2682 | 2683 | [[package]] 2684 | name = "rustix" 2685 | version = "0.38.37" 2686 | source = "registry+https://github.com/rust-lang/crates.io-index" 2687 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 2688 | dependencies = [ 2689 | "bitflags 2.6.0", 2690 | "errno", 2691 | "libc", 2692 | "linux-raw-sys", 2693 | "windows-sys 0.52.0", 2694 | ] 2695 | 2696 | [[package]] 2697 | name = "rustls" 2698 | version = "0.23.13" 2699 | source = "registry+https://github.com/rust-lang/crates.io-index" 2700 | checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" 2701 | dependencies = [ 2702 | "once_cell", 2703 | "rustls-pki-types", 2704 | "rustls-webpki", 2705 | "subtle", 2706 | "zeroize", 2707 | ] 2708 | 2709 | [[package]] 2710 | name = "rustls-pemfile" 2711 | version = "1.0.4" 2712 | source = "registry+https://github.com/rust-lang/crates.io-index" 2713 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 2714 | dependencies = [ 2715 | "base64 0.21.7", 2716 | ] 2717 | 2718 | [[package]] 2719 | name = "rustls-pemfile" 2720 | version = "2.1.3" 2721 | source = "registry+https://github.com/rust-lang/crates.io-index" 2722 | checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" 2723 | dependencies = [ 2724 | "base64 0.22.1", 2725 | "rustls-pki-types", 2726 | ] 2727 | 2728 | [[package]] 2729 | name = "rustls-pki-types" 2730 | version = "1.8.0" 2731 | source = "registry+https://github.com/rust-lang/crates.io-index" 2732 | checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" 2733 | 2734 | [[package]] 2735 | name = "rustls-webpki" 2736 | version = "0.102.8" 2737 | source = "registry+https://github.com/rust-lang/crates.io-index" 2738 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 2739 | dependencies = [ 2740 | "ring", 2741 | "rustls-pki-types", 2742 | "untrusted", 2743 | ] 2744 | 2745 | [[package]] 2746 | name = "ryu" 2747 | version = "1.0.18" 2748 | source = "registry+https://github.com/rust-lang/crates.io-index" 2749 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 2750 | 2751 | [[package]] 2752 | name = "schannel" 2753 | version = "0.1.24" 2754 | source = "registry+https://github.com/rust-lang/crates.io-index" 2755 | checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" 2756 | dependencies = [ 2757 | "windows-sys 0.59.0", 2758 | ] 2759 | 2760 | [[package]] 2761 | name = "scopeguard" 2762 | version = "1.2.0" 2763 | source = "registry+https://github.com/rust-lang/crates.io-index" 2764 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 2765 | 2766 | [[package]] 2767 | name = "security-framework" 2768 | version = "2.11.1" 2769 | source = "registry+https://github.com/rust-lang/crates.io-index" 2770 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 2771 | dependencies = [ 2772 | "bitflags 2.6.0", 2773 | "core-foundation", 2774 | "core-foundation-sys", 2775 | "libc", 2776 | "security-framework-sys", 2777 | ] 2778 | 2779 | [[package]] 2780 | name = "security-framework-sys" 2781 | version = "2.11.1" 2782 | source = "registry+https://github.com/rust-lang/crates.io-index" 2783 | checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" 2784 | dependencies = [ 2785 | "core-foundation-sys", 2786 | "libc", 2787 | ] 2788 | 2789 | [[package]] 2790 | name = "semver" 2791 | version = "1.0.23" 2792 | source = "registry+https://github.com/rust-lang/crates.io-index" 2793 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 2794 | 2795 | [[package]] 2796 | name = "serde" 2797 | version = "1.0.210" 2798 | source = "registry+https://github.com/rust-lang/crates.io-index" 2799 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 2800 | dependencies = [ 2801 | "serde_derive", 2802 | ] 2803 | 2804 | [[package]] 2805 | name = "serde-wasm-bindgen" 2806 | version = "0.6.5" 2807 | source = "registry+https://github.com/rust-lang/crates.io-index" 2808 | checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" 2809 | dependencies = [ 2810 | "js-sys", 2811 | "serde", 2812 | "wasm-bindgen", 2813 | ] 2814 | 2815 | [[package]] 2816 | name = "serde_bytes" 2817 | version = "0.11.15" 2818 | source = "registry+https://github.com/rust-lang/crates.io-index" 2819 | checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" 2820 | dependencies = [ 2821 | "serde", 2822 | ] 2823 | 2824 | [[package]] 2825 | name = "serde_derive" 2826 | version = "1.0.210" 2827 | source = "registry+https://github.com/rust-lang/crates.io-index" 2828 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 2829 | dependencies = [ 2830 | "proc-macro2", 2831 | "quote", 2832 | "syn 2.0.77", 2833 | ] 2834 | 2835 | [[package]] 2836 | name = "serde_html_form" 2837 | version = "0.2.6" 2838 | source = "registry+https://github.com/rust-lang/crates.io-index" 2839 | checksum = "8de514ef58196f1fc96dcaef80fe6170a1ce6215df9687a93fe8300e773fefc5" 2840 | dependencies = [ 2841 | "form_urlencoded", 2842 | "indexmap", 2843 | "itoa", 2844 | "ryu", 2845 | "serde", 2846 | ] 2847 | 2848 | [[package]] 2849 | name = "serde_json" 2850 | version = "1.0.128" 2851 | source = "registry+https://github.com/rust-lang/crates.io-index" 2852 | checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" 2853 | dependencies = [ 2854 | "itoa", 2855 | "memchr", 2856 | "ryu", 2857 | "serde", 2858 | ] 2859 | 2860 | [[package]] 2861 | name = "serde_spanned" 2862 | version = "0.6.7" 2863 | source = "registry+https://github.com/rust-lang/crates.io-index" 2864 | checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" 2865 | dependencies = [ 2866 | "serde", 2867 | ] 2868 | 2869 | [[package]] 2870 | name = "serde_urlencoded" 2871 | version = "0.7.1" 2872 | source = "registry+https://github.com/rust-lang/crates.io-index" 2873 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 2874 | dependencies = [ 2875 | "form_urlencoded", 2876 | "itoa", 2877 | "ryu", 2878 | "serde", 2879 | ] 2880 | 2881 | [[package]] 2882 | name = "serde_yaml" 2883 | version = "0.9.34+deprecated" 2884 | source = "registry+https://github.com/rust-lang/crates.io-index" 2885 | checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" 2886 | dependencies = [ 2887 | "indexmap", 2888 | "itoa", 2889 | "ryu", 2890 | "serde", 2891 | "unsafe-libyaml", 2892 | ] 2893 | 2894 | [[package]] 2895 | name = "sha2" 2896 | version = "0.10.8" 2897 | source = "registry+https://github.com/rust-lang/crates.io-index" 2898 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 2899 | dependencies = [ 2900 | "cfg-if", 2901 | "cpufeatures", 2902 | "digest", 2903 | ] 2904 | 2905 | [[package]] 2906 | name = "sharded-slab" 2907 | version = "0.1.7" 2908 | source = "registry+https://github.com/rust-lang/crates.io-index" 2909 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 2910 | dependencies = [ 2911 | "lazy_static", 2912 | ] 2913 | 2914 | [[package]] 2915 | name = "shlex" 2916 | version = "1.3.0" 2917 | source = "registry+https://github.com/rust-lang/crates.io-index" 2918 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 2919 | 2920 | [[package]] 2921 | name = "signal-hook-registry" 2922 | version = "1.4.2" 2923 | source = "registry+https://github.com/rust-lang/crates.io-index" 2924 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 2925 | dependencies = [ 2926 | "libc", 2927 | ] 2928 | 2929 | [[package]] 2930 | name = "signature" 2931 | version = "2.2.0" 2932 | source = "registry+https://github.com/rust-lang/crates.io-index" 2933 | checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" 2934 | dependencies = [ 2935 | "rand_core", 2936 | ] 2937 | 2938 | [[package]] 2939 | name = "siphasher" 2940 | version = "0.3.11" 2941 | source = "registry+https://github.com/rust-lang/crates.io-index" 2942 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 2943 | 2944 | [[package]] 2945 | name = "slab" 2946 | version = "0.4.9" 2947 | source = "registry+https://github.com/rust-lang/crates.io-index" 2948 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2949 | dependencies = [ 2950 | "autocfg", 2951 | ] 2952 | 2953 | [[package]] 2954 | name = "smallvec" 2955 | version = "1.13.2" 2956 | source = "registry+https://github.com/rust-lang/crates.io-index" 2957 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 2958 | 2959 | [[package]] 2960 | name = "socket2" 2961 | version = "0.5.7" 2962 | source = "registry+https://github.com/rust-lang/crates.io-index" 2963 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 2964 | dependencies = [ 2965 | "libc", 2966 | "windows-sys 0.52.0", 2967 | ] 2968 | 2969 | [[package]] 2970 | name = "spin" 2971 | version = "0.9.8" 2972 | source = "registry+https://github.com/rust-lang/crates.io-index" 2973 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 2974 | 2975 | [[package]] 2976 | name = "spki" 2977 | version = "0.7.3" 2978 | source = "registry+https://github.com/rust-lang/crates.io-index" 2979 | checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" 2980 | dependencies = [ 2981 | "base64ct", 2982 | "der", 2983 | ] 2984 | 2985 | [[package]] 2986 | name = "strsim" 2987 | version = "0.11.1" 2988 | source = "registry+https://github.com/rust-lang/crates.io-index" 2989 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2990 | 2991 | [[package]] 2992 | name = "subtle" 2993 | version = "2.6.1" 2994 | source = "registry+https://github.com/rust-lang/crates.io-index" 2995 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 2996 | 2997 | [[package]] 2998 | name = "syn" 2999 | version = "1.0.109" 3000 | source = "registry+https://github.com/rust-lang/crates.io-index" 3001 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 3002 | dependencies = [ 3003 | "proc-macro2", 3004 | "quote", 3005 | "unicode-ident", 3006 | ] 3007 | 3008 | [[package]] 3009 | name = "syn" 3010 | version = "2.0.77" 3011 | source = "registry+https://github.com/rust-lang/crates.io-index" 3012 | checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" 3013 | dependencies = [ 3014 | "proc-macro2", 3015 | "quote", 3016 | "unicode-ident", 3017 | ] 3018 | 3019 | [[package]] 3020 | name = "sync_wrapper" 3021 | version = "0.1.2" 3022 | source = "registry+https://github.com/rust-lang/crates.io-index" 3023 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 3024 | 3025 | [[package]] 3026 | name = "sync_wrapper" 3027 | version = "1.0.1" 3028 | source = "registry+https://github.com/rust-lang/crates.io-index" 3029 | checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 3030 | dependencies = [ 3031 | "futures-core", 3032 | ] 3033 | 3034 | [[package]] 3035 | name = "system-configuration" 3036 | version = "0.5.1" 3037 | source = "registry+https://github.com/rust-lang/crates.io-index" 3038 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 3039 | dependencies = [ 3040 | "bitflags 1.3.2", 3041 | "core-foundation", 3042 | "system-configuration-sys 0.5.0", 3043 | ] 3044 | 3045 | [[package]] 3046 | name = "system-configuration" 3047 | version = "0.6.1" 3048 | source = "registry+https://github.com/rust-lang/crates.io-index" 3049 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 3050 | dependencies = [ 3051 | "bitflags 2.6.0", 3052 | "core-foundation", 3053 | "system-configuration-sys 0.6.0", 3054 | ] 3055 | 3056 | [[package]] 3057 | name = "system-configuration-sys" 3058 | version = "0.5.0" 3059 | source = "registry+https://github.com/rust-lang/crates.io-index" 3060 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 3061 | dependencies = [ 3062 | "core-foundation-sys", 3063 | "libc", 3064 | ] 3065 | 3066 | [[package]] 3067 | name = "system-configuration-sys" 3068 | version = "0.6.0" 3069 | source = "registry+https://github.com/rust-lang/crates.io-index" 3070 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 3071 | dependencies = [ 3072 | "core-foundation-sys", 3073 | "libc", 3074 | ] 3075 | 3076 | [[package]] 3077 | name = "tempfile" 3078 | version = "3.12.0" 3079 | source = "registry+https://github.com/rust-lang/crates.io-index" 3080 | checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" 3081 | dependencies = [ 3082 | "cfg-if", 3083 | "fastrand", 3084 | "once_cell", 3085 | "rustix", 3086 | "windows-sys 0.59.0", 3087 | ] 3088 | 3089 | [[package]] 3090 | name = "thiserror" 3091 | version = "1.0.63" 3092 | source = "registry+https://github.com/rust-lang/crates.io-index" 3093 | checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" 3094 | dependencies = [ 3095 | "thiserror-impl", 3096 | ] 3097 | 3098 | [[package]] 3099 | name = "thiserror-impl" 3100 | version = "1.0.63" 3101 | source = "registry+https://github.com/rust-lang/crates.io-index" 3102 | checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" 3103 | dependencies = [ 3104 | "proc-macro2", 3105 | "quote", 3106 | "syn 2.0.77", 3107 | ] 3108 | 3109 | [[package]] 3110 | name = "thread_local" 3111 | version = "1.1.8" 3112 | source = "registry+https://github.com/rust-lang/crates.io-index" 3113 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 3114 | dependencies = [ 3115 | "cfg-if", 3116 | "once_cell", 3117 | ] 3118 | 3119 | [[package]] 3120 | name = "tinyvec" 3121 | version = "1.8.0" 3122 | source = "registry+https://github.com/rust-lang/crates.io-index" 3123 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 3124 | dependencies = [ 3125 | "tinyvec_macros", 3126 | ] 3127 | 3128 | [[package]] 3129 | name = "tinyvec_macros" 3130 | version = "0.1.1" 3131 | source = "registry+https://github.com/rust-lang/crates.io-index" 3132 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 3133 | 3134 | [[package]] 3135 | name = "tokio" 3136 | version = "1.40.0" 3137 | source = "registry+https://github.com/rust-lang/crates.io-index" 3138 | checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" 3139 | dependencies = [ 3140 | "backtrace", 3141 | "bytes", 3142 | "libc", 3143 | "mio", 3144 | "parking_lot", 3145 | "pin-project-lite", 3146 | "signal-hook-registry", 3147 | "socket2", 3148 | "tokio-macros", 3149 | "windows-sys 0.52.0", 3150 | ] 3151 | 3152 | [[package]] 3153 | name = "tokio-macros" 3154 | version = "2.4.0" 3155 | source = "registry+https://github.com/rust-lang/crates.io-index" 3156 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 3157 | dependencies = [ 3158 | "proc-macro2", 3159 | "quote", 3160 | "syn 2.0.77", 3161 | ] 3162 | 3163 | [[package]] 3164 | name = "tokio-native-tls" 3165 | version = "0.3.1" 3166 | source = "registry+https://github.com/rust-lang/crates.io-index" 3167 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 3168 | dependencies = [ 3169 | "native-tls", 3170 | "tokio", 3171 | ] 3172 | 3173 | [[package]] 3174 | name = "tokio-rustls" 3175 | version = "0.26.0" 3176 | source = "registry+https://github.com/rust-lang/crates.io-index" 3177 | checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" 3178 | dependencies = [ 3179 | "rustls", 3180 | "rustls-pki-types", 3181 | "tokio", 3182 | ] 3183 | 3184 | [[package]] 3185 | name = "tokio-stream" 3186 | version = "0.1.16" 3187 | source = "registry+https://github.com/rust-lang/crates.io-index" 3188 | checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" 3189 | dependencies = [ 3190 | "futures-core", 3191 | "pin-project-lite", 3192 | "tokio", 3193 | "tokio-util", 3194 | ] 3195 | 3196 | [[package]] 3197 | name = "tokio-util" 3198 | version = "0.7.12" 3199 | source = "registry+https://github.com/rust-lang/crates.io-index" 3200 | checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" 3201 | dependencies = [ 3202 | "bytes", 3203 | "futures-core", 3204 | "futures-sink", 3205 | "pin-project-lite", 3206 | "tokio", 3207 | ] 3208 | 3209 | [[package]] 3210 | name = "toml" 3211 | version = "0.8.19" 3212 | source = "registry+https://github.com/rust-lang/crates.io-index" 3213 | checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" 3214 | dependencies = [ 3215 | "serde", 3216 | "serde_spanned", 3217 | "toml_datetime", 3218 | "toml_edit 0.22.20", 3219 | ] 3220 | 3221 | [[package]] 3222 | name = "toml_datetime" 3223 | version = "0.6.8" 3224 | source = "registry+https://github.com/rust-lang/crates.io-index" 3225 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 3226 | dependencies = [ 3227 | "serde", 3228 | ] 3229 | 3230 | [[package]] 3231 | name = "toml_edit" 3232 | version = "0.19.15" 3233 | source = "registry+https://github.com/rust-lang/crates.io-index" 3234 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 3235 | dependencies = [ 3236 | "indexmap", 3237 | "toml_datetime", 3238 | "winnow 0.5.40", 3239 | ] 3240 | 3241 | [[package]] 3242 | name = "toml_edit" 3243 | version = "0.20.7" 3244 | source = "registry+https://github.com/rust-lang/crates.io-index" 3245 | checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" 3246 | dependencies = [ 3247 | "indexmap", 3248 | "toml_datetime", 3249 | "winnow 0.5.40", 3250 | ] 3251 | 3252 | [[package]] 3253 | name = "toml_edit" 3254 | version = "0.22.20" 3255 | source = "registry+https://github.com/rust-lang/crates.io-index" 3256 | checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" 3257 | dependencies = [ 3258 | "indexmap", 3259 | "serde", 3260 | "serde_spanned", 3261 | "toml_datetime", 3262 | "winnow 0.6.18", 3263 | ] 3264 | 3265 | [[package]] 3266 | name = "tower" 3267 | version = "0.4.13" 3268 | source = "registry+https://github.com/rust-lang/crates.io-index" 3269 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 3270 | dependencies = [ 3271 | "futures-core", 3272 | "futures-util", 3273 | "pin-project", 3274 | "pin-project-lite", 3275 | "tokio", 3276 | "tower-layer", 3277 | "tower-service", 3278 | ] 3279 | 3280 | [[package]] 3281 | name = "tower-layer" 3282 | version = "0.3.3" 3283 | source = "registry+https://github.com/rust-lang/crates.io-index" 3284 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 3285 | 3286 | [[package]] 3287 | name = "tower-service" 3288 | version = "0.3.3" 3289 | source = "registry+https://github.com/rust-lang/crates.io-index" 3290 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 3291 | 3292 | [[package]] 3293 | name = "tracing" 3294 | version = "0.1.40" 3295 | source = "registry+https://github.com/rust-lang/crates.io-index" 3296 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 3297 | dependencies = [ 3298 | "pin-project-lite", 3299 | "tracing-attributes", 3300 | "tracing-core", 3301 | ] 3302 | 3303 | [[package]] 3304 | name = "tracing-attributes" 3305 | version = "0.1.27" 3306 | source = "registry+https://github.com/rust-lang/crates.io-index" 3307 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 3308 | dependencies = [ 3309 | "proc-macro2", 3310 | "quote", 3311 | "syn 2.0.77", 3312 | ] 3313 | 3314 | [[package]] 3315 | name = "tracing-core" 3316 | version = "0.1.32" 3317 | source = "registry+https://github.com/rust-lang/crates.io-index" 3318 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 3319 | dependencies = [ 3320 | "once_cell", 3321 | "valuable", 3322 | ] 3323 | 3324 | [[package]] 3325 | name = "tracing-log" 3326 | version = "0.2.0" 3327 | source = "registry+https://github.com/rust-lang/crates.io-index" 3328 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 3329 | dependencies = [ 3330 | "log", 3331 | "once_cell", 3332 | "tracing-core", 3333 | ] 3334 | 3335 | [[package]] 3336 | name = "tracing-subscriber" 3337 | version = "0.3.18" 3338 | source = "registry+https://github.com/rust-lang/crates.io-index" 3339 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 3340 | dependencies = [ 3341 | "nu-ansi-term", 3342 | "sharded-slab", 3343 | "smallvec", 3344 | "thread_local", 3345 | "tracing-core", 3346 | "tracing-log", 3347 | ] 3348 | 3349 | [[package]] 3350 | name = "try-lock" 3351 | version = "0.2.5" 3352 | source = "registry+https://github.com/rust-lang/crates.io-index" 3353 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 3354 | 3355 | [[package]] 3356 | name = "typenum" 3357 | version = "1.17.0" 3358 | source = "registry+https://github.com/rust-lang/crates.io-index" 3359 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 3360 | 3361 | [[package]] 3362 | name = "typewit" 3363 | version = "1.9.0" 3364 | source = "registry+https://github.com/rust-lang/crates.io-index" 3365 | checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" 3366 | dependencies = [ 3367 | "typewit_proc_macros", 3368 | ] 3369 | 3370 | [[package]] 3371 | name = "typewit_proc_macros" 3372 | version = "1.8.1" 3373 | source = "registry+https://github.com/rust-lang/crates.io-index" 3374 | checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" 3375 | 3376 | [[package]] 3377 | name = "ulid" 3378 | version = "1.1.3" 3379 | source = "registry+https://github.com/rust-lang/crates.io-index" 3380 | checksum = "04f903f293d11f31c0c29e4148f6dc0d033a7f80cebc0282bea147611667d289" 3381 | dependencies = [ 3382 | "getrandom", 3383 | "rand", 3384 | "web-time", 3385 | ] 3386 | 3387 | [[package]] 3388 | name = "unicase" 3389 | version = "2.7.0" 3390 | source = "registry+https://github.com/rust-lang/crates.io-index" 3391 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 3392 | dependencies = [ 3393 | "version_check", 3394 | ] 3395 | 3396 | [[package]] 3397 | name = "unicode-bidi" 3398 | version = "0.3.15" 3399 | source = "registry+https://github.com/rust-lang/crates.io-index" 3400 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 3401 | 3402 | [[package]] 3403 | name = "unicode-ident" 3404 | version = "1.0.13" 3405 | source = "registry+https://github.com/rust-lang/crates.io-index" 3406 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 3407 | 3408 | [[package]] 3409 | name = "unicode-normalization" 3410 | version = "0.1.23" 3411 | source = "registry+https://github.com/rust-lang/crates.io-index" 3412 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 3413 | dependencies = [ 3414 | "tinyvec", 3415 | ] 3416 | 3417 | [[package]] 3418 | name = "universal-hash" 3419 | version = "0.5.1" 3420 | source = "registry+https://github.com/rust-lang/crates.io-index" 3421 | checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" 3422 | dependencies = [ 3423 | "crypto-common", 3424 | "subtle", 3425 | ] 3426 | 3427 | [[package]] 3428 | name = "unsafe-libyaml" 3429 | version = "0.2.11" 3430 | source = "registry+https://github.com/rust-lang/crates.io-index" 3431 | checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" 3432 | 3433 | [[package]] 3434 | name = "untrusted" 3435 | version = "0.9.0" 3436 | source = "registry+https://github.com/rust-lang/crates.io-index" 3437 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 3438 | 3439 | [[package]] 3440 | name = "url" 3441 | version = "2.5.2" 3442 | source = "registry+https://github.com/rust-lang/crates.io-index" 3443 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" 3444 | dependencies = [ 3445 | "form_urlencoded", 3446 | "idna", 3447 | "percent-encoding", 3448 | ] 3449 | 3450 | [[package]] 3451 | name = "urlencoding" 3452 | version = "2.1.3" 3453 | source = "registry+https://github.com/rust-lang/crates.io-index" 3454 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 3455 | 3456 | [[package]] 3457 | name = "utf8parse" 3458 | version = "0.2.2" 3459 | source = "registry+https://github.com/rust-lang/crates.io-index" 3460 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 3461 | 3462 | [[package]] 3463 | name = "uuid" 3464 | version = "1.10.0" 3465 | source = "registry+https://github.com/rust-lang/crates.io-index" 3466 | checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" 3467 | dependencies = [ 3468 | "getrandom", 3469 | "wasm-bindgen", 3470 | ] 3471 | 3472 | [[package]] 3473 | name = "valuable" 3474 | version = "0.1.0" 3475 | source = "registry+https://github.com/rust-lang/crates.io-index" 3476 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 3477 | 3478 | [[package]] 3479 | name = "vcpkg" 3480 | version = "0.2.15" 3481 | source = "registry+https://github.com/rust-lang/crates.io-index" 3482 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 3483 | 3484 | [[package]] 3485 | name = "version_check" 3486 | version = "0.9.5" 3487 | source = "registry+https://github.com/rust-lang/crates.io-index" 3488 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 3489 | 3490 | [[package]] 3491 | name = "vodozemac" 3492 | version = "0.7.0" 3493 | source = "registry+https://github.com/rust-lang/crates.io-index" 3494 | checksum = "051d4af70b53b42adf2aac459a305851b8d754f210aaf11ab509e1065beff422" 3495 | dependencies = [ 3496 | "aes", 3497 | "arrayvec", 3498 | "base64 0.22.1", 3499 | "base64ct", 3500 | "cbc", 3501 | "chacha20poly1305", 3502 | "curve25519-dalek", 3503 | "ed25519-dalek", 3504 | "getrandom", 3505 | "hkdf", 3506 | "hmac", 3507 | "matrix-pickle", 3508 | "pkcs7", 3509 | "prost", 3510 | "rand", 3511 | "serde", 3512 | "serde_bytes", 3513 | "serde_json", 3514 | "sha2", 3515 | "subtle", 3516 | "thiserror", 3517 | "x25519-dalek", 3518 | "zeroize", 3519 | ] 3520 | 3521 | [[package]] 3522 | name = "want" 3523 | version = "0.3.1" 3524 | source = "registry+https://github.com/rust-lang/crates.io-index" 3525 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 3526 | dependencies = [ 3527 | "try-lock", 3528 | ] 3529 | 3530 | [[package]] 3531 | name = "wasi" 3532 | version = "0.11.0+wasi-snapshot-preview1" 3533 | source = "registry+https://github.com/rust-lang/crates.io-index" 3534 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 3535 | 3536 | [[package]] 3537 | name = "wasm-bindgen" 3538 | version = "0.2.93" 3539 | source = "registry+https://github.com/rust-lang/crates.io-index" 3540 | checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" 3541 | dependencies = [ 3542 | "cfg-if", 3543 | "once_cell", 3544 | "wasm-bindgen-macro", 3545 | ] 3546 | 3547 | [[package]] 3548 | name = "wasm-bindgen-backend" 3549 | version = "0.2.93" 3550 | source = "registry+https://github.com/rust-lang/crates.io-index" 3551 | checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" 3552 | dependencies = [ 3553 | "bumpalo", 3554 | "log", 3555 | "once_cell", 3556 | "proc-macro2", 3557 | "quote", 3558 | "syn 2.0.77", 3559 | "wasm-bindgen-shared", 3560 | ] 3561 | 3562 | [[package]] 3563 | name = "wasm-bindgen-futures" 3564 | version = "0.4.43" 3565 | source = "registry+https://github.com/rust-lang/crates.io-index" 3566 | checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" 3567 | dependencies = [ 3568 | "cfg-if", 3569 | "js-sys", 3570 | "wasm-bindgen", 3571 | "web-sys", 3572 | ] 3573 | 3574 | [[package]] 3575 | name = "wasm-bindgen-macro" 3576 | version = "0.2.93" 3577 | source = "registry+https://github.com/rust-lang/crates.io-index" 3578 | checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" 3579 | dependencies = [ 3580 | "quote", 3581 | "wasm-bindgen-macro-support", 3582 | ] 3583 | 3584 | [[package]] 3585 | name = "wasm-bindgen-macro-support" 3586 | version = "0.2.93" 3587 | source = "registry+https://github.com/rust-lang/crates.io-index" 3588 | checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" 3589 | dependencies = [ 3590 | "proc-macro2", 3591 | "quote", 3592 | "syn 2.0.77", 3593 | "wasm-bindgen-backend", 3594 | "wasm-bindgen-shared", 3595 | ] 3596 | 3597 | [[package]] 3598 | name = "wasm-bindgen-shared" 3599 | version = "0.2.93" 3600 | source = "registry+https://github.com/rust-lang/crates.io-index" 3601 | checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" 3602 | 3603 | [[package]] 3604 | name = "wasm-streams" 3605 | version = "0.4.0" 3606 | source = "registry+https://github.com/rust-lang/crates.io-index" 3607 | checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" 3608 | dependencies = [ 3609 | "futures-util", 3610 | "js-sys", 3611 | "wasm-bindgen", 3612 | "wasm-bindgen-futures", 3613 | "web-sys", 3614 | ] 3615 | 3616 | [[package]] 3617 | name = "web-sys" 3618 | version = "0.3.70" 3619 | source = "registry+https://github.com/rust-lang/crates.io-index" 3620 | checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" 3621 | dependencies = [ 3622 | "js-sys", 3623 | "wasm-bindgen", 3624 | ] 3625 | 3626 | [[package]] 3627 | name = "web-time" 3628 | version = "1.1.0" 3629 | source = "registry+https://github.com/rust-lang/crates.io-index" 3630 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 3631 | dependencies = [ 3632 | "js-sys", 3633 | "wasm-bindgen", 3634 | ] 3635 | 3636 | [[package]] 3637 | name = "wildmatch" 3638 | version = "2.3.4" 3639 | source = "registry+https://github.com/rust-lang/crates.io-index" 3640 | checksum = "3928939971918220fed093266b809d1ee4ec6c1a2d72692ff6876898f3b16c19" 3641 | 3642 | [[package]] 3643 | name = "winapi" 3644 | version = "0.3.9" 3645 | source = "registry+https://github.com/rust-lang/crates.io-index" 3646 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 3647 | dependencies = [ 3648 | "winapi-i686-pc-windows-gnu", 3649 | "winapi-x86_64-pc-windows-gnu", 3650 | ] 3651 | 3652 | [[package]] 3653 | name = "winapi-i686-pc-windows-gnu" 3654 | version = "0.4.0" 3655 | source = "registry+https://github.com/rust-lang/crates.io-index" 3656 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3657 | 3658 | [[package]] 3659 | name = "winapi-x86_64-pc-windows-gnu" 3660 | version = "0.4.0" 3661 | source = "registry+https://github.com/rust-lang/crates.io-index" 3662 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 3663 | 3664 | [[package]] 3665 | name = "windows-registry" 3666 | version = "0.2.0" 3667 | source = "registry+https://github.com/rust-lang/crates.io-index" 3668 | checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" 3669 | dependencies = [ 3670 | "windows-result", 3671 | "windows-strings", 3672 | "windows-targets 0.52.6", 3673 | ] 3674 | 3675 | [[package]] 3676 | name = "windows-result" 3677 | version = "0.2.0" 3678 | source = "registry+https://github.com/rust-lang/crates.io-index" 3679 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 3680 | dependencies = [ 3681 | "windows-targets 0.52.6", 3682 | ] 3683 | 3684 | [[package]] 3685 | name = "windows-strings" 3686 | version = "0.1.0" 3687 | source = "registry+https://github.com/rust-lang/crates.io-index" 3688 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 3689 | dependencies = [ 3690 | "windows-result", 3691 | "windows-targets 0.52.6", 3692 | ] 3693 | 3694 | [[package]] 3695 | name = "windows-sys" 3696 | version = "0.48.0" 3697 | source = "registry+https://github.com/rust-lang/crates.io-index" 3698 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 3699 | dependencies = [ 3700 | "windows-targets 0.48.5", 3701 | ] 3702 | 3703 | [[package]] 3704 | name = "windows-sys" 3705 | version = "0.52.0" 3706 | source = "registry+https://github.com/rust-lang/crates.io-index" 3707 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 3708 | dependencies = [ 3709 | "windows-targets 0.52.6", 3710 | ] 3711 | 3712 | [[package]] 3713 | name = "windows-sys" 3714 | version = "0.59.0" 3715 | source = "registry+https://github.com/rust-lang/crates.io-index" 3716 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 3717 | dependencies = [ 3718 | "windows-targets 0.52.6", 3719 | ] 3720 | 3721 | [[package]] 3722 | name = "windows-targets" 3723 | version = "0.48.5" 3724 | source = "registry+https://github.com/rust-lang/crates.io-index" 3725 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 3726 | dependencies = [ 3727 | "windows_aarch64_gnullvm 0.48.5", 3728 | "windows_aarch64_msvc 0.48.5", 3729 | "windows_i686_gnu 0.48.5", 3730 | "windows_i686_msvc 0.48.5", 3731 | "windows_x86_64_gnu 0.48.5", 3732 | "windows_x86_64_gnullvm 0.48.5", 3733 | "windows_x86_64_msvc 0.48.5", 3734 | ] 3735 | 3736 | [[package]] 3737 | name = "windows-targets" 3738 | version = "0.52.6" 3739 | source = "registry+https://github.com/rust-lang/crates.io-index" 3740 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 3741 | dependencies = [ 3742 | "windows_aarch64_gnullvm 0.52.6", 3743 | "windows_aarch64_msvc 0.52.6", 3744 | "windows_i686_gnu 0.52.6", 3745 | "windows_i686_gnullvm", 3746 | "windows_i686_msvc 0.52.6", 3747 | "windows_x86_64_gnu 0.52.6", 3748 | "windows_x86_64_gnullvm 0.52.6", 3749 | "windows_x86_64_msvc 0.52.6", 3750 | ] 3751 | 3752 | [[package]] 3753 | name = "windows_aarch64_gnullvm" 3754 | version = "0.48.5" 3755 | source = "registry+https://github.com/rust-lang/crates.io-index" 3756 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 3757 | 3758 | [[package]] 3759 | name = "windows_aarch64_gnullvm" 3760 | version = "0.52.6" 3761 | source = "registry+https://github.com/rust-lang/crates.io-index" 3762 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 3763 | 3764 | [[package]] 3765 | name = "windows_aarch64_msvc" 3766 | version = "0.48.5" 3767 | source = "registry+https://github.com/rust-lang/crates.io-index" 3768 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 3769 | 3770 | [[package]] 3771 | name = "windows_aarch64_msvc" 3772 | version = "0.52.6" 3773 | source = "registry+https://github.com/rust-lang/crates.io-index" 3774 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 3775 | 3776 | [[package]] 3777 | name = "windows_i686_gnu" 3778 | version = "0.48.5" 3779 | source = "registry+https://github.com/rust-lang/crates.io-index" 3780 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 3781 | 3782 | [[package]] 3783 | name = "windows_i686_gnu" 3784 | version = "0.52.6" 3785 | source = "registry+https://github.com/rust-lang/crates.io-index" 3786 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 3787 | 3788 | [[package]] 3789 | name = "windows_i686_gnullvm" 3790 | version = "0.52.6" 3791 | source = "registry+https://github.com/rust-lang/crates.io-index" 3792 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 3793 | 3794 | [[package]] 3795 | name = "windows_i686_msvc" 3796 | version = "0.48.5" 3797 | source = "registry+https://github.com/rust-lang/crates.io-index" 3798 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 3799 | 3800 | [[package]] 3801 | name = "windows_i686_msvc" 3802 | version = "0.52.6" 3803 | source = "registry+https://github.com/rust-lang/crates.io-index" 3804 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 3805 | 3806 | [[package]] 3807 | name = "windows_x86_64_gnu" 3808 | version = "0.48.5" 3809 | source = "registry+https://github.com/rust-lang/crates.io-index" 3810 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 3811 | 3812 | [[package]] 3813 | name = "windows_x86_64_gnu" 3814 | version = "0.52.6" 3815 | source = "registry+https://github.com/rust-lang/crates.io-index" 3816 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 3817 | 3818 | [[package]] 3819 | name = "windows_x86_64_gnullvm" 3820 | version = "0.48.5" 3821 | source = "registry+https://github.com/rust-lang/crates.io-index" 3822 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 3823 | 3824 | [[package]] 3825 | name = "windows_x86_64_gnullvm" 3826 | version = "0.52.6" 3827 | source = "registry+https://github.com/rust-lang/crates.io-index" 3828 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 3829 | 3830 | [[package]] 3831 | name = "windows_x86_64_msvc" 3832 | version = "0.48.5" 3833 | source = "registry+https://github.com/rust-lang/crates.io-index" 3834 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 3835 | 3836 | [[package]] 3837 | name = "windows_x86_64_msvc" 3838 | version = "0.52.6" 3839 | source = "registry+https://github.com/rust-lang/crates.io-index" 3840 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 3841 | 3842 | [[package]] 3843 | name = "winnow" 3844 | version = "0.5.40" 3845 | source = "registry+https://github.com/rust-lang/crates.io-index" 3846 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 3847 | dependencies = [ 3848 | "memchr", 3849 | ] 3850 | 3851 | [[package]] 3852 | name = "winnow" 3853 | version = "0.6.18" 3854 | source = "registry+https://github.com/rust-lang/crates.io-index" 3855 | checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" 3856 | dependencies = [ 3857 | "memchr", 3858 | ] 3859 | 3860 | [[package]] 3861 | name = "winreg" 3862 | version = "0.50.0" 3863 | source = "registry+https://github.com/rust-lang/crates.io-index" 3864 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 3865 | dependencies = [ 3866 | "cfg-if", 3867 | "windows-sys 0.48.0", 3868 | ] 3869 | 3870 | [[package]] 3871 | name = "x25519-dalek" 3872 | version = "2.0.1" 3873 | source = "registry+https://github.com/rust-lang/crates.io-index" 3874 | checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" 3875 | dependencies = [ 3876 | "curve25519-dalek", 3877 | "rand_core", 3878 | "serde", 3879 | "zeroize", 3880 | ] 3881 | 3882 | [[package]] 3883 | name = "x509-cert" 3884 | version = "0.2.5" 3885 | source = "registry+https://github.com/rust-lang/crates.io-index" 3886 | checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" 3887 | dependencies = [ 3888 | "const-oid", 3889 | "der", 3890 | "spki", 3891 | ] 3892 | 3893 | [[package]] 3894 | name = "zerocopy" 3895 | version = "0.7.35" 3896 | source = "registry+https://github.com/rust-lang/crates.io-index" 3897 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 3898 | dependencies = [ 3899 | "byteorder", 3900 | "zerocopy-derive", 3901 | ] 3902 | 3903 | [[package]] 3904 | name = "zerocopy-derive" 3905 | version = "0.7.35" 3906 | source = "registry+https://github.com/rust-lang/crates.io-index" 3907 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 3908 | dependencies = [ 3909 | "proc-macro2", 3910 | "quote", 3911 | "syn 2.0.77", 3912 | ] 3913 | 3914 | [[package]] 3915 | name = "zeroize" 3916 | version = "1.8.1" 3917 | source = "registry+https://github.com/rust-lang/crates.io-index" 3918 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 3919 | dependencies = [ 3920 | "zeroize_derive", 3921 | ] 3922 | 3923 | [[package]] 3924 | name = "zeroize_derive" 3925 | version = "1.4.2" 3926 | source = "registry+https://github.com/rust-lang/crates.io-index" 3927 | checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" 3928 | dependencies = [ 3929 | "proc-macro2", 3930 | "quote", 3931 | "syn 2.0.77", 3932 | ] 3933 | --------------------------------------------------------------------------------