├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── analytics-extension ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── poetry.lock ├── pyproject.toml ├── s3-admin-app ├── __init__.py ├── authorizer_python │ ├── __init__.py │ ├── app.py │ └── requirements.txt ├── authorizer_rust │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── get-s3-details-node │ ├── .npmignore │ ├── app.mjs │ └── package.json ├── list-buckets-node │ ├── .npmignore │ ├── app.mjs │ ├── package-lock.json │ └── package.json ├── list-buckets-rust-node │ ├── .gitignore │ ├── .npmignore │ ├── app.mjs │ ├── index.d.ts │ ├── index.js │ ├── package-lock.json │ └── package.json ├── list_buckets_python │ ├── __init__.py │ ├── app.py │ └── requirements.txt ├── list_buckets_rust_python │ ├── __init__.py │ ├── app.py │ └── requirements.txt ├── samconfig.toml └── template.yaml ├── s3-ops-rust-napi-lib ├── .gitignore ├── .npmignore ├── .yarn │ └── releases │ │ └── yarn-4.0.2.cjs ├── .yarnrc.yml ├── Cargo.toml ├── build.rs ├── index.d.ts ├── index.js ├── npm │ ├── linux-arm64-gnu │ │ ├── README.md │ │ └── package.json │ └── linux-x64-gnu │ │ ├── README.md │ │ └── package.json ├── package.json ├── rustfmt.toml ├── src │ └── lib.rs └── yarn.lock └── s3-ops-rust-pyo3-lib ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── pyproject.toml ├── s3_ops_rust.pyi └── src └── lib.rs /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/rust:latest 2 | 3 | RUN sudo apt-get update 4 | 5 | RUN echo 'bind '\''"\e[A": history-search-backward'\' >> /etc/bash.bashrc 6 | RUN echo 'bind '\''"\e[B": history-search-forward'\' >> /etc/bash.bashrc 7 | RUN echo 'alias ll="ls -l"' >> /etc/bash.bashrc 8 | ARG USERNAME=vscode 9 | RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \ 10 | && mkdir /commandhistory \ 11 | && touch /commandhistory/.bash_history \ 12 | && chown -R $USERNAME /commandhistory \ 13 | && echo "$SNIPPET" >> "/home/$USERNAME/.bashrc" 14 | 15 | # Install Python 16 | RUN curl https://pyenv.run | bash 17 | ENV PYENV_ROOT /root/.pyenv 18 | ENV PATH $PYENV_ROOT/bin:$PATH 19 | 20 | RUN pyenv install 3.11 && pyenv global 3.11 21 | 22 | # Continue with Rust 23 | RUN curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin 24 | RUN wget https://github.com/mozilla/grcov/releases/download/v0.8.18/grcov-x86_64-unknown-linux-gnu.tar.bz2 && tar -xvjf grcov-x86_64-unknown-linux-gnu.tar.bz2 -C /usr/local/bin 25 | RUN rustup component add llvm-tools-preview 26 | RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash 27 | RUN cargo install cargo-audit && cargo install cargo-edit 28 | 29 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "dockerfile": "Dockerfile" 4 | }, 5 | "features": { 6 | "ghcr.io/devcontainers/features/aws-cli:1": {}, 7 | "ghcr.io/devcontainers-contrib/features/poetry:2": {}, 8 | "ghcr.io/devcontainers/features/rust:1": {}, 9 | "ghcr.io/customink/codespaces-features/sam-cli:1": {}, 10 | "ghcr.io/devcontainers/features/node:1": {} 11 | 12 | }, 13 | "mounts": [ 14 | "source=projectname-bashhistory,target=/commandhistory,type=volume", 15 | "source=${localEnv:HOME}/.aws,target=/home/vscode/.aws,type=bind,consistency=cached", 16 | "source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind" 17 | ], 18 | "onCreateCommand": { 19 | "install-poe": "pipx install poethepoet", 20 | "install-napi": "npm install -g @napi-rs/cli" 21 | } 22 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | .aws-sam 163 | .rust-lib 164 | .rust-napi-lib 165 | 166 | # Rust 167 | # Generated by Cargo 168 | # will have compiled files and executables 169 | debug/ 170 | target/ 171 | 172 | # These are backup files generated by rustfmt 173 | **/*.rs.bk 174 | 175 | # MSVC Windows builds of rustc generate these, which store debugging information 176 | *.pdb 177 | 178 | # Code coveragte 179 | *.profraw 180 | cobertura.xml 181 | 182 | # homebrew 183 | dist 184 | 185 | node_modules/ 186 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[python]": { 3 | "editor.defaultFormatter": "ms-python.black-formatter" 4 | }, 5 | "python.formatting.provider": "none", 6 | "rust-analyzer.linkedProjects": [ 7 | "s3-ops-rust-pyo3-lib/Cargo.toml", 8 | "s3-admin-app/authorizer_rust/Cargo.toml", 9 | "analytics-extension/Cargo.toml", 10 | "s3-ops-rust-napi-lib/Cargo.toml" 11 | ] 12 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # “Rustifying” serverless: Boost AWS Lambda performance with Rust (COM306) 2 | 3 | ## Introduction 4 | This repository serves as a companion to my talk at AWS ReInvent. The talk, titled "“Rustifying” serverless: Boost AWS Lambda performance with Rust", explores how to leverage the performance advantages of Rust in serverless AWS Lambda functions. For more details and to watch the talk, visit [ReInvent Talk](https://www.youtube.com/watch?v=Mdh_2PXe9i8). 5 | 6 | ## Background Story 7 | ### The Journey 8 | - As a company focused on developing AWS management tools, we started with a Minimum Viable Product (MVP) for S3 bucket management. 9 | - Initially, the product was open only to our most loyal customers, and we received overwhelmingly positive feedback. 10 | - Eventually, we opened the product to all of our users. 11 | - At its peak, the service catered to thousands of clients and tens of thousands of users. 12 | 13 | ### Challenges 14 | - We started experiencing performance bottlenecks and increased IT spending. 15 | - Major architectural changes like adding cache and improving algorithms were implemented. 16 | 17 | ### The Decision 18 | - We reached a point where our existing runtime, Python, was not sufficient for our performance needs. 19 | - Thus, we decided to leverage Rust for its performance advantages. 20 | 21 | This repository illustrates the journey that led us to this point. 22 | 23 | ## Architecture 24 | ![Architecture Diagram](https://github.com/fun-with-serverless/rustifying-serverless/assets/110536677/7950f8d2-1e80-4681-8938-339ef6b203f6) 25 | 26 | - The architecture consists of an API Gateway with a Lambda authorizer. 27 | - Multiple Lambda functions are connected to the API Gateway. These functions interact with services like S3 and DynamoDB. 28 | - We have multiple runtimes, mostly Python, but also NodeJS. 29 | 30 | ## Ways to Integrate Rust into Your Serverless Workload 31 | There are primarily three ways to integrate Rust: 32 | 33 | ### 1. Rust Bindings 34 | #### Python 35 | - Use Pyo3 with maturin to create a `.whl` package for use in your Python Lambda. 36 | - Example code can be found under [s3-ops-rust-pyo3-lib](./s3-ops-rust-pyo3-lib). 37 | 38 | #### NodeJS 39 | - Use NAPI-RS to package and build your code. A one stop CLI, unlike Python where you need to use teo tools. 40 | - Examples can be found under [s3-ops-rust-napi-lib](./s3-ops-rust-napi-lib). 41 | 42 | **Benefits**: Speed of development and no need to rewrite the Lambda function. 43 | 44 | ### 2. Rewrite the Lambda 45 | - Use `cargo-lambda` and AWS SAM to deploy a full-fledged Rust Lambda. 46 | - Example code can be found under [s3-admin-app/authorizer_rust](./s3-admin-app/authorizer_rust). 47 | - **Benefits**: Reduced cold starts, thanks to the Rust runtime. 48 | 49 | ### 3. Use Extensions 50 | - Use extensions to address cross-cutting concerns, such as analytics reporting, using a fast language like Rust. 51 | - Example code can be found under [analytics-extension](./analytics-extension). 52 | - **Benefits**: Reduce Lambda latency by offloading tasks to an external process. 53 | 54 | ## Building the Example 55 | - This example comes with a devcontainer for both Rust and Python development. 56 | - In case you are not using DevContainers, make sure you have the following prerequisites: 57 | - Python 3.11 58 | - Rust - latest version 59 | - Poetry 60 | - Poe 61 | - AWS SAM 62 | - NodeJS 20 63 | - AWS CLI 64 | - NAPI-RS 65 | - Prepare the NodeJS Rust Library by running: 66 | ``` 67 | cd s3-ops-rust-napi-lib 68 | npm i 69 | ``` 70 | - We use `poetry` for build management. To build and deploy, run: 71 | ```bash 72 | # Install dev tools used for rust compilation. 73 | poetry install --only=rust-dev-tools 74 | # Build the rust package 75 | poe build-python-lib 76 | poe build-node-lib 77 | # Build and deploy the extension 78 | poe build-and-deploy-extension 79 | ``` 80 | - Update [s3-asmin-app/template.yaml](./s3-admin-app/template.yaml) with the ARN of the extension under `Globals/Layers`. 81 | - Build the application and deploy it - `poe build-and-deploy-app` 82 | - To create a new user in the 'users' table, follow the AWS SAM output. For example `aws dynamodb put-item --table-name ...` 83 | - Make API calls to the various APIs as defined in the AWS SAM output. 84 | 85 | ## Local development 86 | The main application resides in `s3-admin-app`, Rust bindings are in `s3-ops-rust-lib` and the extension in `analytics-extension`. 87 | ```bash 88 | # Install dev tools used for rust compilation. 89 | poetry install --only=rust-dev-tools 90 | # Build the rust package 91 | poe build-python-lib 92 | poe build-node-lib 93 | # Add the local rust package 94 | poetry add .rust-lib/s3_ops_rust-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl --group dev 95 | poetry install 96 | ``` 97 | -------------------------------------------------------------------------------- /analytics-extension/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 = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "analytics-extension" 31 | version = "0.1.0" 32 | dependencies = [ 33 | "aws-config", 34 | "aws-sdk-sqs", 35 | "axum", 36 | "lambda-extension", 37 | "serde", 38 | "serde_json", 39 | "tokio", 40 | "tokio-stream", 41 | "tracing", 42 | "tracing-subscriber", 43 | ] 44 | 45 | [[package]] 46 | name = "android-tzdata" 47 | version = "0.1.1" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 50 | 51 | [[package]] 52 | name = "android_system_properties" 53 | version = "0.1.5" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 56 | dependencies = [ 57 | "libc", 58 | ] 59 | 60 | [[package]] 61 | name = "async-stream" 62 | version = "0.3.5" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 65 | dependencies = [ 66 | "async-stream-impl", 67 | "futures-core", 68 | "pin-project-lite", 69 | ] 70 | 71 | [[package]] 72 | name = "async-stream-impl" 73 | version = "0.3.5" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 76 | dependencies = [ 77 | "proc-macro2", 78 | "quote", 79 | "syn", 80 | ] 81 | 82 | [[package]] 83 | name = "async-trait" 84 | version = "0.1.73" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" 87 | dependencies = [ 88 | "proc-macro2", 89 | "quote", 90 | "syn", 91 | ] 92 | 93 | [[package]] 94 | name = "autocfg" 95 | version = "1.1.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 98 | 99 | [[package]] 100 | name = "aws-config" 101 | version = "0.56.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "fc6b3804dca60326e07205179847f17a4fce45af3a1106939177ad41ac08a6de" 104 | dependencies = [ 105 | "aws-credential-types", 106 | "aws-http", 107 | "aws-sdk-sso", 108 | "aws-sdk-sts", 109 | "aws-smithy-async", 110 | "aws-smithy-client", 111 | "aws-smithy-http", 112 | "aws-smithy-http-tower", 113 | "aws-smithy-json", 114 | "aws-smithy-types", 115 | "aws-types", 116 | "bytes", 117 | "fastrand", 118 | "hex", 119 | "http", 120 | "hyper", 121 | "ring", 122 | "time", 123 | "tokio", 124 | "tower", 125 | "tracing", 126 | "zeroize", 127 | ] 128 | 129 | [[package]] 130 | name = "aws-credential-types" 131 | version = "0.56.1" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "70a66ac8ef5fa9cf01c2d999f39d16812e90ec1467bd382cbbb74ba23ea86201" 134 | dependencies = [ 135 | "aws-smithy-async", 136 | "aws-smithy-types", 137 | "fastrand", 138 | "tokio", 139 | "tracing", 140 | "zeroize", 141 | ] 142 | 143 | [[package]] 144 | name = "aws-http" 145 | version = "0.56.1" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "3e626370f9ba806ae4c439e49675fd871f5767b093075cdf4fef16cac42ba900" 148 | dependencies = [ 149 | "aws-credential-types", 150 | "aws-smithy-http", 151 | "aws-smithy-types", 152 | "aws-types", 153 | "bytes", 154 | "http", 155 | "http-body", 156 | "lazy_static", 157 | "percent-encoding", 158 | "pin-project-lite", 159 | "tracing", 160 | ] 161 | 162 | [[package]] 163 | name = "aws-runtime" 164 | version = "0.56.1" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "07ac5cf0ff19c1bca0cea7932e11b239d1025a45696a4f44f72ea86e2b8bdd07" 167 | dependencies = [ 168 | "aws-credential-types", 169 | "aws-http", 170 | "aws-sigv4", 171 | "aws-smithy-async", 172 | "aws-smithy-http", 173 | "aws-smithy-runtime-api", 174 | "aws-smithy-types", 175 | "aws-types", 176 | "fastrand", 177 | "http", 178 | "percent-encoding", 179 | "tracing", 180 | "uuid", 181 | ] 182 | 183 | [[package]] 184 | name = "aws-sdk-sqs" 185 | version = "0.30.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "d5165c11d0b552d035ad753f48a2b7f2f152eec18a7667a9f7906ef2fc2a14be" 188 | dependencies = [ 189 | "aws-credential-types", 190 | "aws-http", 191 | "aws-runtime", 192 | "aws-smithy-async", 193 | "aws-smithy-client", 194 | "aws-smithy-http", 195 | "aws-smithy-json", 196 | "aws-smithy-query", 197 | "aws-smithy-runtime", 198 | "aws-smithy-runtime-api", 199 | "aws-smithy-types", 200 | "aws-smithy-xml", 201 | "aws-types", 202 | "http", 203 | "regex", 204 | "tokio-stream", 205 | "tracing", 206 | ] 207 | 208 | [[package]] 209 | name = "aws-sdk-sso" 210 | version = "0.30.0" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "903f888ff190e64f6f5c83fb0f8d54f9c20481f1dc26359bb8896f5d99908949" 213 | dependencies = [ 214 | "aws-credential-types", 215 | "aws-http", 216 | "aws-runtime", 217 | "aws-smithy-async", 218 | "aws-smithy-client", 219 | "aws-smithy-http", 220 | "aws-smithy-json", 221 | "aws-smithy-runtime", 222 | "aws-smithy-runtime-api", 223 | "aws-smithy-types", 224 | "aws-types", 225 | "bytes", 226 | "http", 227 | "regex", 228 | "tokio-stream", 229 | "tracing", 230 | ] 231 | 232 | [[package]] 233 | name = "aws-sdk-sts" 234 | version = "0.30.0" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "a47ad6bf01afc00423d781d464220bf69fb6a674ad6629cbbcb06d88cdc2be82" 237 | dependencies = [ 238 | "aws-credential-types", 239 | "aws-http", 240 | "aws-runtime", 241 | "aws-smithy-async", 242 | "aws-smithy-client", 243 | "aws-smithy-http", 244 | "aws-smithy-json", 245 | "aws-smithy-query", 246 | "aws-smithy-runtime", 247 | "aws-smithy-runtime-api", 248 | "aws-smithy-types", 249 | "aws-smithy-xml", 250 | "aws-types", 251 | "http", 252 | "regex", 253 | "tracing", 254 | ] 255 | 256 | [[package]] 257 | name = "aws-sigv4" 258 | version = "0.56.1" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "b7b28f4910bb956b7ab320b62e98096402354eca976c587d1eeccd523d9bac03" 261 | dependencies = [ 262 | "aws-smithy-http", 263 | "form_urlencoded", 264 | "hex", 265 | "hmac", 266 | "http", 267 | "once_cell", 268 | "percent-encoding", 269 | "regex", 270 | "sha2", 271 | "time", 272 | "tracing", 273 | ] 274 | 275 | [[package]] 276 | name = "aws-smithy-async" 277 | version = "0.56.1" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "2cdb73f85528b9d19c23a496034ac53703955a59323d581c06aa27b4e4e247af" 280 | dependencies = [ 281 | "futures-util", 282 | "pin-project-lite", 283 | "tokio", 284 | "tokio-stream", 285 | ] 286 | 287 | [[package]] 288 | name = "aws-smithy-client" 289 | version = "0.56.1" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "c27b2756264c82f830a91cb4d2d485b2d19ad5bea476d9a966e03d27f27ba59a" 292 | dependencies = [ 293 | "aws-smithy-async", 294 | "aws-smithy-http", 295 | "aws-smithy-http-tower", 296 | "aws-smithy-types", 297 | "bytes", 298 | "fastrand", 299 | "http", 300 | "http-body", 301 | "hyper", 302 | "hyper-rustls", 303 | "lazy_static", 304 | "pin-project-lite", 305 | "rustls", 306 | "tokio", 307 | "tower", 308 | "tracing", 309 | ] 310 | 311 | [[package]] 312 | name = "aws-smithy-http" 313 | version = "0.56.1" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "54cdcf365d8eee60686885f750a34c190e513677db58bbc466c44c588abf4199" 316 | dependencies = [ 317 | "aws-smithy-types", 318 | "bytes", 319 | "bytes-utils", 320 | "futures-core", 321 | "http", 322 | "http-body", 323 | "hyper", 324 | "once_cell", 325 | "percent-encoding", 326 | "pin-project-lite", 327 | "pin-utils", 328 | "tokio", 329 | "tokio-util", 330 | "tracing", 331 | ] 332 | 333 | [[package]] 334 | name = "aws-smithy-http-tower" 335 | version = "0.56.1" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "822de399d0ce62829a69dfa8c5cd08efdbe61a7426b953e2268f8b8b52a607bd" 338 | dependencies = [ 339 | "aws-smithy-http", 340 | "aws-smithy-types", 341 | "bytes", 342 | "http", 343 | "http-body", 344 | "pin-project-lite", 345 | "tower", 346 | "tracing", 347 | ] 348 | 349 | [[package]] 350 | name = "aws-smithy-json" 351 | version = "0.56.1" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "4fb1e7ab8fa7ad10c193af7ae56d2420989e9f4758bf03601a342573333ea34f" 354 | dependencies = [ 355 | "aws-smithy-types", 356 | ] 357 | 358 | [[package]] 359 | name = "aws-smithy-query" 360 | version = "0.56.1" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "28556a3902091c1f768a34f6c998028921bdab8d47d92586f363f14a4a32d047" 363 | dependencies = [ 364 | "aws-smithy-types", 365 | "urlencoding", 366 | ] 367 | 368 | [[package]] 369 | name = "aws-smithy-runtime" 370 | version = "0.56.1" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "745e096b3553e7e0f40622aa04971ce52765af82bebdeeac53aa6fc82fe801e6" 373 | dependencies = [ 374 | "aws-smithy-async", 375 | "aws-smithy-client", 376 | "aws-smithy-http", 377 | "aws-smithy-runtime-api", 378 | "aws-smithy-types", 379 | "bytes", 380 | "fastrand", 381 | "http", 382 | "http-body", 383 | "once_cell", 384 | "pin-project-lite", 385 | "pin-utils", 386 | "tokio", 387 | "tracing", 388 | ] 389 | 390 | [[package]] 391 | name = "aws-smithy-runtime-api" 392 | version = "0.56.1" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "93d0ae0c9cfd57944e9711ea610b48a963fb174a53aabacc08c5794a594b1d02" 395 | dependencies = [ 396 | "aws-smithy-async", 397 | "aws-smithy-http", 398 | "aws-smithy-types", 399 | "bytes", 400 | "http", 401 | "tokio", 402 | "tracing", 403 | ] 404 | 405 | [[package]] 406 | name = "aws-smithy-types" 407 | version = "0.56.1" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "d90dbc8da2f6be461fa3c1906b20af8f79d14968fe47f2b7d29d086f62a51728" 410 | dependencies = [ 411 | "base64-simd", 412 | "itoa", 413 | "num-integer", 414 | "ryu", 415 | "serde", 416 | "time", 417 | ] 418 | 419 | [[package]] 420 | name = "aws-smithy-xml" 421 | version = "0.56.1" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "e01d2dedcdd8023043716cfeeb3c6c59f2d447fce365d8e194838891794b23b6" 424 | dependencies = [ 425 | "xmlparser", 426 | ] 427 | 428 | [[package]] 429 | name = "aws-types" 430 | version = "0.56.1" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "85aa0451bf8af1bf22a4f028d5d28054507a14be43cb8ac0597a8471fba9edfe" 433 | dependencies = [ 434 | "aws-credential-types", 435 | "aws-smithy-async", 436 | "aws-smithy-client", 437 | "aws-smithy-http", 438 | "aws-smithy-types", 439 | "http", 440 | "rustc_version", 441 | "tracing", 442 | ] 443 | 444 | [[package]] 445 | name = "axum" 446 | version = "0.6.20" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" 449 | dependencies = [ 450 | "async-trait", 451 | "axum-core", 452 | "bitflags", 453 | "bytes", 454 | "futures-util", 455 | "http", 456 | "http-body", 457 | "hyper", 458 | "itoa", 459 | "matchit", 460 | "memchr", 461 | "mime", 462 | "percent-encoding", 463 | "pin-project-lite", 464 | "rustversion", 465 | "serde", 466 | "serde_json", 467 | "serde_path_to_error", 468 | "sync_wrapper", 469 | "tokio", 470 | "tower", 471 | "tower-layer", 472 | "tower-service", 473 | ] 474 | 475 | [[package]] 476 | name = "axum-core" 477 | version = "0.3.4" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" 480 | dependencies = [ 481 | "async-trait", 482 | "bytes", 483 | "futures-util", 484 | "http", 485 | "http-body", 486 | "mime", 487 | "rustversion", 488 | "tower-layer", 489 | "tower-service", 490 | ] 491 | 492 | [[package]] 493 | name = "backtrace" 494 | version = "0.3.69" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 497 | dependencies = [ 498 | "addr2line", 499 | "cc", 500 | "cfg-if", 501 | "libc", 502 | "miniz_oxide", 503 | "object", 504 | "rustc-demangle", 505 | ] 506 | 507 | [[package]] 508 | name = "base64" 509 | version = "0.21.4" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" 512 | 513 | [[package]] 514 | name = "base64-simd" 515 | version = "0.8.0" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" 518 | dependencies = [ 519 | "outref", 520 | "vsimd", 521 | ] 522 | 523 | [[package]] 524 | name = "bitflags" 525 | version = "1.3.2" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 528 | 529 | [[package]] 530 | name = "block-buffer" 531 | version = "0.10.4" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 534 | dependencies = [ 535 | "generic-array", 536 | ] 537 | 538 | [[package]] 539 | name = "bumpalo" 540 | version = "3.14.0" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 543 | 544 | [[package]] 545 | name = "bytes" 546 | version = "1.5.0" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 549 | 550 | [[package]] 551 | name = "bytes-utils" 552 | version = "0.1.3" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "e47d3a8076e283f3acd27400535992edb3ba4b5bb72f8891ad8fbe7932a7d4b9" 555 | dependencies = [ 556 | "bytes", 557 | "either", 558 | ] 559 | 560 | [[package]] 561 | name = "cc" 562 | version = "1.0.83" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 565 | dependencies = [ 566 | "libc", 567 | ] 568 | 569 | [[package]] 570 | name = "cfg-if" 571 | version = "1.0.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 574 | 575 | [[package]] 576 | name = "chrono" 577 | version = "0.4.31" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" 580 | dependencies = [ 581 | "android-tzdata", 582 | "iana-time-zone", 583 | "js-sys", 584 | "num-traits", 585 | "serde", 586 | "wasm-bindgen", 587 | "windows-targets", 588 | ] 589 | 590 | [[package]] 591 | name = "core-foundation" 592 | version = "0.9.3" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 595 | dependencies = [ 596 | "core-foundation-sys", 597 | "libc", 598 | ] 599 | 600 | [[package]] 601 | name = "core-foundation-sys" 602 | version = "0.8.4" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 605 | 606 | [[package]] 607 | name = "cpufeatures" 608 | version = "0.2.9" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 611 | dependencies = [ 612 | "libc", 613 | ] 614 | 615 | [[package]] 616 | name = "crypto-common" 617 | version = "0.1.6" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 620 | dependencies = [ 621 | "generic-array", 622 | "typenum", 623 | ] 624 | 625 | [[package]] 626 | name = "deranged" 627 | version = "0.3.8" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" 630 | 631 | [[package]] 632 | name = "digest" 633 | version = "0.10.7" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 636 | dependencies = [ 637 | "block-buffer", 638 | "crypto-common", 639 | "subtle", 640 | ] 641 | 642 | [[package]] 643 | name = "either" 644 | version = "1.9.0" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 647 | 648 | [[package]] 649 | name = "fastrand" 650 | version = "2.0.0" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" 653 | 654 | [[package]] 655 | name = "fnv" 656 | version = "1.0.7" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 659 | 660 | [[package]] 661 | name = "form_urlencoded" 662 | version = "1.2.0" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 665 | dependencies = [ 666 | "percent-encoding", 667 | ] 668 | 669 | [[package]] 670 | name = "futures-channel" 671 | version = "0.3.28" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 674 | dependencies = [ 675 | "futures-core", 676 | ] 677 | 678 | [[package]] 679 | name = "futures-core" 680 | version = "0.3.28" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 683 | 684 | [[package]] 685 | name = "futures-macro" 686 | version = "0.3.28" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 689 | dependencies = [ 690 | "proc-macro2", 691 | "quote", 692 | "syn", 693 | ] 694 | 695 | [[package]] 696 | name = "futures-sink" 697 | version = "0.3.28" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 700 | 701 | [[package]] 702 | name = "futures-task" 703 | version = "0.3.28" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 706 | 707 | [[package]] 708 | name = "futures-util" 709 | version = "0.3.28" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 712 | dependencies = [ 713 | "futures-core", 714 | "futures-macro", 715 | "futures-task", 716 | "pin-project-lite", 717 | "pin-utils", 718 | "slab", 719 | ] 720 | 721 | [[package]] 722 | name = "generic-array" 723 | version = "0.14.7" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 726 | dependencies = [ 727 | "typenum", 728 | "version_check", 729 | ] 730 | 731 | [[package]] 732 | name = "gimli" 733 | version = "0.28.0" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 736 | 737 | [[package]] 738 | name = "h2" 739 | version = "0.3.21" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" 742 | dependencies = [ 743 | "bytes", 744 | "fnv", 745 | "futures-core", 746 | "futures-sink", 747 | "futures-util", 748 | "http", 749 | "indexmap", 750 | "slab", 751 | "tokio", 752 | "tokio-util", 753 | "tracing", 754 | ] 755 | 756 | [[package]] 757 | name = "hashbrown" 758 | version = "0.12.3" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 761 | 762 | [[package]] 763 | name = "hermit-abi" 764 | version = "0.3.2" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 767 | 768 | [[package]] 769 | name = "hex" 770 | version = "0.4.3" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 773 | 774 | [[package]] 775 | name = "hmac" 776 | version = "0.12.1" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 779 | dependencies = [ 780 | "digest", 781 | ] 782 | 783 | [[package]] 784 | name = "http" 785 | version = "0.2.9" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 788 | dependencies = [ 789 | "bytes", 790 | "fnv", 791 | "itoa", 792 | ] 793 | 794 | [[package]] 795 | name = "http-body" 796 | version = "0.4.5" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 799 | dependencies = [ 800 | "bytes", 801 | "http", 802 | "pin-project-lite", 803 | ] 804 | 805 | [[package]] 806 | name = "httparse" 807 | version = "1.8.0" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 810 | 811 | [[package]] 812 | name = "httpdate" 813 | version = "1.0.3" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 816 | 817 | [[package]] 818 | name = "hyper" 819 | version = "0.14.27" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 822 | dependencies = [ 823 | "bytes", 824 | "futures-channel", 825 | "futures-core", 826 | "futures-util", 827 | "h2", 828 | "http", 829 | "http-body", 830 | "httparse", 831 | "httpdate", 832 | "itoa", 833 | "pin-project-lite", 834 | "socket2 0.4.9", 835 | "tokio", 836 | "tower-service", 837 | "tracing", 838 | "want", 839 | ] 840 | 841 | [[package]] 842 | name = "hyper-rustls" 843 | version = "0.24.1" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" 846 | dependencies = [ 847 | "futures-util", 848 | "http", 849 | "hyper", 850 | "log", 851 | "rustls", 852 | "rustls-native-certs", 853 | "tokio", 854 | "tokio-rustls", 855 | ] 856 | 857 | [[package]] 858 | name = "iana-time-zone" 859 | version = "0.1.57" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" 862 | dependencies = [ 863 | "android_system_properties", 864 | "core-foundation-sys", 865 | "iana-time-zone-haiku", 866 | "js-sys", 867 | "wasm-bindgen", 868 | "windows", 869 | ] 870 | 871 | [[package]] 872 | name = "iana-time-zone-haiku" 873 | version = "0.1.2" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 876 | dependencies = [ 877 | "cc", 878 | ] 879 | 880 | [[package]] 881 | name = "indexmap" 882 | version = "1.9.3" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 885 | dependencies = [ 886 | "autocfg", 887 | "hashbrown", 888 | ] 889 | 890 | [[package]] 891 | name = "itoa" 892 | version = "1.0.9" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 895 | 896 | [[package]] 897 | name = "js-sys" 898 | version = "0.3.64" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 901 | dependencies = [ 902 | "wasm-bindgen", 903 | ] 904 | 905 | [[package]] 906 | name = "lambda-extension" 907 | version = "0.8.1" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "c758c916cf90b290a489cafa9935fd0d1508d8974fbbc5d29a5b95ee5d4249a3" 910 | dependencies = [ 911 | "async-stream", 912 | "bytes", 913 | "chrono", 914 | "http", 915 | "hyper", 916 | "lambda_runtime_api_client", 917 | "serde", 918 | "serde_json", 919 | "tokio", 920 | "tokio-stream", 921 | "tower", 922 | "tracing", 923 | ] 924 | 925 | [[package]] 926 | name = "lambda_runtime_api_client" 927 | version = "0.8.0" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "690c5ae01f3acac8c9c3348b556fc443054e9b7f1deaf53e9ebab716282bf0ed" 930 | dependencies = [ 931 | "http", 932 | "hyper", 933 | "tokio", 934 | "tower-service", 935 | ] 936 | 937 | [[package]] 938 | name = "lazy_static" 939 | version = "1.4.0" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 942 | 943 | [[package]] 944 | name = "libc" 945 | version = "0.2.148" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" 948 | 949 | [[package]] 950 | name = "log" 951 | version = "0.4.20" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 954 | 955 | [[package]] 956 | name = "matchers" 957 | version = "0.1.0" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 960 | dependencies = [ 961 | "regex-automata 0.1.10", 962 | ] 963 | 964 | [[package]] 965 | name = "matchit" 966 | version = "0.7.2" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" 969 | 970 | [[package]] 971 | name = "memchr" 972 | version = "2.6.3" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" 975 | 976 | [[package]] 977 | name = "mime" 978 | version = "0.3.17" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 981 | 982 | [[package]] 983 | name = "miniz_oxide" 984 | version = "0.7.1" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 987 | dependencies = [ 988 | "adler", 989 | ] 990 | 991 | [[package]] 992 | name = "mio" 993 | version = "0.8.8" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 996 | dependencies = [ 997 | "libc", 998 | "wasi", 999 | "windows-sys", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "num-integer" 1004 | version = "0.1.45" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1007 | dependencies = [ 1008 | "autocfg", 1009 | "num-traits", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "num-traits" 1014 | version = "0.2.16" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" 1017 | dependencies = [ 1018 | "autocfg", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "num_cpus" 1023 | version = "1.16.0" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1026 | dependencies = [ 1027 | "hermit-abi", 1028 | "libc", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "object" 1033 | version = "0.32.1" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 1036 | dependencies = [ 1037 | "memchr", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "once_cell" 1042 | version = "1.18.0" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 1045 | 1046 | [[package]] 1047 | name = "openssl-probe" 1048 | version = "0.1.5" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1051 | 1052 | [[package]] 1053 | name = "outref" 1054 | version = "0.5.1" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" 1057 | 1058 | [[package]] 1059 | name = "percent-encoding" 1060 | version = "2.3.0" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 1063 | 1064 | [[package]] 1065 | name = "pin-project" 1066 | version = "1.1.3" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" 1069 | dependencies = [ 1070 | "pin-project-internal", 1071 | ] 1072 | 1073 | [[package]] 1074 | name = "pin-project-internal" 1075 | version = "1.1.3" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" 1078 | dependencies = [ 1079 | "proc-macro2", 1080 | "quote", 1081 | "syn", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "pin-project-lite" 1086 | version = "0.2.13" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1089 | 1090 | [[package]] 1091 | name = "pin-utils" 1092 | version = "0.1.0" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1095 | 1096 | [[package]] 1097 | name = "proc-macro2" 1098 | version = "1.0.67" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" 1101 | dependencies = [ 1102 | "unicode-ident", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "quote" 1107 | version = "1.0.33" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1110 | dependencies = [ 1111 | "proc-macro2", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "regex" 1116 | version = "1.9.5" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" 1119 | dependencies = [ 1120 | "aho-corasick", 1121 | "memchr", 1122 | "regex-automata 0.3.8", 1123 | "regex-syntax 0.7.5", 1124 | ] 1125 | 1126 | [[package]] 1127 | name = "regex-automata" 1128 | version = "0.1.10" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1131 | dependencies = [ 1132 | "regex-syntax 0.6.29", 1133 | ] 1134 | 1135 | [[package]] 1136 | name = "regex-automata" 1137 | version = "0.3.8" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" 1140 | dependencies = [ 1141 | "aho-corasick", 1142 | "memchr", 1143 | "regex-syntax 0.7.5", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "regex-syntax" 1148 | version = "0.6.29" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1151 | 1152 | [[package]] 1153 | name = "regex-syntax" 1154 | version = "0.7.5" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" 1157 | 1158 | [[package]] 1159 | name = "ring" 1160 | version = "0.16.20" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1163 | dependencies = [ 1164 | "cc", 1165 | "libc", 1166 | "once_cell", 1167 | "spin", 1168 | "untrusted", 1169 | "web-sys", 1170 | "winapi", 1171 | ] 1172 | 1173 | [[package]] 1174 | name = "rustc-demangle" 1175 | version = "0.1.23" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1178 | 1179 | [[package]] 1180 | name = "rustc_version" 1181 | version = "0.4.0" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1184 | dependencies = [ 1185 | "semver", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "rustls" 1190 | version = "0.21.7" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" 1193 | dependencies = [ 1194 | "log", 1195 | "ring", 1196 | "rustls-webpki", 1197 | "sct", 1198 | ] 1199 | 1200 | [[package]] 1201 | name = "rustls-native-certs" 1202 | version = "0.6.3" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" 1205 | dependencies = [ 1206 | "openssl-probe", 1207 | "rustls-pemfile", 1208 | "schannel", 1209 | "security-framework", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "rustls-pemfile" 1214 | version = "1.0.3" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" 1217 | dependencies = [ 1218 | "base64", 1219 | ] 1220 | 1221 | [[package]] 1222 | name = "rustls-webpki" 1223 | version = "0.101.5" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" 1226 | dependencies = [ 1227 | "ring", 1228 | "untrusted", 1229 | ] 1230 | 1231 | [[package]] 1232 | name = "rustversion" 1233 | version = "1.0.14" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 1236 | 1237 | [[package]] 1238 | name = "ryu" 1239 | version = "1.0.15" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 1242 | 1243 | [[package]] 1244 | name = "schannel" 1245 | version = "0.1.22" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" 1248 | dependencies = [ 1249 | "windows-sys", 1250 | ] 1251 | 1252 | [[package]] 1253 | name = "sct" 1254 | version = "0.7.0" 1255 | source = "registry+https://github.com/rust-lang/crates.io-index" 1256 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1257 | dependencies = [ 1258 | "ring", 1259 | "untrusted", 1260 | ] 1261 | 1262 | [[package]] 1263 | name = "security-framework" 1264 | version = "2.9.2" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" 1267 | dependencies = [ 1268 | "bitflags", 1269 | "core-foundation", 1270 | "core-foundation-sys", 1271 | "libc", 1272 | "security-framework-sys", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "security-framework-sys" 1277 | version = "2.9.1" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" 1280 | dependencies = [ 1281 | "core-foundation-sys", 1282 | "libc", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "semver" 1287 | version = "1.0.18" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" 1290 | 1291 | [[package]] 1292 | name = "serde" 1293 | version = "1.0.188" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 1296 | dependencies = [ 1297 | "serde_derive", 1298 | ] 1299 | 1300 | [[package]] 1301 | name = "serde_derive" 1302 | version = "1.0.188" 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" 1304 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 1305 | dependencies = [ 1306 | "proc-macro2", 1307 | "quote", 1308 | "syn", 1309 | ] 1310 | 1311 | [[package]] 1312 | name = "serde_json" 1313 | version = "1.0.107" 1314 | source = "registry+https://github.com/rust-lang/crates.io-index" 1315 | checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" 1316 | dependencies = [ 1317 | "itoa", 1318 | "ryu", 1319 | "serde", 1320 | ] 1321 | 1322 | [[package]] 1323 | name = "serde_path_to_error" 1324 | version = "0.1.14" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" 1327 | dependencies = [ 1328 | "itoa", 1329 | "serde", 1330 | ] 1331 | 1332 | [[package]] 1333 | name = "sha2" 1334 | version = "0.10.7" 1335 | source = "registry+https://github.com/rust-lang/crates.io-index" 1336 | checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" 1337 | dependencies = [ 1338 | "cfg-if", 1339 | "cpufeatures", 1340 | "digest", 1341 | ] 1342 | 1343 | [[package]] 1344 | name = "sharded-slab" 1345 | version = "0.1.4" 1346 | source = "registry+https://github.com/rust-lang/crates.io-index" 1347 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 1348 | dependencies = [ 1349 | "lazy_static", 1350 | ] 1351 | 1352 | [[package]] 1353 | name = "slab" 1354 | version = "0.4.9" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1357 | dependencies = [ 1358 | "autocfg", 1359 | ] 1360 | 1361 | [[package]] 1362 | name = "socket2" 1363 | version = "0.4.9" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1366 | dependencies = [ 1367 | "libc", 1368 | "winapi", 1369 | ] 1370 | 1371 | [[package]] 1372 | name = "socket2" 1373 | version = "0.5.4" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" 1376 | dependencies = [ 1377 | "libc", 1378 | "windows-sys", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "spin" 1383 | version = "0.5.2" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1386 | 1387 | [[package]] 1388 | name = "subtle" 1389 | version = "2.5.0" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 1392 | 1393 | [[package]] 1394 | name = "syn" 1395 | version = "2.0.37" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" 1398 | dependencies = [ 1399 | "proc-macro2", 1400 | "quote", 1401 | "unicode-ident", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "sync_wrapper" 1406 | version = "0.1.2" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1409 | 1410 | [[package]] 1411 | name = "thread_local" 1412 | version = "1.1.7" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 1415 | dependencies = [ 1416 | "cfg-if", 1417 | "once_cell", 1418 | ] 1419 | 1420 | [[package]] 1421 | name = "time" 1422 | version = "0.3.28" 1423 | source = "registry+https://github.com/rust-lang/crates.io-index" 1424 | checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" 1425 | dependencies = [ 1426 | "deranged", 1427 | "serde", 1428 | "time-core", 1429 | "time-macros", 1430 | ] 1431 | 1432 | [[package]] 1433 | name = "time-core" 1434 | version = "0.1.1" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" 1437 | 1438 | [[package]] 1439 | name = "time-macros" 1440 | version = "0.2.14" 1441 | source = "registry+https://github.com/rust-lang/crates.io-index" 1442 | checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" 1443 | dependencies = [ 1444 | "time-core", 1445 | ] 1446 | 1447 | [[package]] 1448 | name = "tokio" 1449 | version = "1.32.0" 1450 | source = "registry+https://github.com/rust-lang/crates.io-index" 1451 | checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" 1452 | dependencies = [ 1453 | "backtrace", 1454 | "bytes", 1455 | "libc", 1456 | "mio", 1457 | "num_cpus", 1458 | "pin-project-lite", 1459 | "socket2 0.5.4", 1460 | "tokio-macros", 1461 | "windows-sys", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "tokio-macros" 1466 | version = "2.1.0" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 1469 | dependencies = [ 1470 | "proc-macro2", 1471 | "quote", 1472 | "syn", 1473 | ] 1474 | 1475 | [[package]] 1476 | name = "tokio-rustls" 1477 | version = "0.24.1" 1478 | source = "registry+https://github.com/rust-lang/crates.io-index" 1479 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 1480 | dependencies = [ 1481 | "rustls", 1482 | "tokio", 1483 | ] 1484 | 1485 | [[package]] 1486 | name = "tokio-stream" 1487 | version = "0.1.14" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" 1490 | dependencies = [ 1491 | "futures-core", 1492 | "pin-project-lite", 1493 | "tokio", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "tokio-util" 1498 | version = "0.7.8" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1501 | dependencies = [ 1502 | "bytes", 1503 | "futures-core", 1504 | "futures-sink", 1505 | "pin-project-lite", 1506 | "tokio", 1507 | "tracing", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "tower" 1512 | version = "0.4.13" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1515 | dependencies = [ 1516 | "futures-core", 1517 | "futures-util", 1518 | "pin-project", 1519 | "pin-project-lite", 1520 | "tokio", 1521 | "tower-layer", 1522 | "tower-service", 1523 | "tracing", 1524 | ] 1525 | 1526 | [[package]] 1527 | name = "tower-layer" 1528 | version = "0.3.2" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 1531 | 1532 | [[package]] 1533 | name = "tower-service" 1534 | version = "0.3.2" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1537 | 1538 | [[package]] 1539 | name = "tracing" 1540 | version = "0.1.37" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1543 | dependencies = [ 1544 | "cfg-if", 1545 | "log", 1546 | "pin-project-lite", 1547 | "tracing-attributes", 1548 | "tracing-core", 1549 | ] 1550 | 1551 | [[package]] 1552 | name = "tracing-attributes" 1553 | version = "0.1.26" 1554 | source = "registry+https://github.com/rust-lang/crates.io-index" 1555 | checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" 1556 | dependencies = [ 1557 | "proc-macro2", 1558 | "quote", 1559 | "syn", 1560 | ] 1561 | 1562 | [[package]] 1563 | name = "tracing-core" 1564 | version = "0.1.31" 1565 | source = "registry+https://github.com/rust-lang/crates.io-index" 1566 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1567 | dependencies = [ 1568 | "once_cell", 1569 | ] 1570 | 1571 | [[package]] 1572 | name = "tracing-subscriber" 1573 | version = "0.3.17" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" 1576 | dependencies = [ 1577 | "matchers", 1578 | "once_cell", 1579 | "regex", 1580 | "sharded-slab", 1581 | "thread_local", 1582 | "tracing", 1583 | "tracing-core", 1584 | ] 1585 | 1586 | [[package]] 1587 | name = "try-lock" 1588 | version = "0.2.4" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1591 | 1592 | [[package]] 1593 | name = "typenum" 1594 | version = "1.17.0" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1597 | 1598 | [[package]] 1599 | name = "unicode-ident" 1600 | version = "1.0.12" 1601 | source = "registry+https://github.com/rust-lang/crates.io-index" 1602 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1603 | 1604 | [[package]] 1605 | name = "untrusted" 1606 | version = "0.7.1" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1609 | 1610 | [[package]] 1611 | name = "urlencoding" 1612 | version = "2.1.3" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 1615 | 1616 | [[package]] 1617 | name = "uuid" 1618 | version = "1.4.1" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" 1621 | 1622 | [[package]] 1623 | name = "version_check" 1624 | version = "0.9.4" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1627 | 1628 | [[package]] 1629 | name = "vsimd" 1630 | version = "0.8.0" 1631 | source = "registry+https://github.com/rust-lang/crates.io-index" 1632 | checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" 1633 | 1634 | [[package]] 1635 | name = "want" 1636 | version = "0.3.1" 1637 | source = "registry+https://github.com/rust-lang/crates.io-index" 1638 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1639 | dependencies = [ 1640 | "try-lock", 1641 | ] 1642 | 1643 | [[package]] 1644 | name = "wasi" 1645 | version = "0.11.0+wasi-snapshot-preview1" 1646 | source = "registry+https://github.com/rust-lang/crates.io-index" 1647 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1648 | 1649 | [[package]] 1650 | name = "wasm-bindgen" 1651 | version = "0.2.87" 1652 | source = "registry+https://github.com/rust-lang/crates.io-index" 1653 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 1654 | dependencies = [ 1655 | "cfg-if", 1656 | "wasm-bindgen-macro", 1657 | ] 1658 | 1659 | [[package]] 1660 | name = "wasm-bindgen-backend" 1661 | version = "0.2.87" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 1664 | dependencies = [ 1665 | "bumpalo", 1666 | "log", 1667 | "once_cell", 1668 | "proc-macro2", 1669 | "quote", 1670 | "syn", 1671 | "wasm-bindgen-shared", 1672 | ] 1673 | 1674 | [[package]] 1675 | name = "wasm-bindgen-macro" 1676 | version = "0.2.87" 1677 | source = "registry+https://github.com/rust-lang/crates.io-index" 1678 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 1679 | dependencies = [ 1680 | "quote", 1681 | "wasm-bindgen-macro-support", 1682 | ] 1683 | 1684 | [[package]] 1685 | name = "wasm-bindgen-macro-support" 1686 | version = "0.2.87" 1687 | source = "registry+https://github.com/rust-lang/crates.io-index" 1688 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 1689 | dependencies = [ 1690 | "proc-macro2", 1691 | "quote", 1692 | "syn", 1693 | "wasm-bindgen-backend", 1694 | "wasm-bindgen-shared", 1695 | ] 1696 | 1697 | [[package]] 1698 | name = "wasm-bindgen-shared" 1699 | version = "0.2.87" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 1702 | 1703 | [[package]] 1704 | name = "web-sys" 1705 | version = "0.3.64" 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" 1707 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1708 | dependencies = [ 1709 | "js-sys", 1710 | "wasm-bindgen", 1711 | ] 1712 | 1713 | [[package]] 1714 | name = "winapi" 1715 | version = "0.3.9" 1716 | source = "registry+https://github.com/rust-lang/crates.io-index" 1717 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1718 | dependencies = [ 1719 | "winapi-i686-pc-windows-gnu", 1720 | "winapi-x86_64-pc-windows-gnu", 1721 | ] 1722 | 1723 | [[package]] 1724 | name = "winapi-i686-pc-windows-gnu" 1725 | version = "0.4.0" 1726 | source = "registry+https://github.com/rust-lang/crates.io-index" 1727 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1728 | 1729 | [[package]] 1730 | name = "winapi-x86_64-pc-windows-gnu" 1731 | version = "0.4.0" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1734 | 1735 | [[package]] 1736 | name = "windows" 1737 | version = "0.48.0" 1738 | source = "registry+https://github.com/rust-lang/crates.io-index" 1739 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 1740 | dependencies = [ 1741 | "windows-targets", 1742 | ] 1743 | 1744 | [[package]] 1745 | name = "windows-sys" 1746 | version = "0.48.0" 1747 | source = "registry+https://github.com/rust-lang/crates.io-index" 1748 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1749 | dependencies = [ 1750 | "windows-targets", 1751 | ] 1752 | 1753 | [[package]] 1754 | name = "windows-targets" 1755 | version = "0.48.5" 1756 | source = "registry+https://github.com/rust-lang/crates.io-index" 1757 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1758 | dependencies = [ 1759 | "windows_aarch64_gnullvm", 1760 | "windows_aarch64_msvc", 1761 | "windows_i686_gnu", 1762 | "windows_i686_msvc", 1763 | "windows_x86_64_gnu", 1764 | "windows_x86_64_gnullvm", 1765 | "windows_x86_64_msvc", 1766 | ] 1767 | 1768 | [[package]] 1769 | name = "windows_aarch64_gnullvm" 1770 | version = "0.48.5" 1771 | source = "registry+https://github.com/rust-lang/crates.io-index" 1772 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1773 | 1774 | [[package]] 1775 | name = "windows_aarch64_msvc" 1776 | version = "0.48.5" 1777 | source = "registry+https://github.com/rust-lang/crates.io-index" 1778 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1779 | 1780 | [[package]] 1781 | name = "windows_i686_gnu" 1782 | version = "0.48.5" 1783 | source = "registry+https://github.com/rust-lang/crates.io-index" 1784 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1785 | 1786 | [[package]] 1787 | name = "windows_i686_msvc" 1788 | version = "0.48.5" 1789 | source = "registry+https://github.com/rust-lang/crates.io-index" 1790 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1791 | 1792 | [[package]] 1793 | name = "windows_x86_64_gnu" 1794 | version = "0.48.5" 1795 | source = "registry+https://github.com/rust-lang/crates.io-index" 1796 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1797 | 1798 | [[package]] 1799 | name = "windows_x86_64_gnullvm" 1800 | version = "0.48.5" 1801 | source = "registry+https://github.com/rust-lang/crates.io-index" 1802 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1803 | 1804 | [[package]] 1805 | name = "windows_x86_64_msvc" 1806 | version = "0.48.5" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1809 | 1810 | [[package]] 1811 | name = "xmlparser" 1812 | version = "0.13.5" 1813 | source = "registry+https://github.com/rust-lang/crates.io-index" 1814 | checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" 1815 | 1816 | [[package]] 1817 | name = "zeroize" 1818 | version = "1.6.0" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" 1821 | -------------------------------------------------------------------------------- /analytics-extension/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "analytics-extension" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | aws-config = "0.56.1" 10 | aws-sdk-sqs = "0.30.0" 11 | axum = { version = "0.6.20", default-features = false, features = ["tokio", "json", "matched-path", "http1"] } 12 | lambda-extension = "0.8.1" 13 | serde = "1.0.188" 14 | serde_json = "1.0.107" 15 | tokio = { version = "1.32.0", features = ["macros"] } 16 | tokio-stream = "0.1.14" 17 | tracing = { version = "0.1.37", features = ["log"] } 18 | tracing-subscriber = { version = "0.3.17", default-features = false, features = ["fmt", "env-filter"] } 19 | -------------------------------------------------------------------------------- /analytics-extension/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use aws_sdk_sqs::Client; 4 | use axum::{extract::State, http::StatusCode, routing::post, Json, Router}; 5 | use lambda_extension::{service_fn, Error, LambdaEvent, NextEvent}; 6 | use serde::{Deserialize, Serialize}; 7 | use tokio::{ 8 | sync::{ 9 | mpsc::{channel, Receiver, Sender}, 10 | Mutex, 11 | }, 12 | task, 13 | }; 14 | use tracing::{debug, error}; 15 | use tracing_subscriber::EnvFilter; 16 | 17 | #[derive(Clone)] 18 | struct AppState { 19 | pub sender: Sender, 20 | } 21 | 22 | #[derive(Deserialize, Serialize, Debug)] 23 | struct AnalyticsData { 24 | event: String, 25 | } 26 | 27 | async fn my_extension( 28 | client: Client, 29 | receiver: Arc>>, 30 | event: LambdaEvent, 31 | ) -> Result<(), Error> { 32 | let queue_url = std::env::var("ANALYTICS_SQS_URL").expect("Missing ANALYTICS_SQS_URL env!"); 33 | match event.next { 34 | NextEvent::Shutdown(_e) => { 35 | debug!(target: "extension","Shutdown Event"); 36 | } 37 | NextEvent::Invoke(_e) => { 38 | debug!(target: "extension","Invoke Event"); 39 | } 40 | } 41 | let mut rx = receiver.lock().await; 42 | while let Ok(message) = rx.try_recv() { 43 | debug!(target: "extension","GOT = {:?}", message); 44 | // Convert your data to payload, serialize it to JSON string for example 45 | let payload = serde_json::to_string(&message).unwrap(); 46 | 47 | // Send the message to SQS 48 | let response = client 49 | .send_message() 50 | .queue_url(queue_url.clone()) 51 | .message_body(payload) 52 | .send() 53 | .await; 54 | 55 | if let Err(error) = response { 56 | error!(target: "extension","ERROR = {:?}", error) 57 | } 58 | } 59 | Ok(()) 60 | } 61 | 62 | async fn post_message( 63 | State(state): State, 64 | Json(payload): Json, 65 | ) -> StatusCode { 66 | debug!(target: "extension","Sending = {:?}", payload); 67 | // Send a message to the queue 68 | state.sender.send(payload).await.unwrap(); 69 | 70 | StatusCode::OK 71 | } 72 | #[tokio::main] 73 | async fn main() -> Result<(), Error> { 74 | tracing_subscriber::fmt() 75 | .with_max_level(tracing::Level::INFO) 76 | .with_env_filter(EnvFilter::from_default_env()) 77 | .with_target(false) 78 | .without_time() 79 | .init(); 80 | 81 | debug!(target: "extension", "Starting extension"); 82 | let client = Client::new(&aws_config::load_from_env().await); 83 | let (sender, receiver) = channel(100); 84 | let state = AppState { sender: sender }; 85 | let route = Router::new() 86 | .route("/v1/analytics", post(post_message)) 87 | .with_state(state); 88 | 89 | let server = 90 | axum::Server::bind(&"0.0.0.0:3001".parse().unwrap()).serve(route.into_make_service()); 91 | task::spawn(async move { 92 | server.await.unwrap(); 93 | }); 94 | 95 | let rec = Arc::new(Mutex::new(receiver)); 96 | let func = |event| my_extension(client.clone(), rec.clone(), event); 97 | let func = service_fn(func); 98 | lambda_extension::run(func).await 99 | } 100 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "rustifying-serverless" 3 | version = "0.1.0" 4 | description = "How to use Rust in your existing Serverless projects" 5 | authors = ["Efi Merdler-Kravitz "] 6 | readme = "README.md" 7 | 8 | [tool.poe.tasks] 9 | build-python-lib = "maturin build -m s3-ops-rust-pyo3-lib/Cargo.toml --strip --release --zig -o .rust-lib" 10 | build-node-lib = { shell = "napi build --platform --release --config ./s3-ops-rust-napi-lib/package.json --cargo-cwd ./s3-ops-rust-napi-lib && mv s3-ops-rust-napi-lib.linux-x64-gnu.node index.js index.d.ts ./s3-admin-app/list-buckets-rust-node" } 11 | deploy-app = { shell = "cd s3-admin-app && sam build --no-cached && sam deploy" } 12 | build-and-deploy-app = ["build-python-lib", "build-node-lib", "deploy-app"] 13 | build-extension = "cargo lambda build --manifest-path analytics-extension/Cargo.toml --extension --release" 14 | deploy-extension = "cargo lambda deploy --manifest-path analytics-extension/Cargo.toml --extension" 15 | build-and-deploy-extension = ["build-extension", "deploy-extension"] 16 | update-dependencies = { shell = "poetry remove s3-ops-rust && poetry add .rust-lib/s3_ops_rust-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl --group dev" } 17 | 18 | [tool.poetry.dependencies] 19 | python = "^3.11" 20 | 21 | [tool.poetry.group.dev.dependencies] 22 | aws-lambda-powertools = { extras = ["aws-sdk"], version = "^2.23.1" } 23 | black = "^23.7.0" 24 | ipython = "^8.14.0" 25 | wheel = "^0.41.2" 26 | aiobotocore = "^2.6.0" 27 | uvloop = "^0.17.0" 28 | aiolimiter = "^1.1.0" 29 | 30 | 31 | [tool.poetry.group.rust-dev-tools.dependencies] 32 | maturin = "^1.2.3" 33 | cargo-lambda = "^0.21.1" 34 | 35 | [build-system] 36 | requires = ["poetry-core"] 37 | build-backend = "poetry.core.masonry.api" 38 | -------------------------------------------------------------------------------- /s3-admin-app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fun-with-serverless/rustifying-serverless/4febf36cbad815154c7cf8c91287a1cd80a695c8/s3-admin-app/__init__.py -------------------------------------------------------------------------------- /s3-admin-app/authorizer_python/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fun-with-serverless/rustifying-serverless/4febf36cbad815154c7cf8c91287a1cd80a695c8/s3-admin-app/authorizer_python/__init__.py -------------------------------------------------------------------------------- /s3-admin-app/authorizer_python/app.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from aws_lambda_powertools import Logger 3 | from aws_lambda_powertools.utilities.data_classes import event_source 4 | import base64 5 | from aws_lambda_powertools.utilities import parameters 6 | import boto3 7 | import os 8 | from aws_lambda_powertools.utilities.data_classes.api_gateway_authorizer_event import ( 9 | DENY_ALL_RESPONSE, 10 | APIGatewayAuthorizerRequestEvent, 11 | APIGatewayAuthorizerResponse, 12 | ) 13 | 14 | logger = Logger() 15 | dynamodb = boto3.resource("dynamodb") 16 | table = dynamodb.Table(os.environ["USERS_TABLE_NAME"]) 17 | 18 | 19 | @logger.inject_lambda_context(log_event=True) 20 | @event_source(data_class=APIGatewayAuthorizerRequestEvent) 21 | def lambda_handler(event: APIGatewayAuthorizerRequestEvent, context): 22 | user = get_user_by_token(event.get_header_value("authorization")) 23 | 24 | if user is None: 25 | # No user was found, so we return not authorized 26 | return DENY_ALL_RESPONSE 27 | 28 | # Found the user and setting the details in the context 29 | arn = event.parsed_arn 30 | policy = APIGatewayAuthorizerResponse( 31 | principal_id=user, 32 | context={"user": user}, 33 | region=arn.region, 34 | aws_account_id=arn.aws_account_id, 35 | api_id=arn.api_id, 36 | stage=arn.stage, 37 | ) 38 | 39 | policy.allow_all_routes() 40 | logger.info("Policy for user", policy=policy.asdict()) 41 | return policy.asdict() 42 | 43 | 44 | def get_user_by_token(token: Optional[str]) -> Optional[str]: 45 | if token and token.startswith("Basic"): 46 | logger.info("Basic auth arrived", auth_details=token) 47 | decoded_auth = base64.b64decode(token[6:]).decode() 48 | username, password = decoded_auth.split(":") 49 | 50 | response = table.get_item(Key={"user": username}) 51 | item = response.get("Item") 52 | if item and password == item["password"]: 53 | logger.info("User logged in") 54 | return username 55 | logger.info("User not found") 56 | return None 57 | -------------------------------------------------------------------------------- /s3-admin-app/authorizer_python/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | aws-lambda-powertools -------------------------------------------------------------------------------- /s3-admin-app/authorizer_rust/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 = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.0.5" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anyhow" 31 | version = "1.0.75" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" 34 | 35 | [[package]] 36 | name = "async-stream" 37 | version = "0.3.5" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 40 | dependencies = [ 41 | "async-stream-impl", 42 | "futures-core", 43 | "pin-project-lite", 44 | ] 45 | 46 | [[package]] 47 | name = "async-stream-impl" 48 | version = "0.3.5" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 51 | dependencies = [ 52 | "proc-macro2", 53 | "quote", 54 | "syn", 55 | ] 56 | 57 | [[package]] 58 | name = "authorizer-rust" 59 | version = "0.1.0" 60 | dependencies = [ 61 | "anyhow", 62 | "aws-config", 63 | "aws-sdk-dynamodb", 64 | "aws_lambda_events", 65 | "base64", 66 | "lambda_runtime", 67 | "serde", 68 | "serde_json", 69 | "tokio", 70 | "tracing", 71 | "tracing-subscriber", 72 | ] 73 | 74 | [[package]] 75 | name = "autocfg" 76 | version = "1.1.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 79 | 80 | [[package]] 81 | name = "aws-config" 82 | version = "0.56.1" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "fc6b3804dca60326e07205179847f17a4fce45af3a1106939177ad41ac08a6de" 85 | dependencies = [ 86 | "aws-credential-types", 87 | "aws-http", 88 | "aws-sdk-sso", 89 | "aws-sdk-sts", 90 | "aws-smithy-async", 91 | "aws-smithy-client", 92 | "aws-smithy-http", 93 | "aws-smithy-http-tower", 94 | "aws-smithy-json", 95 | "aws-smithy-types", 96 | "aws-types", 97 | "bytes", 98 | "fastrand", 99 | "hex", 100 | "http", 101 | "hyper", 102 | "ring", 103 | "time", 104 | "tokio", 105 | "tower", 106 | "tracing", 107 | "zeroize", 108 | ] 109 | 110 | [[package]] 111 | name = "aws-credential-types" 112 | version = "0.56.1" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "70a66ac8ef5fa9cf01c2d999f39d16812e90ec1467bd382cbbb74ba23ea86201" 115 | dependencies = [ 116 | "aws-smithy-async", 117 | "aws-smithy-types", 118 | "fastrand", 119 | "tokio", 120 | "tracing", 121 | "zeroize", 122 | ] 123 | 124 | [[package]] 125 | name = "aws-http" 126 | version = "0.56.1" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "3e626370f9ba806ae4c439e49675fd871f5767b093075cdf4fef16cac42ba900" 129 | dependencies = [ 130 | "aws-credential-types", 131 | "aws-smithy-http", 132 | "aws-smithy-types", 133 | "aws-types", 134 | "bytes", 135 | "http", 136 | "http-body", 137 | "lazy_static", 138 | "percent-encoding", 139 | "pin-project-lite", 140 | "tracing", 141 | ] 142 | 143 | [[package]] 144 | name = "aws-runtime" 145 | version = "0.56.1" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "07ac5cf0ff19c1bca0cea7932e11b239d1025a45696a4f44f72ea86e2b8bdd07" 148 | dependencies = [ 149 | "aws-credential-types", 150 | "aws-http", 151 | "aws-sigv4", 152 | "aws-smithy-async", 153 | "aws-smithy-http", 154 | "aws-smithy-runtime-api", 155 | "aws-smithy-types", 156 | "aws-types", 157 | "fastrand", 158 | "http", 159 | "percent-encoding", 160 | "tracing", 161 | "uuid", 162 | ] 163 | 164 | [[package]] 165 | name = "aws-sdk-dynamodb" 166 | version = "0.30.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "069e3c6f367a02ee0af86616b6bf9dcc4f1eab19e11b05d4b0f71da0c86fcd9d" 169 | dependencies = [ 170 | "aws-credential-types", 171 | "aws-http", 172 | "aws-runtime", 173 | "aws-smithy-async", 174 | "aws-smithy-client", 175 | "aws-smithy-http", 176 | "aws-smithy-json", 177 | "aws-smithy-runtime", 178 | "aws-smithy-runtime-api", 179 | "aws-smithy-types", 180 | "aws-types", 181 | "bytes", 182 | "fastrand", 183 | "http", 184 | "regex", 185 | "tokio-stream", 186 | "tracing", 187 | ] 188 | 189 | [[package]] 190 | name = "aws-sdk-sso" 191 | version = "0.30.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "903f888ff190e64f6f5c83fb0f8d54f9c20481f1dc26359bb8896f5d99908949" 194 | dependencies = [ 195 | "aws-credential-types", 196 | "aws-http", 197 | "aws-runtime", 198 | "aws-smithy-async", 199 | "aws-smithy-client", 200 | "aws-smithy-http", 201 | "aws-smithy-json", 202 | "aws-smithy-runtime", 203 | "aws-smithy-runtime-api", 204 | "aws-smithy-types", 205 | "aws-types", 206 | "bytes", 207 | "http", 208 | "regex", 209 | "tokio-stream", 210 | "tracing", 211 | ] 212 | 213 | [[package]] 214 | name = "aws-sdk-sts" 215 | version = "0.30.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "a47ad6bf01afc00423d781d464220bf69fb6a674ad6629cbbcb06d88cdc2be82" 218 | dependencies = [ 219 | "aws-credential-types", 220 | "aws-http", 221 | "aws-runtime", 222 | "aws-smithy-async", 223 | "aws-smithy-client", 224 | "aws-smithy-http", 225 | "aws-smithy-json", 226 | "aws-smithy-query", 227 | "aws-smithy-runtime", 228 | "aws-smithy-runtime-api", 229 | "aws-smithy-types", 230 | "aws-smithy-xml", 231 | "aws-types", 232 | "http", 233 | "regex", 234 | "tracing", 235 | ] 236 | 237 | [[package]] 238 | name = "aws-sigv4" 239 | version = "0.56.1" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "b7b28f4910bb956b7ab320b62e98096402354eca976c587d1eeccd523d9bac03" 242 | dependencies = [ 243 | "aws-smithy-http", 244 | "form_urlencoded", 245 | "hex", 246 | "hmac", 247 | "http", 248 | "once_cell", 249 | "percent-encoding", 250 | "regex", 251 | "sha2", 252 | "time", 253 | "tracing", 254 | ] 255 | 256 | [[package]] 257 | name = "aws-smithy-async" 258 | version = "0.56.1" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "2cdb73f85528b9d19c23a496034ac53703955a59323d581c06aa27b4e4e247af" 261 | dependencies = [ 262 | "futures-util", 263 | "pin-project-lite", 264 | "tokio", 265 | "tokio-stream", 266 | ] 267 | 268 | [[package]] 269 | name = "aws-smithy-client" 270 | version = "0.56.1" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "c27b2756264c82f830a91cb4d2d485b2d19ad5bea476d9a966e03d27f27ba59a" 273 | dependencies = [ 274 | "aws-smithy-async", 275 | "aws-smithy-http", 276 | "aws-smithy-http-tower", 277 | "aws-smithy-types", 278 | "bytes", 279 | "fastrand", 280 | "http", 281 | "http-body", 282 | "hyper", 283 | "hyper-rustls", 284 | "lazy_static", 285 | "pin-project-lite", 286 | "rustls", 287 | "tokio", 288 | "tower", 289 | "tracing", 290 | ] 291 | 292 | [[package]] 293 | name = "aws-smithy-http" 294 | version = "0.56.1" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "54cdcf365d8eee60686885f750a34c190e513677db58bbc466c44c588abf4199" 297 | dependencies = [ 298 | "aws-smithy-types", 299 | "bytes", 300 | "bytes-utils", 301 | "futures-core", 302 | "http", 303 | "http-body", 304 | "hyper", 305 | "once_cell", 306 | "percent-encoding", 307 | "pin-project-lite", 308 | "pin-utils", 309 | "tokio", 310 | "tokio-util", 311 | "tracing", 312 | ] 313 | 314 | [[package]] 315 | name = "aws-smithy-http-tower" 316 | version = "0.56.1" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "822de399d0ce62829a69dfa8c5cd08efdbe61a7426b953e2268f8b8b52a607bd" 319 | dependencies = [ 320 | "aws-smithy-http", 321 | "aws-smithy-types", 322 | "bytes", 323 | "http", 324 | "http-body", 325 | "pin-project-lite", 326 | "tower", 327 | "tracing", 328 | ] 329 | 330 | [[package]] 331 | name = "aws-smithy-json" 332 | version = "0.56.1" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "4fb1e7ab8fa7ad10c193af7ae56d2420989e9f4758bf03601a342573333ea34f" 335 | dependencies = [ 336 | "aws-smithy-types", 337 | ] 338 | 339 | [[package]] 340 | name = "aws-smithy-query" 341 | version = "0.56.1" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "28556a3902091c1f768a34f6c998028921bdab8d47d92586f363f14a4a32d047" 344 | dependencies = [ 345 | "aws-smithy-types", 346 | "urlencoding", 347 | ] 348 | 349 | [[package]] 350 | name = "aws-smithy-runtime" 351 | version = "0.56.1" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "745e096b3553e7e0f40622aa04971ce52765af82bebdeeac53aa6fc82fe801e6" 354 | dependencies = [ 355 | "aws-smithy-async", 356 | "aws-smithy-client", 357 | "aws-smithy-http", 358 | "aws-smithy-runtime-api", 359 | "aws-smithy-types", 360 | "bytes", 361 | "fastrand", 362 | "http", 363 | "http-body", 364 | "once_cell", 365 | "pin-project-lite", 366 | "pin-utils", 367 | "tokio", 368 | "tracing", 369 | ] 370 | 371 | [[package]] 372 | name = "aws-smithy-runtime-api" 373 | version = "0.56.1" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "93d0ae0c9cfd57944e9711ea610b48a963fb174a53aabacc08c5794a594b1d02" 376 | dependencies = [ 377 | "aws-smithy-async", 378 | "aws-smithy-http", 379 | "aws-smithy-types", 380 | "bytes", 381 | "http", 382 | "tokio", 383 | "tracing", 384 | ] 385 | 386 | [[package]] 387 | name = "aws-smithy-types" 388 | version = "0.56.1" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "d90dbc8da2f6be461fa3c1906b20af8f79d14968fe47f2b7d29d086f62a51728" 391 | dependencies = [ 392 | "base64-simd", 393 | "itoa", 394 | "num-integer", 395 | "ryu", 396 | "serde", 397 | "time", 398 | ] 399 | 400 | [[package]] 401 | name = "aws-smithy-xml" 402 | version = "0.56.1" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "e01d2dedcdd8023043716cfeeb3c6c59f2d447fce365d8e194838891794b23b6" 405 | dependencies = [ 406 | "xmlparser", 407 | ] 408 | 409 | [[package]] 410 | name = "aws-types" 411 | version = "0.56.1" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "85aa0451bf8af1bf22a4f028d5d28054507a14be43cb8ac0597a8471fba9edfe" 414 | dependencies = [ 415 | "aws-credential-types", 416 | "aws-smithy-async", 417 | "aws-smithy-client", 418 | "aws-smithy-http", 419 | "aws-smithy-types", 420 | "http", 421 | "rustc_version", 422 | "tracing", 423 | ] 424 | 425 | [[package]] 426 | name = "aws_lambda_events" 427 | version = "0.10.0" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "65991dbc3bfb586939ba1527eefdc99bc21157b6ec891f180fb1e16e2dddc7a9" 430 | dependencies = [ 431 | "base64", 432 | "bytes", 433 | "http", 434 | "http-body", 435 | "http-serde", 436 | "query_map", 437 | "serde", 438 | "serde_json", 439 | ] 440 | 441 | [[package]] 442 | name = "backtrace" 443 | version = "0.3.69" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 446 | dependencies = [ 447 | "addr2line", 448 | "cc", 449 | "cfg-if", 450 | "libc", 451 | "miniz_oxide", 452 | "object", 453 | "rustc-demangle", 454 | ] 455 | 456 | [[package]] 457 | name = "base64" 458 | version = "0.21.3" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" 461 | 462 | [[package]] 463 | name = "base64-simd" 464 | version = "0.8.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" 467 | dependencies = [ 468 | "outref", 469 | "vsimd", 470 | ] 471 | 472 | [[package]] 473 | name = "bitflags" 474 | version = "1.3.2" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 477 | 478 | [[package]] 479 | name = "block-buffer" 480 | version = "0.10.4" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 483 | dependencies = [ 484 | "generic-array", 485 | ] 486 | 487 | [[package]] 488 | name = "bumpalo" 489 | version = "3.13.0" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" 492 | 493 | [[package]] 494 | name = "bytes" 495 | version = "1.4.0" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 498 | dependencies = [ 499 | "serde", 500 | ] 501 | 502 | [[package]] 503 | name = "bytes-utils" 504 | version = "0.1.3" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "e47d3a8076e283f3acd27400535992edb3ba4b5bb72f8891ad8fbe7932a7d4b9" 507 | dependencies = [ 508 | "bytes", 509 | "either", 510 | ] 511 | 512 | [[package]] 513 | name = "cc" 514 | version = "1.0.83" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 517 | dependencies = [ 518 | "libc", 519 | ] 520 | 521 | [[package]] 522 | name = "cfg-if" 523 | version = "1.0.0" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 526 | 527 | [[package]] 528 | name = "core-foundation" 529 | version = "0.9.3" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 532 | dependencies = [ 533 | "core-foundation-sys", 534 | "libc", 535 | ] 536 | 537 | [[package]] 538 | name = "core-foundation-sys" 539 | version = "0.8.4" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 542 | 543 | [[package]] 544 | name = "cpufeatures" 545 | version = "0.2.9" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 548 | dependencies = [ 549 | "libc", 550 | ] 551 | 552 | [[package]] 553 | name = "crypto-common" 554 | version = "0.1.6" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 557 | dependencies = [ 558 | "generic-array", 559 | "typenum", 560 | ] 561 | 562 | [[package]] 563 | name = "deranged" 564 | version = "0.3.8" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" 567 | 568 | [[package]] 569 | name = "digest" 570 | version = "0.10.7" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 573 | dependencies = [ 574 | "block-buffer", 575 | "crypto-common", 576 | "subtle", 577 | ] 578 | 579 | [[package]] 580 | name = "either" 581 | version = "1.9.0" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 584 | 585 | [[package]] 586 | name = "fastrand" 587 | version = "2.0.0" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" 590 | 591 | [[package]] 592 | name = "fnv" 593 | version = "1.0.7" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 596 | 597 | [[package]] 598 | name = "form_urlencoded" 599 | version = "1.2.0" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 602 | dependencies = [ 603 | "percent-encoding", 604 | ] 605 | 606 | [[package]] 607 | name = "futures" 608 | version = "0.3.28" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 611 | dependencies = [ 612 | "futures-channel", 613 | "futures-core", 614 | "futures-executor", 615 | "futures-io", 616 | "futures-sink", 617 | "futures-task", 618 | "futures-util", 619 | ] 620 | 621 | [[package]] 622 | name = "futures-channel" 623 | version = "0.3.28" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 626 | dependencies = [ 627 | "futures-core", 628 | "futures-sink", 629 | ] 630 | 631 | [[package]] 632 | name = "futures-core" 633 | version = "0.3.28" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 636 | 637 | [[package]] 638 | name = "futures-executor" 639 | version = "0.3.28" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" 642 | dependencies = [ 643 | "futures-core", 644 | "futures-task", 645 | "futures-util", 646 | ] 647 | 648 | [[package]] 649 | name = "futures-io" 650 | version = "0.3.28" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 653 | 654 | [[package]] 655 | name = "futures-macro" 656 | version = "0.3.28" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 659 | dependencies = [ 660 | "proc-macro2", 661 | "quote", 662 | "syn", 663 | ] 664 | 665 | [[package]] 666 | name = "futures-sink" 667 | version = "0.3.28" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 670 | 671 | [[package]] 672 | name = "futures-task" 673 | version = "0.3.28" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 676 | 677 | [[package]] 678 | name = "futures-util" 679 | version = "0.3.28" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 682 | dependencies = [ 683 | "futures-channel", 684 | "futures-core", 685 | "futures-io", 686 | "futures-macro", 687 | "futures-sink", 688 | "futures-task", 689 | "memchr", 690 | "pin-project-lite", 691 | "pin-utils", 692 | "slab", 693 | ] 694 | 695 | [[package]] 696 | name = "generic-array" 697 | version = "0.14.7" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 700 | dependencies = [ 701 | "typenum", 702 | "version_check", 703 | ] 704 | 705 | [[package]] 706 | name = "gimli" 707 | version = "0.28.0" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 710 | 711 | [[package]] 712 | name = "h2" 713 | version = "0.3.21" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" 716 | dependencies = [ 717 | "bytes", 718 | "fnv", 719 | "futures-core", 720 | "futures-sink", 721 | "futures-util", 722 | "http", 723 | "indexmap", 724 | "slab", 725 | "tokio", 726 | "tokio-util", 727 | "tracing", 728 | ] 729 | 730 | [[package]] 731 | name = "hashbrown" 732 | version = "0.12.3" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 735 | 736 | [[package]] 737 | name = "hermit-abi" 738 | version = "0.3.2" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 741 | 742 | [[package]] 743 | name = "hex" 744 | version = "0.4.3" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 747 | 748 | [[package]] 749 | name = "hmac" 750 | version = "0.12.1" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 753 | dependencies = [ 754 | "digest", 755 | ] 756 | 757 | [[package]] 758 | name = "http" 759 | version = "0.2.9" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 762 | dependencies = [ 763 | "bytes", 764 | "fnv", 765 | "itoa", 766 | ] 767 | 768 | [[package]] 769 | name = "http-body" 770 | version = "0.4.5" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 773 | dependencies = [ 774 | "bytes", 775 | "http", 776 | "pin-project-lite", 777 | ] 778 | 779 | [[package]] 780 | name = "http-serde" 781 | version = "1.1.3" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "6f560b665ad9f1572cfcaf034f7fb84338a7ce945216d64a90fd81f046a3caee" 784 | dependencies = [ 785 | "http", 786 | "serde", 787 | ] 788 | 789 | [[package]] 790 | name = "httparse" 791 | version = "1.8.0" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 794 | 795 | [[package]] 796 | name = "httpdate" 797 | version = "1.0.3" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 800 | 801 | [[package]] 802 | name = "hyper" 803 | version = "0.14.27" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 806 | dependencies = [ 807 | "bytes", 808 | "futures-channel", 809 | "futures-core", 810 | "futures-util", 811 | "h2", 812 | "http", 813 | "http-body", 814 | "httparse", 815 | "httpdate", 816 | "itoa", 817 | "pin-project-lite", 818 | "socket2 0.4.9", 819 | "tokio", 820 | "tower-service", 821 | "tracing", 822 | "want", 823 | ] 824 | 825 | [[package]] 826 | name = "hyper-rustls" 827 | version = "0.24.1" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" 830 | dependencies = [ 831 | "futures-util", 832 | "http", 833 | "hyper", 834 | "log", 835 | "rustls", 836 | "rustls-native-certs", 837 | "tokio", 838 | "tokio-rustls", 839 | ] 840 | 841 | [[package]] 842 | name = "indexmap" 843 | version = "1.9.3" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 846 | dependencies = [ 847 | "autocfg", 848 | "hashbrown", 849 | ] 850 | 851 | [[package]] 852 | name = "itoa" 853 | version = "1.0.9" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 856 | 857 | [[package]] 858 | name = "js-sys" 859 | version = "0.3.64" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 862 | dependencies = [ 863 | "wasm-bindgen", 864 | ] 865 | 866 | [[package]] 867 | name = "lambda_runtime" 868 | version = "0.8.1" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "9db262b5e9548a371d9e1dd54ba094b75e3e46b345c11458ea2b4d4c54fbffa9" 871 | dependencies = [ 872 | "async-stream", 873 | "bytes", 874 | "futures", 875 | "http", 876 | "hyper", 877 | "lambda_runtime_api_client", 878 | "serde", 879 | "serde_json", 880 | "serde_path_to_error", 881 | "tokio", 882 | "tokio-stream", 883 | "tower", 884 | "tracing", 885 | ] 886 | 887 | [[package]] 888 | name = "lambda_runtime_api_client" 889 | version = "0.8.0" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "690c5ae01f3acac8c9c3348b556fc443054e9b7f1deaf53e9ebab716282bf0ed" 892 | dependencies = [ 893 | "http", 894 | "hyper", 895 | "tokio", 896 | "tower-service", 897 | ] 898 | 899 | [[package]] 900 | name = "lazy_static" 901 | version = "1.4.0" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 904 | 905 | [[package]] 906 | name = "libc" 907 | version = "0.2.147" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 910 | 911 | [[package]] 912 | name = "log" 913 | version = "0.4.20" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 916 | 917 | [[package]] 918 | name = "memchr" 919 | version = "2.6.3" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" 922 | 923 | [[package]] 924 | name = "miniz_oxide" 925 | version = "0.7.1" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 928 | dependencies = [ 929 | "adler", 930 | ] 931 | 932 | [[package]] 933 | name = "mio" 934 | version = "0.8.8" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 937 | dependencies = [ 938 | "libc", 939 | "wasi", 940 | "windows-sys", 941 | ] 942 | 943 | [[package]] 944 | name = "num-integer" 945 | version = "0.1.45" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 948 | dependencies = [ 949 | "autocfg", 950 | "num-traits", 951 | ] 952 | 953 | [[package]] 954 | name = "num-traits" 955 | version = "0.2.16" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" 958 | dependencies = [ 959 | "autocfg", 960 | ] 961 | 962 | [[package]] 963 | name = "num_cpus" 964 | version = "1.16.0" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 967 | dependencies = [ 968 | "hermit-abi", 969 | "libc", 970 | ] 971 | 972 | [[package]] 973 | name = "object" 974 | version = "0.32.1" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 977 | dependencies = [ 978 | "memchr", 979 | ] 980 | 981 | [[package]] 982 | name = "once_cell" 983 | version = "1.18.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 986 | 987 | [[package]] 988 | name = "openssl-probe" 989 | version = "0.1.5" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 992 | 993 | [[package]] 994 | name = "outref" 995 | version = "0.5.1" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" 998 | 999 | [[package]] 1000 | name = "percent-encoding" 1001 | version = "2.3.0" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 1004 | 1005 | [[package]] 1006 | name = "pin-project" 1007 | version = "1.1.3" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" 1010 | dependencies = [ 1011 | "pin-project-internal", 1012 | ] 1013 | 1014 | [[package]] 1015 | name = "pin-project-internal" 1016 | version = "1.1.3" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" 1019 | dependencies = [ 1020 | "proc-macro2", 1021 | "quote", 1022 | "syn", 1023 | ] 1024 | 1025 | [[package]] 1026 | name = "pin-project-lite" 1027 | version = "0.2.13" 1028 | source = "registry+https://github.com/rust-lang/crates.io-index" 1029 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1030 | 1031 | [[package]] 1032 | name = "pin-utils" 1033 | version = "0.1.0" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1036 | 1037 | [[package]] 1038 | name = "proc-macro2" 1039 | version = "1.0.66" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 1042 | dependencies = [ 1043 | "unicode-ident", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "query_map" 1048 | version = "0.6.0" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "4465aacac3bebc9484cf7a56dc8b2d7feacb657da6002a9198b4f7af4247a204" 1051 | dependencies = [ 1052 | "form_urlencoded", 1053 | "serde", 1054 | "serde_derive", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "quote" 1059 | version = "1.0.33" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1062 | dependencies = [ 1063 | "proc-macro2", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "regex" 1068 | version = "1.9.5" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" 1071 | dependencies = [ 1072 | "aho-corasick", 1073 | "memchr", 1074 | "regex-automata", 1075 | "regex-syntax", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "regex-automata" 1080 | version = "0.3.8" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" 1083 | dependencies = [ 1084 | "aho-corasick", 1085 | "memchr", 1086 | "regex-syntax", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "regex-syntax" 1091 | version = "0.7.5" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" 1094 | 1095 | [[package]] 1096 | name = "ring" 1097 | version = "0.16.20" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1100 | dependencies = [ 1101 | "cc", 1102 | "libc", 1103 | "once_cell", 1104 | "spin", 1105 | "untrusted", 1106 | "web-sys", 1107 | "winapi", 1108 | ] 1109 | 1110 | [[package]] 1111 | name = "rustc-demangle" 1112 | version = "0.1.23" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1115 | 1116 | [[package]] 1117 | name = "rustc_version" 1118 | version = "0.4.0" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1121 | dependencies = [ 1122 | "semver", 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "rustls" 1127 | version = "0.21.7" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" 1130 | dependencies = [ 1131 | "log", 1132 | "ring", 1133 | "rustls-webpki", 1134 | "sct", 1135 | ] 1136 | 1137 | [[package]] 1138 | name = "rustls-native-certs" 1139 | version = "0.6.3" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" 1142 | dependencies = [ 1143 | "openssl-probe", 1144 | "rustls-pemfile", 1145 | "schannel", 1146 | "security-framework", 1147 | ] 1148 | 1149 | [[package]] 1150 | name = "rustls-pemfile" 1151 | version = "1.0.3" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" 1154 | dependencies = [ 1155 | "base64", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "rustls-webpki" 1160 | version = "0.101.4" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" 1163 | dependencies = [ 1164 | "ring", 1165 | "untrusted", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "ryu" 1170 | version = "1.0.15" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 1173 | 1174 | [[package]] 1175 | name = "schannel" 1176 | version = "0.1.22" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" 1179 | dependencies = [ 1180 | "windows-sys", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "sct" 1185 | version = "0.7.0" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1188 | dependencies = [ 1189 | "ring", 1190 | "untrusted", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "security-framework" 1195 | version = "2.9.2" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" 1198 | dependencies = [ 1199 | "bitflags", 1200 | "core-foundation", 1201 | "core-foundation-sys", 1202 | "libc", 1203 | "security-framework-sys", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "security-framework-sys" 1208 | version = "2.9.1" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" 1211 | dependencies = [ 1212 | "core-foundation-sys", 1213 | "libc", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "semver" 1218 | version = "1.0.18" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" 1221 | 1222 | [[package]] 1223 | name = "serde" 1224 | version = "1.0.188" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 1227 | dependencies = [ 1228 | "serde_derive", 1229 | ] 1230 | 1231 | [[package]] 1232 | name = "serde_derive" 1233 | version = "1.0.188" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 1236 | dependencies = [ 1237 | "proc-macro2", 1238 | "quote", 1239 | "syn", 1240 | ] 1241 | 1242 | [[package]] 1243 | name = "serde_json" 1244 | version = "1.0.105" 1245 | source = "registry+https://github.com/rust-lang/crates.io-index" 1246 | checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" 1247 | dependencies = [ 1248 | "itoa", 1249 | "ryu", 1250 | "serde", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "serde_path_to_error" 1255 | version = "0.1.14" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" 1258 | dependencies = [ 1259 | "itoa", 1260 | "serde", 1261 | ] 1262 | 1263 | [[package]] 1264 | name = "sha2" 1265 | version = "0.10.7" 1266 | source = "registry+https://github.com/rust-lang/crates.io-index" 1267 | checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" 1268 | dependencies = [ 1269 | "cfg-if", 1270 | "cpufeatures", 1271 | "digest", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "sharded-slab" 1276 | version = "0.1.4" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 1279 | dependencies = [ 1280 | "lazy_static", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "slab" 1285 | version = "0.4.9" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1288 | dependencies = [ 1289 | "autocfg", 1290 | ] 1291 | 1292 | [[package]] 1293 | name = "socket2" 1294 | version = "0.4.9" 1295 | source = "registry+https://github.com/rust-lang/crates.io-index" 1296 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1297 | dependencies = [ 1298 | "libc", 1299 | "winapi", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "socket2" 1304 | version = "0.5.3" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" 1307 | dependencies = [ 1308 | "libc", 1309 | "windows-sys", 1310 | ] 1311 | 1312 | [[package]] 1313 | name = "spin" 1314 | version = "0.5.2" 1315 | source = "registry+https://github.com/rust-lang/crates.io-index" 1316 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1317 | 1318 | [[package]] 1319 | name = "subtle" 1320 | version = "2.5.0" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 1323 | 1324 | [[package]] 1325 | name = "syn" 1326 | version = "2.0.31" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" 1329 | dependencies = [ 1330 | "proc-macro2", 1331 | "quote", 1332 | "unicode-ident", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "thread_local" 1337 | version = "1.1.7" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 1340 | dependencies = [ 1341 | "cfg-if", 1342 | "once_cell", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "time" 1347 | version = "0.3.28" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" 1350 | dependencies = [ 1351 | "deranged", 1352 | "serde", 1353 | "time-core", 1354 | "time-macros", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "time-core" 1359 | version = "0.1.1" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" 1362 | 1363 | [[package]] 1364 | name = "time-macros" 1365 | version = "0.2.14" 1366 | source = "registry+https://github.com/rust-lang/crates.io-index" 1367 | checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" 1368 | dependencies = [ 1369 | "time-core", 1370 | ] 1371 | 1372 | [[package]] 1373 | name = "tokio" 1374 | version = "1.32.0" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" 1377 | dependencies = [ 1378 | "backtrace", 1379 | "bytes", 1380 | "libc", 1381 | "mio", 1382 | "num_cpus", 1383 | "pin-project-lite", 1384 | "socket2 0.5.3", 1385 | "tokio-macros", 1386 | "windows-sys", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "tokio-macros" 1391 | version = "2.1.0" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 1394 | dependencies = [ 1395 | "proc-macro2", 1396 | "quote", 1397 | "syn", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "tokio-rustls" 1402 | version = "0.24.1" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 1405 | dependencies = [ 1406 | "rustls", 1407 | "tokio", 1408 | ] 1409 | 1410 | [[package]] 1411 | name = "tokio-stream" 1412 | version = "0.1.14" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" 1415 | dependencies = [ 1416 | "futures-core", 1417 | "pin-project-lite", 1418 | "tokio", 1419 | ] 1420 | 1421 | [[package]] 1422 | name = "tokio-util" 1423 | version = "0.7.8" 1424 | source = "registry+https://github.com/rust-lang/crates.io-index" 1425 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1426 | dependencies = [ 1427 | "bytes", 1428 | "futures-core", 1429 | "futures-sink", 1430 | "pin-project-lite", 1431 | "tokio", 1432 | "tracing", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "tower" 1437 | version = "0.4.13" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1440 | dependencies = [ 1441 | "futures-core", 1442 | "futures-util", 1443 | "pin-project", 1444 | "pin-project-lite", 1445 | "tokio", 1446 | "tower-layer", 1447 | "tower-service", 1448 | "tracing", 1449 | ] 1450 | 1451 | [[package]] 1452 | name = "tower-layer" 1453 | version = "0.3.2" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 1456 | 1457 | [[package]] 1458 | name = "tower-service" 1459 | version = "0.3.2" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1462 | 1463 | [[package]] 1464 | name = "tracing" 1465 | version = "0.1.37" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1468 | dependencies = [ 1469 | "cfg-if", 1470 | "log", 1471 | "pin-project-lite", 1472 | "tracing-attributes", 1473 | "tracing-core", 1474 | ] 1475 | 1476 | [[package]] 1477 | name = "tracing-attributes" 1478 | version = "0.1.26" 1479 | source = "registry+https://github.com/rust-lang/crates.io-index" 1480 | checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" 1481 | dependencies = [ 1482 | "proc-macro2", 1483 | "quote", 1484 | "syn", 1485 | ] 1486 | 1487 | [[package]] 1488 | name = "tracing-core" 1489 | version = "0.1.31" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1492 | dependencies = [ 1493 | "once_cell", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "tracing-subscriber" 1498 | version = "0.3.17" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" 1501 | dependencies = [ 1502 | "sharded-slab", 1503 | "thread_local", 1504 | "tracing-core", 1505 | ] 1506 | 1507 | [[package]] 1508 | name = "try-lock" 1509 | version = "0.2.4" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1512 | 1513 | [[package]] 1514 | name = "typenum" 1515 | version = "1.16.0" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1518 | 1519 | [[package]] 1520 | name = "unicode-ident" 1521 | version = "1.0.11" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 1524 | 1525 | [[package]] 1526 | name = "untrusted" 1527 | version = "0.7.1" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1530 | 1531 | [[package]] 1532 | name = "urlencoding" 1533 | version = "2.1.3" 1534 | source = "registry+https://github.com/rust-lang/crates.io-index" 1535 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 1536 | 1537 | [[package]] 1538 | name = "uuid" 1539 | version = "1.4.1" 1540 | source = "registry+https://github.com/rust-lang/crates.io-index" 1541 | checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" 1542 | 1543 | [[package]] 1544 | name = "version_check" 1545 | version = "0.9.4" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1548 | 1549 | [[package]] 1550 | name = "vsimd" 1551 | version = "0.8.0" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" 1554 | 1555 | [[package]] 1556 | name = "want" 1557 | version = "0.3.1" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1560 | dependencies = [ 1561 | "try-lock", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "wasi" 1566 | version = "0.11.0+wasi-snapshot-preview1" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1569 | 1570 | [[package]] 1571 | name = "wasm-bindgen" 1572 | version = "0.2.87" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 1575 | dependencies = [ 1576 | "cfg-if", 1577 | "wasm-bindgen-macro", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "wasm-bindgen-backend" 1582 | version = "0.2.87" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 1585 | dependencies = [ 1586 | "bumpalo", 1587 | "log", 1588 | "once_cell", 1589 | "proc-macro2", 1590 | "quote", 1591 | "syn", 1592 | "wasm-bindgen-shared", 1593 | ] 1594 | 1595 | [[package]] 1596 | name = "wasm-bindgen-macro" 1597 | version = "0.2.87" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 1600 | dependencies = [ 1601 | "quote", 1602 | "wasm-bindgen-macro-support", 1603 | ] 1604 | 1605 | [[package]] 1606 | name = "wasm-bindgen-macro-support" 1607 | version = "0.2.87" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 1610 | dependencies = [ 1611 | "proc-macro2", 1612 | "quote", 1613 | "syn", 1614 | "wasm-bindgen-backend", 1615 | "wasm-bindgen-shared", 1616 | ] 1617 | 1618 | [[package]] 1619 | name = "wasm-bindgen-shared" 1620 | version = "0.2.87" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 1623 | 1624 | [[package]] 1625 | name = "web-sys" 1626 | version = "0.3.64" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1629 | dependencies = [ 1630 | "js-sys", 1631 | "wasm-bindgen", 1632 | ] 1633 | 1634 | [[package]] 1635 | name = "winapi" 1636 | version = "0.3.9" 1637 | source = "registry+https://github.com/rust-lang/crates.io-index" 1638 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1639 | dependencies = [ 1640 | "winapi-i686-pc-windows-gnu", 1641 | "winapi-x86_64-pc-windows-gnu", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "winapi-i686-pc-windows-gnu" 1646 | version = "0.4.0" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1649 | 1650 | [[package]] 1651 | name = "winapi-x86_64-pc-windows-gnu" 1652 | version = "0.4.0" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1655 | 1656 | [[package]] 1657 | name = "windows-sys" 1658 | version = "0.48.0" 1659 | source = "registry+https://github.com/rust-lang/crates.io-index" 1660 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1661 | dependencies = [ 1662 | "windows-targets", 1663 | ] 1664 | 1665 | [[package]] 1666 | name = "windows-targets" 1667 | version = "0.48.5" 1668 | source = "registry+https://github.com/rust-lang/crates.io-index" 1669 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1670 | dependencies = [ 1671 | "windows_aarch64_gnullvm", 1672 | "windows_aarch64_msvc", 1673 | "windows_i686_gnu", 1674 | "windows_i686_msvc", 1675 | "windows_x86_64_gnu", 1676 | "windows_x86_64_gnullvm", 1677 | "windows_x86_64_msvc", 1678 | ] 1679 | 1680 | [[package]] 1681 | name = "windows_aarch64_gnullvm" 1682 | version = "0.48.5" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1685 | 1686 | [[package]] 1687 | name = "windows_aarch64_msvc" 1688 | version = "0.48.5" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1691 | 1692 | [[package]] 1693 | name = "windows_i686_gnu" 1694 | version = "0.48.5" 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" 1696 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1697 | 1698 | [[package]] 1699 | name = "windows_i686_msvc" 1700 | version = "0.48.5" 1701 | source = "registry+https://github.com/rust-lang/crates.io-index" 1702 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1703 | 1704 | [[package]] 1705 | name = "windows_x86_64_gnu" 1706 | version = "0.48.5" 1707 | source = "registry+https://github.com/rust-lang/crates.io-index" 1708 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1709 | 1710 | [[package]] 1711 | name = "windows_x86_64_gnullvm" 1712 | version = "0.48.5" 1713 | source = "registry+https://github.com/rust-lang/crates.io-index" 1714 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1715 | 1716 | [[package]] 1717 | name = "windows_x86_64_msvc" 1718 | version = "0.48.5" 1719 | source = "registry+https://github.com/rust-lang/crates.io-index" 1720 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1721 | 1722 | [[package]] 1723 | name = "xmlparser" 1724 | version = "0.13.5" 1725 | source = "registry+https://github.com/rust-lang/crates.io-index" 1726 | checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" 1727 | 1728 | [[package]] 1729 | name = "zeroize" 1730 | version = "1.6.0" 1731 | source = "registry+https://github.com/rust-lang/crates.io-index" 1732 | checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" 1733 | -------------------------------------------------------------------------------- /s3-admin-app/authorizer_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "authorizer-rust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | anyhow = "1.0.75" 10 | aws-config = "0.56.1" 11 | aws-sdk-dynamodb = "0.30.0" 12 | aws_lambda_events = { version = "0.10.0", default-features = false, features = ["apigw"] } 13 | base64 = "0.21.3" 14 | lambda_runtime = "0.8.1" 15 | serde = "1.0.136" 16 | serde_json = "1.0.105" 17 | tokio = { version = "1", features = ["macros"] } 18 | tracing = { version = "0.1", features = ["log"] } 19 | tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] } 20 | -------------------------------------------------------------------------------- /s3-admin-app/authorizer_rust/src/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{Context, Result}; 2 | use aws_lambda_events::apigw::{ 3 | ApiGatewayCustomAuthorizerPolicy, ApiGatewayCustomAuthorizerRequestTypeRequest, 4 | ApiGatewayCustomAuthorizerResponse, IamPolicyStatement, 5 | }; 6 | use aws_sdk_dynamodb::types::AttributeValue; 7 | use aws_sdk_dynamodb::Client; 8 | use base64::decode; 9 | use lambda_runtime::{service_fn, Error, LambdaEvent}; 10 | use serde_json::json; 11 | use tracing::info; 12 | use std::env; 13 | use std::option::Option; 14 | use std::str; 15 | 16 | const USERS_TABLE_NAME_ENV: &'static str = "USERS_TABLE_NAME"; 17 | 18 | #[tokio::main] 19 | async fn main() -> Result<(), Error> { 20 | tracing_subscriber::fmt() 21 | .without_time() 22 | .with_max_level(tracing::Level::INFO) 23 | .init(); 24 | 25 | let shared_config = aws_config::load_from_env().await; 26 | let client = Client::new(&shared_config); 27 | let func = service_fn(move |event| { 28 | let client_ref = client.clone(); 29 | async move { function_handler(event, &client_ref).await } 30 | }); 31 | 32 | lambda_runtime::run(func).await?; 33 | Ok(()) 34 | } 35 | 36 | async fn function_handler( 37 | event: LambdaEvent, 38 | client: &Client, 39 | ) -> Result { 40 | let method_arn = event 41 | .payload 42 | .method_arn 43 | .as_ref() 44 | .context("Method ARN is missing")?; 45 | if let Some(header_value) = event.payload.headers.get("authorization") { 46 | if let Ok(token_str) = str::from_utf8(header_value.as_bytes()) { 47 | let user_result = get_user_by_token(token_str, client).await?; 48 | let user = user_result.unwrap_or(String::from("NoUser")); 49 | let policy = if user == "NoUser" { "DENY" } else { "ALLOW" }; 50 | return Ok(custom_authorizer_response(policy, &user, method_arn)); 51 | } 52 | } 53 | 54 | Ok(custom_authorizer_response("DENY", "NoUser", method_arn)) 55 | } 56 | 57 | fn custom_authorizer_response( 58 | effect: &str, 59 | principal: &str, 60 | method_arn: &str, 61 | ) -> ApiGatewayCustomAuthorizerResponse { 62 | let stmt = IamPolicyStatement { 63 | action: vec!["execute-api:Invoke".to_string()], 64 | resource: vec![method_arn.to_owned()], 65 | effect: Some(effect.to_owned()), 66 | }; 67 | let policy = ApiGatewayCustomAuthorizerPolicy { 68 | version: Some("2012-10-17".to_string()), 69 | statement: vec![stmt], 70 | }; 71 | ApiGatewayCustomAuthorizerResponse { 72 | principal_id: Some(principal.to_owned()), 73 | policy_document: policy, 74 | context: json!({ "user": principal }), 75 | usage_identifier_key: None, 76 | } 77 | } 78 | 79 | async fn get_user_by_token(token: &str, client: &Client) -> Result, Error> { 80 | if token.starts_with("Basic") { 81 | let decoded_auth = decode(&token[6..]).unwrap(); 82 | let decoded_str = String::from_utf8(decoded_auth).unwrap(); 83 | let split: Vec<&str> = decoded_str.split(":").collect(); 84 | let (username, password) = (split[0], split[1]); 85 | 86 | let table_name = env::var(USERS_TABLE_NAME_ENV).unwrap(); 87 | 88 | let item = client 89 | .get_item() 90 | .table_name(table_name) 91 | .key("user", AttributeValue::S(String::from(username))) 92 | .send() 93 | .await?; 94 | 95 | let value = match item.item { 96 | Some(value) => value, 97 | None => { 98 | info!("NotApproved"); 99 | return Ok(None); 100 | } 101 | }; 102 | 103 | if password == value.get("password").unwrap().as_s().unwrap() { 104 | info!("Approved"); 105 | return Ok(Some(String::from(username))); 106 | } 107 | } 108 | info!("NotApproved"); 109 | Ok(None) 110 | } 111 | -------------------------------------------------------------------------------- /s3-admin-app/get-s3-details-node/.npmignore: -------------------------------------------------------------------------------- 1 | tests/* 2 | -------------------------------------------------------------------------------- /s3-admin-app/get-s3-details-node/app.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format 4 | * @param {Object} event - API Gateway Lambda Proxy Input Format 5 | * 6 | * Context doc: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html 7 | * @param {Object} context 8 | * 9 | * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html 10 | * @returns {Object} object - API Gateway Lambda Proxy Output Format 11 | * 12 | */ 13 | import axios from 'axios'; 14 | 15 | const url = "http://localhost:3001/v1/analytics"; 16 | 17 | export const lambdaHandler = async (event, context) => { 18 | 19 | const payload = { 20 | event: `some_event_type_${Math.floor(Math.random() * 100)}` 21 | }; 22 | try { 23 | // Send analytics event. 24 | const response = await axios.post(url, payload, { 25 | headers: { 26 | 'Content-Type': 'application/json' 27 | } 28 | }); 29 | 30 | console.log(`Status Code: ${response.status}`); 31 | console.log(`Response Data: ${JSON.stringify(response.data)}`); 32 | return { 33 | 'statusCode': 200, 34 | 'body': JSON.stringify({ 35 | message: 'hello world', 36 | }) 37 | } 38 | } catch (err) { 39 | console.log(err); 40 | return err; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /s3-admin-app/get-s3-details-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-s3-details", 3 | "version": "1.0.0", 4 | "description": "Get S3 bucket details", 5 | "main": "app.js", 6 | "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", 7 | "author": "SAM CLI", 8 | "license": "MIT", 9 | "dependencies": { 10 | "axios": ">=0.21.1" 11 | }, 12 | "scripts": {}, 13 | "devDependencies": {} 14 | } -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-node/.npmignore: -------------------------------------------------------------------------------- 1 | tests/* 2 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-node/app.mjs: -------------------------------------------------------------------------------- 1 | import { S3Client, ListBucketsCommand, GetBucketLocationCommand } from "@aws-sdk/client-s3" 2 | import { SignatureV4 } from "@smithy/signature-v4" 3 | import { HttpRequest } from "@smithy/protocol-http" 4 | import { defaultProvider } from "@aws-sdk/credential-provider-node" 5 | import { Sha256 } from "@aws-crypto/sha256-browser" 6 | 7 | const client = new S3Client(); 8 | const command = new ListBucketsCommand({}); 9 | 10 | const getBucketRegion = async (bucket) => { 11 | const bucketName = bucket.Name; 12 | const command = new GetBucketLocationCommand({ Bucket: bucketName }); 13 | 14 | try { 15 | const response = await client.send(command); 16 | const region = response.LocationConstraint || "us-east-1"; 17 | return [bucketName, region] 18 | } catch (error) { 19 | console.error(`Error getting region for bucket ${bucketName}:`, error); 20 | throw error; 21 | } 22 | } 23 | 24 | export const lambdaHandler = async (event, context) => { 25 | 26 | try { 27 | const response = await client.send(command); 28 | const regionPromises = response.Buckets.map(getBucketRegion); 29 | const results = await Promise.all(regionPromises); 30 | return { 31 | statusCode: 200, 32 | body: JSON.stringify(results), 33 | } 34 | } catch (err) { 35 | console.log(err); 36 | return err; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-s3-details", 3 | "version": "1.0.0", 4 | "description": "Get S3 bucket details", 5 | "main": "app.js", 6 | "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", 7 | "author": "SAM CLI", 8 | "license": "MIT", 9 | "dependencies": { 10 | "@aws-sdk/client-s3": "^3.498.0" 11 | }, 12 | "scripts": {} 13 | } 14 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-rust-node/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variables file 76 | .env 77 | .env.test 78 | 79 | # parcel-bundler cache (https://parceljs.org/) 80 | .cache 81 | 82 | # Next.js build output 83 | .next 84 | 85 | # Nuxt.js build / generate output 86 | .nuxt 87 | dist 88 | 89 | # Gatsby files 90 | .cache/ 91 | # Comment in the public line in if your project uses Gatsby and not Next.js 92 | # https://nextjs.org/blog/next-9-1#public-directory-support 93 | # public 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # TernJS port file 108 | .tern-port 109 | 110 | # Stores VSCode versions used for testing VSCode extensions 111 | .vscode-test 112 | 113 | # End of https://www.toptal.com/developers/gitignore/api/node 114 | 115 | # Created by https://www.toptal.com/developers/gitignore/api/macos 116 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos 117 | 118 | ### macOS ### 119 | # General 120 | .DS_Store 121 | .AppleDouble 122 | .LSOverride 123 | 124 | # Icon must end with two 125 | Icon 126 | 127 | 128 | # Thumbnails 129 | ._* 130 | 131 | # Files that might appear in the root of a volume 132 | .DocumentRevisions-V100 133 | .fseventsd 134 | .Spotlight-V100 135 | .TemporaryItems 136 | .Trashes 137 | .VolumeIcon.icns 138 | .com.apple.timemachine.donotpresent 139 | 140 | # Directories potentially created on remote AFP share 141 | .AppleDB 142 | .AppleDesktop 143 | Network Trash Folder 144 | Temporary Items 145 | .apdisk 146 | 147 | ### macOS Patch ### 148 | # iCloud generated files 149 | *.icloud 150 | 151 | # End of https://www.toptal.com/developers/gitignore/api/macos 152 | 153 | # Created by https://www.toptal.com/developers/gitignore/api/windows 154 | # Edit at https://www.toptal.com/developers/gitignore?templates=windows 155 | 156 | ### Windows ### 157 | # Windows thumbnail cache files 158 | Thumbs.db 159 | Thumbs.db:encryptable 160 | ehthumbs.db 161 | ehthumbs_vista.db 162 | 163 | # Dump file 164 | *.stackdump 165 | 166 | # Folder config file 167 | [Dd]esktop.ini 168 | 169 | # Recycle Bin used on file shares 170 | $RECYCLE.BIN/ 171 | 172 | # Windows Installer files 173 | *.cab 174 | *.msi 175 | *.msix 176 | *.msm 177 | *.msp 178 | 179 | # Windows shortcuts 180 | *.lnk 181 | 182 | # End of https://www.toptal.com/developers/gitignore/api/windows 183 | 184 | #Added by cargo 185 | 186 | /target 187 | Cargo.lock 188 | 189 | .pnp.* 190 | .yarn/* 191 | !.yarn/patches 192 | !.yarn/plugins 193 | !.yarn/releases 194 | !.yarn/sdks 195 | !.yarn/versions 196 | 197 | *.node 198 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-rust-node/.npmignore: -------------------------------------------------------------------------------- 1 | tests/* 2 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-rust-node/app.mjs: -------------------------------------------------------------------------------- 1 | import { S3OpsRust } from "./index.js" 2 | 3 | const s3ops = new S3OpsRust(); 4 | 5 | export const lambdaHandler = async (event, context) => { 6 | 7 | try { 8 | const results = s3ops.listBuckets(); 9 | return { 10 | statusCode: 200, 11 | body: JSON.stringify(results), 12 | } 13 | } catch (err) { 14 | console.log(err); 15 | return err; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-rust-node/index.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | 4 | /* auto-generated by NAPI-RS */ 5 | 6 | export interface BucketDetails { 7 | name: string 8 | location: string 9 | } 10 | export function sign(host: string, url: string): Promise 11 | export class S3OpsRust { 12 | constructor() 13 | listBuckets(): Array 14 | } 15 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-rust-node/index.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /* prettier-ignore */ 4 | 5 | /* auto-generated by NAPI-RS */ 6 | 7 | const { existsSync, readFileSync } = require('fs') 8 | const { join } = require('path') 9 | 10 | const { platform, arch } = process 11 | 12 | let nativeBinding = null 13 | let localFileExisted = false 14 | let loadError = null 15 | 16 | function isMusl() { 17 | // For Node 10 18 | if (!process.report || typeof process.report.getReport !== 'function') { 19 | try { 20 | const lddPath = require('child_process').execSync('which ldd').toString().trim() 21 | return readFileSync(lddPath, 'utf8').includes('musl') 22 | } catch (e) { 23 | return true 24 | } 25 | } else { 26 | const { glibcVersionRuntime } = process.report.getReport().header 27 | return !glibcVersionRuntime 28 | } 29 | } 30 | 31 | switch (platform) { 32 | case 'android': 33 | switch (arch) { 34 | case 'arm64': 35 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.android-arm64.node')) 36 | try { 37 | if (localFileExisted) { 38 | nativeBinding = require('./s3-ops-rust-napi-lib.android-arm64.node') 39 | } else { 40 | nativeBinding = require('s3-ops-rust-napi-lib-android-arm64') 41 | } 42 | } catch (e) { 43 | loadError = e 44 | } 45 | break 46 | case 'arm': 47 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.android-arm-eabi.node')) 48 | try { 49 | if (localFileExisted) { 50 | nativeBinding = require('./s3-ops-rust-napi-lib.android-arm-eabi.node') 51 | } else { 52 | nativeBinding = require('s3-ops-rust-napi-lib-android-arm-eabi') 53 | } 54 | } catch (e) { 55 | loadError = e 56 | } 57 | break 58 | default: 59 | throw new Error(`Unsupported architecture on Android ${arch}`) 60 | } 61 | break 62 | case 'win32': 63 | switch (arch) { 64 | case 'x64': 65 | localFileExisted = existsSync( 66 | join(__dirname, 's3-ops-rust-napi-lib.win32-x64-msvc.node') 67 | ) 68 | try { 69 | if (localFileExisted) { 70 | nativeBinding = require('./s3-ops-rust-napi-lib.win32-x64-msvc.node') 71 | } else { 72 | nativeBinding = require('s3-ops-rust-napi-lib-win32-x64-msvc') 73 | } 74 | } catch (e) { 75 | loadError = e 76 | } 77 | break 78 | case 'ia32': 79 | localFileExisted = existsSync( 80 | join(__dirname, 's3-ops-rust-napi-lib.win32-ia32-msvc.node') 81 | ) 82 | try { 83 | if (localFileExisted) { 84 | nativeBinding = require('./s3-ops-rust-napi-lib.win32-ia32-msvc.node') 85 | } else { 86 | nativeBinding = require('s3-ops-rust-napi-lib-win32-ia32-msvc') 87 | } 88 | } catch (e) { 89 | loadError = e 90 | } 91 | break 92 | case 'arm64': 93 | localFileExisted = existsSync( 94 | join(__dirname, 's3-ops-rust-napi-lib.win32-arm64-msvc.node') 95 | ) 96 | try { 97 | if (localFileExisted) { 98 | nativeBinding = require('./s3-ops-rust-napi-lib.win32-arm64-msvc.node') 99 | } else { 100 | nativeBinding = require('s3-ops-rust-napi-lib-win32-arm64-msvc') 101 | } 102 | } catch (e) { 103 | loadError = e 104 | } 105 | break 106 | default: 107 | throw new Error(`Unsupported architecture on Windows: ${arch}`) 108 | } 109 | break 110 | case 'darwin': 111 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.darwin-universal.node')) 112 | try { 113 | if (localFileExisted) { 114 | nativeBinding = require('./s3-ops-rust-napi-lib.darwin-universal.node') 115 | } else { 116 | nativeBinding = require('s3-ops-rust-napi-lib-darwin-universal') 117 | } 118 | break 119 | } catch {} 120 | switch (arch) { 121 | case 'x64': 122 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.darwin-x64.node')) 123 | try { 124 | if (localFileExisted) { 125 | nativeBinding = require('./s3-ops-rust-napi-lib.darwin-x64.node') 126 | } else { 127 | nativeBinding = require('s3-ops-rust-napi-lib-darwin-x64') 128 | } 129 | } catch (e) { 130 | loadError = e 131 | } 132 | break 133 | case 'arm64': 134 | localFileExisted = existsSync( 135 | join(__dirname, 's3-ops-rust-napi-lib.darwin-arm64.node') 136 | ) 137 | try { 138 | if (localFileExisted) { 139 | nativeBinding = require('./s3-ops-rust-napi-lib.darwin-arm64.node') 140 | } else { 141 | nativeBinding = require('s3-ops-rust-napi-lib-darwin-arm64') 142 | } 143 | } catch (e) { 144 | loadError = e 145 | } 146 | break 147 | default: 148 | throw new Error(`Unsupported architecture on macOS: ${arch}`) 149 | } 150 | break 151 | case 'freebsd': 152 | if (arch !== 'x64') { 153 | throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) 154 | } 155 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.freebsd-x64.node')) 156 | try { 157 | if (localFileExisted) { 158 | nativeBinding = require('./s3-ops-rust-napi-lib.freebsd-x64.node') 159 | } else { 160 | nativeBinding = require('s3-ops-rust-napi-lib-freebsd-x64') 161 | } 162 | } catch (e) { 163 | loadError = e 164 | } 165 | break 166 | case 'linux': 167 | switch (arch) { 168 | case 'x64': 169 | if (isMusl()) { 170 | localFileExisted = existsSync( 171 | join(__dirname, 's3-ops-rust-napi-lib.linux-x64-musl.node') 172 | ) 173 | try { 174 | if (localFileExisted) { 175 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-x64-musl.node') 176 | } else { 177 | nativeBinding = require('s3-ops-rust-napi-lib-linux-x64-musl') 178 | } 179 | } catch (e) { 180 | loadError = e 181 | } 182 | } else { 183 | localFileExisted = existsSync( 184 | join(__dirname, 's3-ops-rust-napi-lib.linux-x64-gnu.node') 185 | ) 186 | try { 187 | if (localFileExisted) { 188 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-x64-gnu.node') 189 | } else { 190 | nativeBinding = require('s3-ops-rust-napi-lib-linux-x64-gnu') 191 | } 192 | } catch (e) { 193 | loadError = e 194 | } 195 | } 196 | break 197 | case 'arm64': 198 | if (isMusl()) { 199 | localFileExisted = existsSync( 200 | join(__dirname, 's3-ops-rust-napi-lib.linux-arm64-musl.node') 201 | ) 202 | try { 203 | if (localFileExisted) { 204 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-arm64-musl.node') 205 | } else { 206 | nativeBinding = require('s3-ops-rust-napi-lib-linux-arm64-musl') 207 | } 208 | } catch (e) { 209 | loadError = e 210 | } 211 | } else { 212 | localFileExisted = existsSync( 213 | join(__dirname, 's3-ops-rust-napi-lib.linux-arm64-gnu.node') 214 | ) 215 | try { 216 | if (localFileExisted) { 217 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-arm64-gnu.node') 218 | } else { 219 | nativeBinding = require('s3-ops-rust-napi-lib-linux-arm64-gnu') 220 | } 221 | } catch (e) { 222 | loadError = e 223 | } 224 | } 225 | break 226 | case 'arm': 227 | localFileExisted = existsSync( 228 | join(__dirname, 's3-ops-rust-napi-lib.linux-arm-gnueabihf.node') 229 | ) 230 | try { 231 | if (localFileExisted) { 232 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-arm-gnueabihf.node') 233 | } else { 234 | nativeBinding = require('s3-ops-rust-napi-lib-linux-arm-gnueabihf') 235 | } 236 | } catch (e) { 237 | loadError = e 238 | } 239 | break 240 | case 'riscv64': 241 | if (isMusl()) { 242 | localFileExisted = existsSync( 243 | join(__dirname, 's3-ops-rust-napi-lib.linux-riscv64-musl.node') 244 | ) 245 | try { 246 | if (localFileExisted) { 247 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-riscv64-musl.node') 248 | } else { 249 | nativeBinding = require('s3-ops-rust-napi-lib-linux-riscv64-musl') 250 | } 251 | } catch (e) { 252 | loadError = e 253 | } 254 | } else { 255 | localFileExisted = existsSync( 256 | join(__dirname, 's3-ops-rust-napi-lib.linux-riscv64-gnu.node') 257 | ) 258 | try { 259 | if (localFileExisted) { 260 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-riscv64-gnu.node') 261 | } else { 262 | nativeBinding = require('s3-ops-rust-napi-lib-linux-riscv64-gnu') 263 | } 264 | } catch (e) { 265 | loadError = e 266 | } 267 | } 268 | break 269 | default: 270 | throw new Error(`Unsupported architecture on Linux: ${arch}`) 271 | } 272 | break 273 | default: 274 | throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) 275 | } 276 | 277 | if (!nativeBinding) { 278 | if (loadError) { 279 | throw loadError 280 | } 281 | throw new Error(`Failed to load native binding`) 282 | } 283 | 284 | const { S3OpsRust, sign } = nativeBinding 285 | 286 | module.exports.S3OpsRust = S3OpsRust 287 | module.exports.sign = sign 288 | -------------------------------------------------------------------------------- /s3-admin-app/list-buckets-rust-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-s3-details", 3 | "version": "1.0.0", 4 | "description": "Get S3 bucket details", 5 | "main": "app.js", 6 | "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", 7 | "author": "SAM CLI", 8 | "license": "MIT", 9 | "dependencies": {}, 10 | "scripts": {} 11 | } -------------------------------------------------------------------------------- /s3-admin-app/list_buckets_python/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fun-with-serverless/rustifying-serverless/4febf36cbad815154c7cf8c91287a1cd80a695c8/s3-admin-app/list_buckets_python/__init__.py -------------------------------------------------------------------------------- /s3-admin-app/list_buckets_python/app.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from typing import List, Tuple 3 | from aws_lambda_powertools import Logger 4 | from aws_lambda_powertools.event_handler import APIGatewayRestResolver 5 | import boto3 6 | from aiobotocore.session import get_session 7 | from aiobotocore.config import AioConfig 8 | import uvloop 9 | 10 | logger = Logger() 11 | app = APIGatewayRestResolver() 12 | s3_client = boto3.client("s3") 13 | 14 | 15 | @logger.inject_lambda_context(log_event=True) 16 | def lambda_handler(event, context): 17 | return app.resolve(event, context) 18 | 19 | 20 | @app.get("/buckets-python") 21 | def get_buckets_python() -> List[dict]: 22 | s3_buckets = s3_client.list_buckets() 23 | bucket_info_list = [] 24 | 25 | with asyncio.Runner(loop_factory=uvloop.new_event_loop) as runner: 26 | bucket_info_list = runner.run(get_buckets_region(s3_buckets["Buckets"])) 27 | 28 | return bucket_info_list 29 | 30 | 31 | async def get_buckets_region(buckets: List[str]) -> List[Tuple[str, str]]: 32 | session = get_session() 33 | bucket_info_list = [] 34 | 35 | async with session.create_client("s3", config=AioConfig(retries={"max_attempts": 0}) ) as s3_client: 36 | tasks = [ 37 | get_bucket_info(s3_client, bucket["Name"]) for bucket in buckets 38 | ] 39 | 40 | # Run the batch of tasks and collect results 41 | results = await asyncio.gather(*tasks) 42 | 43 | # Add results to bucket_info_list 44 | bucket_info_list.extend(results) 45 | 46 | return bucket_info_list 47 | 48 | 49 | async def get_bucket_info(s3_client, bucket_name: str): 50 | bucket_location = await s3_client.get_bucket_location(Bucket=bucket_name) 51 | region = bucket_location["LocationConstraint"] or "us-east-1" 52 | return {"name": bucket_name, "region": region} 53 | -------------------------------------------------------------------------------- /s3-admin-app/list_buckets_python/requirements.txt: -------------------------------------------------------------------------------- 1 | aiobotocore 2 | aws-lambda-powertools 3 | uvloop 4 | aiolimiter -------------------------------------------------------------------------------- /s3-admin-app/list_buckets_rust_python/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fun-with-serverless/rustifying-serverless/4febf36cbad815154c7cf8c91287a1cd80a695c8/s3-admin-app/list_buckets_rust_python/__init__.py -------------------------------------------------------------------------------- /s3-admin-app/list_buckets_rust_python/app.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from aws_lambda_powertools import Logger 3 | from aws_lambda_powertools.event_handler import APIGatewayRestResolver 4 | import s3_ops_rust 5 | 6 | logger = Logger() 7 | app = APIGatewayRestResolver() 8 | 9 | s3_client = s3_ops_rust.S3OpsRust() 10 | 11 | # @logger.inject_lambda_context(log_event=True) 12 | def lambda_handler(event, context): 13 | return app.resolve(event, context) 14 | 15 | 16 | @app.get("/buckets-rust") 17 | def get_buckets_rust() -> List[dict]: 18 | return s3_client.list_buckets() 19 | 20 | -------------------------------------------------------------------------------- /s3-admin-app/list_buckets_rust_python/requirements.txt: -------------------------------------------------------------------------------- 1 | ../.rust-lib/s3_ops_rust-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 2 | aws-lambda-powertools -------------------------------------------------------------------------------- /s3-admin-app/samconfig.toml: -------------------------------------------------------------------------------- 1 | # More information about the configuration file can be found here: 2 | # https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html 3 | version = 0.1 4 | 5 | [default] 6 | [default.global.parameters] 7 | stack_name = "s3-admin" 8 | 9 | [default.build.parameters] 10 | cached = true 11 | parallel = true 12 | beta_features = true 13 | 14 | [default.validate.parameters] 15 | lint = true 16 | 17 | [default.deploy.parameters] 18 | capabilities = "CAPABILITY_IAM" 19 | confirm_changeset = false 20 | resolve_s3 = true 21 | s3_prefix = "s3-admin" 22 | region = "us-east-1" 23 | image_repositories = [] 24 | 25 | [default.package.parameters] 26 | resolve_s3 = true 27 | 28 | [default.sync.parameters] 29 | watch = true 30 | beta_features = true 31 | 32 | [default.local_start_api.parameters] 33 | warm_containers = "EAGER" 34 | 35 | [default.local_start_lambda.parameters] 36 | warm_containers = "EAGER" 37 | -------------------------------------------------------------------------------- /s3-admin-app/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Manage your S3 buckets 4 | 5 | Globals: 6 | Function: 7 | Timeout: 10 8 | Layers: 9 | - arn:aws:lambda:us-east-1:234138278568:layer:analytics-extension:8 10 | Environment: 11 | Variables: 12 | ANALYTICS_SQS_URL: !Ref AnalyticsSQS 13 | 14 | Resources: 15 | RootApiRust: 16 | Type: AWS::Serverless::Api 17 | Properties: 18 | StageName: Prod 19 | Auth: 20 | DefaultAuthorizer: LambdaRequestAuthorizer 21 | Authorizers: 22 | LambdaRequestAuthorizer: 23 | FunctionArn: !GetAtt AuthorizerRust.Arn 24 | FunctionPayloadType: REQUEST 25 | Identity: 26 | Headers: 27 | - Authorization 28 | RootApiPython: 29 | Type: AWS::Serverless::Api 30 | Properties: 31 | StageName: Prod 32 | Auth: 33 | DefaultAuthorizer: LambdaRequestAuthorizer 34 | Authorizers: 35 | LambdaRequestAuthorizer: 36 | FunctionArn: !GetAtt AuthorizerPython.Arn 37 | FunctionPayloadType: REQUEST 38 | Identity: 39 | Headers: 40 | - Authorization 41 | 42 | AuthorizerPython: 43 | Type: AWS::Serverless::Function 44 | Properties: 45 | CodeUri: authorizer_python/ 46 | Handler: app.lambda_handler 47 | Runtime: python3.11 48 | Policies: 49 | - DynamoDBReadPolicy: 50 | TableName: !Ref UsersTable 51 | Environment: 52 | Variables: 53 | POWERTOOLS_SERVICE_NAME: auth 54 | LOG_LEVEL: INFO 55 | USERS_TABLE_NAME: !Ref UsersTable 56 | Architectures: 57 | - x86_64 58 | AuthorizerRust: 59 | Type: AWS::Serverless::Function 60 | Metadata: 61 | BuildMethod: rust-cargolambda 62 | Properties: 63 | CodeUri: ./authorizer_rust 64 | Handler: bootstrap 65 | Runtime: provided.al2 66 | Policies: 67 | - DynamoDBReadPolicy: 68 | TableName: !Ref UsersTable 69 | Environment: 70 | Variables: 71 | USERS_TABLE_NAME: !Ref UsersTable 72 | Architectures: 73 | - x86_64 74 | 75 | ListBucketsPython: 76 | Type: AWS::Serverless::Function 77 | Properties: 78 | CodeUri: list_buckets_python/ 79 | Handler: app.lambda_handler 80 | Runtime: python3.11 81 | Policies: 82 | - Version: "2012-10-17" 83 | Statement: 84 | - Effect: Allow 85 | Action: 86 | - s3:ListAllMyBuckets 87 | - s3:GetBucketLocation 88 | Resource: "*" 89 | Architectures: 90 | - x86_64 91 | Events: 92 | ListBcuketsPython: 93 | Type: Api 94 | Properties: 95 | RestApiId: !Ref RootApiPython 96 | Path: /buckets-python 97 | Method: get 98 | 99 | ListBucketsNode: 100 | Type: AWS::Serverless::Function 101 | Properties: 102 | CodeUri: list-buckets-node/ 103 | Handler: app.lambdaHandler 104 | Runtime: nodejs20.x 105 | Policies: 106 | - Version: "2012-10-17" 107 | Statement: 108 | - Effect: Allow 109 | Action: 110 | - s3:ListAllMyBuckets 111 | - s3:GetBucketLocation 112 | Resource: "*" 113 | Architectures: 114 | - x86_64 115 | Events: 116 | ListBucketsNode: 117 | Type: Api 118 | Properties: 119 | RestApiId: !Ref RootApiPython 120 | Path: /buckets-node 121 | Method: get 122 | 123 | ListBucketsRustNode: 124 | Type: AWS::Serverless::Function 125 | Properties: 126 | CodeUri: list-buckets-rust-node/ 127 | Handler: app.lambdaHandler 128 | Runtime: nodejs20.x 129 | Policies: 130 | - Version: "2012-10-17" 131 | Statement: 132 | - Effect: Allow 133 | Action: 134 | - s3:ListAllMyBuckets 135 | - s3:GetBucketLocation 136 | Resource: "*" 137 | Architectures: 138 | - x86_64 139 | Events: 140 | ListBucketsRustNode: 141 | Type: Api 142 | Properties: 143 | RestApiId: !Ref RootApiRust 144 | Path: /buckets-rust-node 145 | Method: get 146 | 147 | 148 | ListBucketsRustPython: 149 | Type: AWS::Serverless::Function 150 | Properties: 151 | CodeUri: list_buckets_rust_python/ 152 | Handler: app.lambda_handler 153 | Runtime: python3.11 154 | Policies: 155 | - Version: "2012-10-17" 156 | Statement: 157 | - Effect: Allow 158 | Action: 159 | - s3:ListAllMyBuckets 160 | - s3:GetBucketLocation 161 | Resource: "*" 162 | Architectures: 163 | - x86_64 164 | Events: 165 | ListBucketsRustPython: 166 | Type: Api 167 | Properties: 168 | RestApiId: !Ref RootApiRust 169 | Path: /buckets-rust-python 170 | Method: get 171 | 172 | GetS3Details: 173 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 174 | Properties: 175 | CodeUri: get-s3-details-node/ 176 | Handler: app.lambdaHandler 177 | Runtime: nodejs18.x 178 | Architectures: 179 | - x86_64 180 | Policies: 181 | - SQSSendMessagePolicy: 182 | QueueName: !GetAtt AnalyticsSQS.QueueName 183 | Events: 184 | GetS3Details: 185 | Type: Api 186 | Properties: 187 | RestApiId: !Ref RootApiRust 188 | Path: /get-bucket 189 | Method: get 190 | 191 | UsersTable: 192 | Type: AWS::DynamoDB::Table 193 | Properties: 194 | AttributeDefinitions: 195 | - AttributeName: user 196 | AttributeType: S 197 | KeySchema: 198 | - AttributeName: user 199 | KeyType: HASH 200 | BillingMode: PAY_PER_REQUEST 201 | 202 | AnalyticsSQS: 203 | Type: AWS::SQS::Queue 204 | 205 | Outputs: 206 | S3AdminApiListNode: 207 | Value: !Sub "curl -u 'admin:CTax;#+9+X3T%|z' https://${RootApiPython}.execute-api.${AWS::Region}.amazonaws.com/Prod/buckets-node" 208 | S3AdminApiListPython: 209 | Value: !Sub "curl -u 'admin:CTax;#+9+X3T%|z' https://${RootApiPython}.execute-api.${AWS::Region}.amazonaws.com/Prod/buckets-python" 210 | S3AdminApiListRust: 211 | Value: !Sub "curl -u 'admin:CTax;#+9+X3T%|z' https://${RootApiRust}.execute-api.${AWS::Region}.amazonaws.com/Prod/buckets-rust-python" 212 | S3AdminApiListNodeRust: 213 | Value: !Sub "curl -u 'admin:CTax;#+9+X3T%|z' https://${RootApiRust}.execute-api.${AWS::Region}.amazonaws.com/Prod/buckets-rust-node" 214 | GetS3DetailsNode: 215 | Value: !Sub "curl -u 'admin:CTax;#+9+X3T%|z' https://${RootApiRust}.execute-api.${AWS::Region}.amazonaws.com/Prod/get-bucket" 216 | DynamoDB: 217 | Value: !Sub "aws dynamodb put-item --table-name ${UsersTable} --item '{\"user\": {\"S\": \"admin\"}, \"password\": {\"S\": \"CTax;#+9+X3T%|z\"}}' --return-consumed-capacity TOTAL" 218 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variables file 76 | .env 77 | .env.test 78 | 79 | # parcel-bundler cache (https://parceljs.org/) 80 | .cache 81 | 82 | # Next.js build output 83 | .next 84 | 85 | # Nuxt.js build / generate output 86 | .nuxt 87 | dist 88 | 89 | # Gatsby files 90 | .cache/ 91 | # Comment in the public line in if your project uses Gatsby and not Next.js 92 | # https://nextjs.org/blog/next-9-1#public-directory-support 93 | # public 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # TernJS port file 108 | .tern-port 109 | 110 | # Stores VSCode versions used for testing VSCode extensions 111 | .vscode-test 112 | 113 | # End of https://www.toptal.com/developers/gitignore/api/node 114 | 115 | # Created by https://www.toptal.com/developers/gitignore/api/macos 116 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos 117 | 118 | ### macOS ### 119 | # General 120 | .DS_Store 121 | .AppleDouble 122 | .LSOverride 123 | 124 | # Icon must end with two 125 | Icon 126 | 127 | 128 | # Thumbnails 129 | ._* 130 | 131 | # Files that might appear in the root of a volume 132 | .DocumentRevisions-V100 133 | .fseventsd 134 | .Spotlight-V100 135 | .TemporaryItems 136 | .Trashes 137 | .VolumeIcon.icns 138 | .com.apple.timemachine.donotpresent 139 | 140 | # Directories potentially created on remote AFP share 141 | .AppleDB 142 | .AppleDesktop 143 | Network Trash Folder 144 | Temporary Items 145 | .apdisk 146 | 147 | ### macOS Patch ### 148 | # iCloud generated files 149 | *.icloud 150 | 151 | # End of https://www.toptal.com/developers/gitignore/api/macos 152 | 153 | # Created by https://www.toptal.com/developers/gitignore/api/windows 154 | # Edit at https://www.toptal.com/developers/gitignore?templates=windows 155 | 156 | ### Windows ### 157 | # Windows thumbnail cache files 158 | Thumbs.db 159 | Thumbs.db:encryptable 160 | ehthumbs.db 161 | ehthumbs_vista.db 162 | 163 | # Dump file 164 | *.stackdump 165 | 166 | # Folder config file 167 | [Dd]esktop.ini 168 | 169 | # Recycle Bin used on file shares 170 | $RECYCLE.BIN/ 171 | 172 | # Windows Installer files 173 | *.cab 174 | *.msi 175 | *.msix 176 | *.msm 177 | *.msp 178 | 179 | # Windows shortcuts 180 | *.lnk 181 | 182 | # End of https://www.toptal.com/developers/gitignore/api/windows 183 | 184 | #Added by cargo 185 | 186 | /target 187 | Cargo.lock 188 | 189 | .pnp.* 190 | .yarn/* 191 | !.yarn/patches 192 | !.yarn/plugins 193 | !.yarn/releases 194 | !.yarn/sdks 195 | !.yarn/versions 196 | 197 | *.node 198 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/.npmignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | .cargo 4 | .github 5 | npm 6 | .eslintrc 7 | .prettierignore 8 | rustfmt.toml 9 | yarn.lock 10 | *.node 11 | .yarn 12 | __test__ 13 | renovate.json 14 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-4.0.2.cjs 4 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2021" 3 | name = "s3-ops-rust-napi-lib" 4 | version = "0.0.0" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | aws-config = "1.1.2" 11 | aws-sdk-s3 = "1.12.0" 12 | futures = "0.3.30" 13 | # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix 14 | napi = { version = "2.12.2", default-features = false, features = ["napi4"] } 15 | napi-derive = "2.14.6" 16 | tokio = { version = "1.35.1", features = ["rt", "rt-multi-thread"] } 17 | 18 | [build-dependencies] 19 | napi-build = "2.0.1" 20 | 21 | [profile.release] 22 | lto = true 23 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/build.rs: -------------------------------------------------------------------------------- 1 | extern crate napi_build; 2 | 3 | fn main() { 4 | napi_build::setup(); 5 | } 6 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/index.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | 4 | /* auto-generated by NAPI-RS */ 5 | 6 | export interface BucketDetails { 7 | name: string 8 | location: string 9 | } 10 | export function sign(host: string, url: string): Promise 11 | export class S3OpsRust { 12 | constructor() 13 | listBuckets(): Array 14 | } 15 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/index.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /* prettier-ignore */ 4 | 5 | /* auto-generated by NAPI-RS */ 6 | 7 | const { existsSync, readFileSync } = require('fs') 8 | const { join } = require('path') 9 | 10 | const { platform, arch } = process 11 | 12 | let nativeBinding = null 13 | let localFileExisted = false 14 | let loadError = null 15 | 16 | function isMusl() { 17 | // For Node 10 18 | if (!process.report || typeof process.report.getReport !== 'function') { 19 | try { 20 | const lddPath = require('child_process').execSync('which ldd').toString().trim() 21 | return readFileSync(lddPath, 'utf8').includes('musl') 22 | } catch (e) { 23 | return true 24 | } 25 | } else { 26 | const { glibcVersionRuntime } = process.report.getReport().header 27 | return !glibcVersionRuntime 28 | } 29 | } 30 | 31 | switch (platform) { 32 | case 'android': 33 | switch (arch) { 34 | case 'arm64': 35 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.android-arm64.node')) 36 | try { 37 | if (localFileExisted) { 38 | nativeBinding = require('./s3-ops-rust-napi-lib.android-arm64.node') 39 | } else { 40 | nativeBinding = require('s3-ops-rust-napi-lib-android-arm64') 41 | } 42 | } catch (e) { 43 | loadError = e 44 | } 45 | break 46 | case 'arm': 47 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.android-arm-eabi.node')) 48 | try { 49 | if (localFileExisted) { 50 | nativeBinding = require('./s3-ops-rust-napi-lib.android-arm-eabi.node') 51 | } else { 52 | nativeBinding = require('s3-ops-rust-napi-lib-android-arm-eabi') 53 | } 54 | } catch (e) { 55 | loadError = e 56 | } 57 | break 58 | default: 59 | throw new Error(`Unsupported architecture on Android ${arch}`) 60 | } 61 | break 62 | case 'win32': 63 | switch (arch) { 64 | case 'x64': 65 | localFileExisted = existsSync( 66 | join(__dirname, 's3-ops-rust-napi-lib.win32-x64-msvc.node') 67 | ) 68 | try { 69 | if (localFileExisted) { 70 | nativeBinding = require('./s3-ops-rust-napi-lib.win32-x64-msvc.node') 71 | } else { 72 | nativeBinding = require('s3-ops-rust-napi-lib-win32-x64-msvc') 73 | } 74 | } catch (e) { 75 | loadError = e 76 | } 77 | break 78 | case 'ia32': 79 | localFileExisted = existsSync( 80 | join(__dirname, 's3-ops-rust-napi-lib.win32-ia32-msvc.node') 81 | ) 82 | try { 83 | if (localFileExisted) { 84 | nativeBinding = require('./s3-ops-rust-napi-lib.win32-ia32-msvc.node') 85 | } else { 86 | nativeBinding = require('s3-ops-rust-napi-lib-win32-ia32-msvc') 87 | } 88 | } catch (e) { 89 | loadError = e 90 | } 91 | break 92 | case 'arm64': 93 | localFileExisted = existsSync( 94 | join(__dirname, 's3-ops-rust-napi-lib.win32-arm64-msvc.node') 95 | ) 96 | try { 97 | if (localFileExisted) { 98 | nativeBinding = require('./s3-ops-rust-napi-lib.win32-arm64-msvc.node') 99 | } else { 100 | nativeBinding = require('s3-ops-rust-napi-lib-win32-arm64-msvc') 101 | } 102 | } catch (e) { 103 | loadError = e 104 | } 105 | break 106 | default: 107 | throw new Error(`Unsupported architecture on Windows: ${arch}`) 108 | } 109 | break 110 | case 'darwin': 111 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.darwin-universal.node')) 112 | try { 113 | if (localFileExisted) { 114 | nativeBinding = require('./s3-ops-rust-napi-lib.darwin-universal.node') 115 | } else { 116 | nativeBinding = require('s3-ops-rust-napi-lib-darwin-universal') 117 | } 118 | break 119 | } catch {} 120 | switch (arch) { 121 | case 'x64': 122 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.darwin-x64.node')) 123 | try { 124 | if (localFileExisted) { 125 | nativeBinding = require('./s3-ops-rust-napi-lib.darwin-x64.node') 126 | } else { 127 | nativeBinding = require('s3-ops-rust-napi-lib-darwin-x64') 128 | } 129 | } catch (e) { 130 | loadError = e 131 | } 132 | break 133 | case 'arm64': 134 | localFileExisted = existsSync( 135 | join(__dirname, 's3-ops-rust-napi-lib.darwin-arm64.node') 136 | ) 137 | try { 138 | if (localFileExisted) { 139 | nativeBinding = require('./s3-ops-rust-napi-lib.darwin-arm64.node') 140 | } else { 141 | nativeBinding = require('s3-ops-rust-napi-lib-darwin-arm64') 142 | } 143 | } catch (e) { 144 | loadError = e 145 | } 146 | break 147 | default: 148 | throw new Error(`Unsupported architecture on macOS: ${arch}`) 149 | } 150 | break 151 | case 'freebsd': 152 | if (arch !== 'x64') { 153 | throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) 154 | } 155 | localFileExisted = existsSync(join(__dirname, 's3-ops-rust-napi-lib.freebsd-x64.node')) 156 | try { 157 | if (localFileExisted) { 158 | nativeBinding = require('./s3-ops-rust-napi-lib.freebsd-x64.node') 159 | } else { 160 | nativeBinding = require('s3-ops-rust-napi-lib-freebsd-x64') 161 | } 162 | } catch (e) { 163 | loadError = e 164 | } 165 | break 166 | case 'linux': 167 | switch (arch) { 168 | case 'x64': 169 | if (isMusl()) { 170 | localFileExisted = existsSync( 171 | join(__dirname, 's3-ops-rust-napi-lib.linux-x64-musl.node') 172 | ) 173 | try { 174 | if (localFileExisted) { 175 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-x64-musl.node') 176 | } else { 177 | nativeBinding = require('s3-ops-rust-napi-lib-linux-x64-musl') 178 | } 179 | } catch (e) { 180 | loadError = e 181 | } 182 | } else { 183 | localFileExisted = existsSync( 184 | join(__dirname, 's3-ops-rust-napi-lib.linux-x64-gnu.node') 185 | ) 186 | try { 187 | if (localFileExisted) { 188 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-x64-gnu.node') 189 | } else { 190 | nativeBinding = require('s3-ops-rust-napi-lib-linux-x64-gnu') 191 | } 192 | } catch (e) { 193 | loadError = e 194 | } 195 | } 196 | break 197 | case 'arm64': 198 | if (isMusl()) { 199 | localFileExisted = existsSync( 200 | join(__dirname, 's3-ops-rust-napi-lib.linux-arm64-musl.node') 201 | ) 202 | try { 203 | if (localFileExisted) { 204 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-arm64-musl.node') 205 | } else { 206 | nativeBinding = require('s3-ops-rust-napi-lib-linux-arm64-musl') 207 | } 208 | } catch (e) { 209 | loadError = e 210 | } 211 | } else { 212 | localFileExisted = existsSync( 213 | join(__dirname, 's3-ops-rust-napi-lib.linux-arm64-gnu.node') 214 | ) 215 | try { 216 | if (localFileExisted) { 217 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-arm64-gnu.node') 218 | } else { 219 | nativeBinding = require('s3-ops-rust-napi-lib-linux-arm64-gnu') 220 | } 221 | } catch (e) { 222 | loadError = e 223 | } 224 | } 225 | break 226 | case 'arm': 227 | localFileExisted = existsSync( 228 | join(__dirname, 's3-ops-rust-napi-lib.linux-arm-gnueabihf.node') 229 | ) 230 | try { 231 | if (localFileExisted) { 232 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-arm-gnueabihf.node') 233 | } else { 234 | nativeBinding = require('s3-ops-rust-napi-lib-linux-arm-gnueabihf') 235 | } 236 | } catch (e) { 237 | loadError = e 238 | } 239 | break 240 | case 'riscv64': 241 | if (isMusl()) { 242 | localFileExisted = existsSync( 243 | join(__dirname, 's3-ops-rust-napi-lib.linux-riscv64-musl.node') 244 | ) 245 | try { 246 | if (localFileExisted) { 247 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-riscv64-musl.node') 248 | } else { 249 | nativeBinding = require('s3-ops-rust-napi-lib-linux-riscv64-musl') 250 | } 251 | } catch (e) { 252 | loadError = e 253 | } 254 | } else { 255 | localFileExisted = existsSync( 256 | join(__dirname, 's3-ops-rust-napi-lib.linux-riscv64-gnu.node') 257 | ) 258 | try { 259 | if (localFileExisted) { 260 | nativeBinding = require('./s3-ops-rust-napi-lib.linux-riscv64-gnu.node') 261 | } else { 262 | nativeBinding = require('s3-ops-rust-napi-lib-linux-riscv64-gnu') 263 | } 264 | } catch (e) { 265 | loadError = e 266 | } 267 | } 268 | break 269 | default: 270 | throw new Error(`Unsupported architecture on Linux: ${arch}`) 271 | } 272 | break 273 | default: 274 | throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) 275 | } 276 | 277 | if (!nativeBinding) { 278 | if (loadError) { 279 | throw loadError 280 | } 281 | throw new Error(`Failed to load native binding`) 282 | } 283 | 284 | const { S3OpsRust, sign } = nativeBinding 285 | 286 | module.exports.S3OpsRust = S3OpsRust 287 | module.exports.sign = sign 288 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/npm/linux-arm64-gnu/README.md: -------------------------------------------------------------------------------- 1 | # `s3-ops-rust-napi-lib-linux-arm64-gnu` 2 | 3 | This is the **aarch64-unknown-linux-gnu** binary for `s3-ops-rust-napi-lib` 4 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/npm/linux-arm64-gnu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "s3-ops-rust-napi-lib-linux-arm64-gnu", 3 | "version": "0.0.0", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "arm64" 9 | ], 10 | "main": "s3-ops-rust-napi-lib.linux-arm64-gnu.node", 11 | "files": [ 12 | "s3-ops-rust-napi-lib.linux-arm64-gnu.node" 13 | ], 14 | "license": "MIT", 15 | "engines": { 16 | "node": ">= 10" 17 | }, 18 | "libc": [ 19 | "glibc" 20 | ] 21 | } -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/npm/linux-x64-gnu/README.md: -------------------------------------------------------------------------------- 1 | # `s3-ops-rust-napi-lib-linux-x64-gnu` 2 | 3 | This is the **x86_64-unknown-linux-gnu** binary for `s3-ops-rust-napi-lib` 4 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/npm/linux-x64-gnu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "s3-ops-rust-napi-lib-linux-x64-gnu", 3 | "version": "0.0.0", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "x64" 9 | ], 10 | "main": "s3-ops-rust-napi-lib.linux-x64-gnu.node", 11 | "files": [ 12 | "s3-ops-rust-napi-lib.linux-x64-gnu.node" 13 | ], 14 | "license": "MIT", 15 | "engines": { 16 | "node": ">= 10" 17 | }, 18 | "libc": [ 19 | "glibc" 20 | ] 21 | } -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "s3-ops-rust-napi-lib", 3 | "version": "0.0.0", 4 | "main": "index.js", 5 | "types": "index.d.ts", 6 | "napi": { 7 | "name": "s3-ops-rust-napi-lib", 8 | "triples": { 9 | "defaults": false, 10 | "additional": [ 11 | "aarch64-unknown-linux-gnu", 12 | "x86_64-unknown-linux-gnu" 13 | ] 14 | } 15 | }, 16 | "license": "MIT", 17 | "devDependencies": { 18 | "@napi-rs/cli": "^2.17.0", 19 | "ava": "^5.1.1" 20 | }, 21 | "ava": { 22 | "timeout": "3m" 23 | }, 24 | "engines": { 25 | "node": ">= 10" 26 | }, 27 | "scripts": { 28 | "artifacts": "napi artifacts", 29 | "build": "napi build --platform --release", 30 | "build:debug": "napi build --platform", 31 | "prepublishOnly": "napi prepublish -t npm", 32 | "universal": "napi universal", 33 | "version": "napi version" 34 | }, 35 | "packageManager": "yarn@4.0.2", 36 | "optionalDependencies": { 37 | "s3-ops-rust-napi-lib-linux-arm64-gnu": "0.0.0", 38 | "s3-ops-rust-napi-lib-linux-x64-gnu": "0.0.0" 39 | } 40 | } -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/rustfmt.toml: -------------------------------------------------------------------------------- 1 | tab_spaces = 2 2 | edition = "2021" 3 | -------------------------------------------------------------------------------- /s3-ops-rust-napi-lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | use aws_config::BehaviorVersion; 2 | use aws_sdk_s3::{types::BucketLocationConstraint, Client, Error}; 3 | use futures::{stream::FuturesUnordered, StreamExt}; 4 | use napi_derive::napi; 5 | use tokio::runtime::Runtime; 6 | 7 | #[napi(object)] 8 | pub struct BucketDetails { 9 | pub name: String, 10 | pub location: String, 11 | } 12 | 13 | #[napi] 14 | pub struct S3OpsRust { 15 | client: Client, 16 | } 17 | 18 | #[napi] 19 | impl S3OpsRust { 20 | #[napi(constructor)] 21 | pub fn new() -> Self { 22 | let rt = Runtime::new().unwrap(); 23 | let client = rt.block_on(async { 24 | let shared_config = aws_config::load_defaults(BehaviorVersion::v2023_11_09()).await; 25 | S3OpsRust { 26 | client: Client::new(&shared_config), 27 | } 28 | }); 29 | 30 | client 31 | } 32 | 33 | #[napi] 34 | pub fn list_buckets(&self) -> napi::Result> { 35 | let rt = Runtime::new().unwrap(); 36 | let result = rt.block_on(async { 37 | let result = list_buckets_internal(&self.client).await; 38 | result.map_err(|err| napi::Error::from_reason(err.to_string())) 39 | }); 40 | result 41 | } 42 | } 43 | async fn list_buckets_internal(client: &Client) -> Result, Error> { 44 | let resp = client.list_buckets().send().await?; 45 | let buckets = resp.buckets(); 46 | let tasks = FuturesUnordered::new(); 47 | for bucket in buckets { 48 | let bucket_name = bucket.name().unwrap_or_default(); 49 | let task = client.get_bucket_location().bucket(bucket_name).send(); 50 | let wrapped_task = async move { 51 | let result = task.await; 52 | match result { 53 | Ok(response) => { 54 | let location = response 55 | .location_constraint() 56 | .unwrap_or(&BucketLocationConstraint::UsWest1) 57 | .as_str(); 58 | Ok(BucketDetails { 59 | name: String::from(bucket_name), 60 | location: String::from(location), 61 | }) 62 | } 63 | Err(e) => Err(e), 64 | } 65 | }; 66 | 67 | tasks.push(wrapped_task); 68 | } 69 | let results = tasks.collect::>().await; 70 | let bucket_locations: Vec = results.into_iter().filter_map(Result::ok).collect(); 71 | 72 | Ok(bucket_locations) 73 | } 74 | -------------------------------------------------------------------------------- /s3-ops-rust-pyo3-lib/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | .pytest_cache/ 6 | *.py[cod] 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | .venv/ 14 | env/ 15 | bin/ 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | include/ 26 | man/ 27 | venv/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | pip-selfcheck.json 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | 45 | # Translations 46 | *.mo 47 | 48 | # Mr Developer 49 | .mr.developer.cfg 50 | .project 51 | .pydevproject 52 | 53 | # Rope 54 | .ropeproject 55 | 56 | # Django stuff: 57 | *.log 58 | *.pot 59 | 60 | .DS_Store 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyCharm 66 | .idea/ 67 | 68 | # VSCode 69 | .vscode/ 70 | 71 | # Pyenv 72 | .python-version -------------------------------------------------------------------------------- /s3-ops-rust-pyo3-lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "s3_ops_rust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | name = "s3_ops_rust" 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | aws-config = { version = "0.56.1", features = ["rustls"] } 12 | aws-sdk-s3 = "0.30.0" 13 | futures = "0.3.28" 14 | once_cell = "1.18.0" 15 | pyo3 = "0.19.0" 16 | tokio = { version = "1.32.0", features = ["rt", "rt-multi-thread"] } 17 | -------------------------------------------------------------------------------- /s3-ops-rust-pyo3-lib/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.2,<2.0"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "s3_ops_rust" 7 | requires-python = ">=3.7" 8 | classifiers = [ 9 | "Programming Language :: Rust", 10 | "Programming Language :: Python :: Implementation :: CPython", 11 | "Programming Language :: Python :: Implementation :: PyPy", 12 | ] 13 | 14 | 15 | [tool.maturin] 16 | features = ["pyo3/extension-module"] 17 | -------------------------------------------------------------------------------- /s3-ops-rust-pyo3-lib/s3_ops_rust.pyi: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class S3OpsRust: 4 | def list_buckets() -> List[(str, str)]: 5 | """ 6 | List available buckets and their respective regions in the AWS account. 7 | """ 8 | ... 9 | -------------------------------------------------------------------------------- /s3-ops-rust-pyo3-lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | use aws_sdk_s3::{types::BucketLocationConstraint, Client, Error}; 2 | use futures::{stream::FuturesUnordered, StreamExt}; 3 | use pyo3::{exceptions::PyValueError, prelude::*, types::PyDict}; 4 | use tokio::runtime::Runtime; 5 | 6 | #[pyclass] 7 | pub struct S3OpsRust { 8 | client: Client, 9 | } 10 | 11 | #[pymethods] 12 | impl S3OpsRust { 13 | #[new] 14 | fn new(_kwargs: Option<&PyDict>) -> PyResult { 15 | let rt = Runtime::new().unwrap(); 16 | let client = rt.block_on(async { 17 | let shared_config = aws_config::load_from_env().await; 18 | S3OpsRust { 19 | client: Client::new(&shared_config), 20 | } 21 | }); 22 | 23 | Ok(client) 24 | } 25 | 26 | fn list_buckets(&self) -> PyResult> { 27 | let rt = Runtime::new().unwrap(); 28 | let result = rt.block_on(async { 29 | let result = list_buckets_internal(&self.client).await; 30 | result.map_err(|err| PyValueError::new_err(err.to_string())) 31 | }); 32 | result 33 | } 34 | } 35 | async fn list_buckets_internal(client: &Client) -> Result, Error> { 36 | let resp = client.list_buckets().send().await?; 37 | let buckets = resp.buckets().unwrap_or_default(); 38 | let tasks = FuturesUnordered::new(); 39 | for bucket in buckets { 40 | let bucket_name = bucket.name().unwrap_or_default(); 41 | let task = client.get_bucket_location().bucket(bucket_name).send(); 42 | let wrapped_task = async move { 43 | let result = task.await; 44 | match result { 45 | Ok(response) => { 46 | let location = response 47 | .location_constraint() 48 | .unwrap_or(&BucketLocationConstraint::UsWest1) 49 | .as_str(); 50 | Ok((String::from(bucket_name), String::from(location))) 51 | } 52 | Err(e) => Err(e), 53 | } 54 | }; 55 | 56 | tasks.push(wrapped_task); 57 | } 58 | let results = tasks.collect::>().await; 59 | let bucket_locations: Vec<(String, String)> = results 60 | .into_iter() 61 | .filter_map(Result::ok) 62 | .collect(); 63 | 64 | Ok(bucket_locations) 65 | } 66 | 67 | /// A Python module implemented in Rust. 68 | #[pymodule] 69 | fn s3_ops_rust(_py: Python, m: &PyModule) -> PyResult<()> { 70 | m.add_class::()?; 71 | Ok(()) 72 | } 73 | --------------------------------------------------------------------------------