From 3655584b0ea809db810454c9b2bc5ad92d03180d Mon Sep 17 00:00:00 2001 From: root Date: Mon, 23 Mar 2026 12:35:26 +0000 Subject: [PATCH 1/2] feat: update Rust SDK to 0.1.1 * Added `CHANGELOG.md` documenting initial Appwrite Rust SDK release --- .github/workflows/autoclose.yml | 1 + .github/workflows/publish.yml | 23 + .github/workflows/stale.yml | 9 + .gitignore | 24 + CHANGELOG.md | 852 ++++++++++++ Cargo.toml | 41 + LICENSE | 29 +- README.md | 109 +- src/client.rs | 904 ++++++++++++ src/enums/adapter.rs | 26 + src/enums/attribute_status.rs | 35 + src/enums/authentication_factor.rs | 32 + src/enums/authenticator_type.rs | 23 + src/enums/backup_services.rs | 29 + src/enums/browser.rs | 62 + src/enums/browser_permission.rs | 80 ++ src/enums/build_runtime.rs | 536 ++++++++ src/enums/column_status.rs | 35 + src/enums/compression.rs | 29 + src/enums/credit_card.rs | 71 + src/enums/database_type.rs | 26 + src/enums/deployment_download_type.rs | 26 + src/enums/deployment_status.rs | 38 + src/enums/execution_method.rs | 41 + src/enums/execution_status.rs | 35 + src/enums/execution_trigger.rs | 29 + src/enums/flag.rs | 605 ++++++++ src/enums/framework.rs | 65 + src/enums/health_antivirus_status.rs | 29 + src/enums/health_check_status.rs | 26 + src/enums/image_format.rs | 41 + src/enums/image_gravity.rs | 47 + src/enums/index_status.rs | 35 + src/enums/index_type.rs | 32 + src/enums/message_priority.rs | 26 + src/enums/message_status.rs | 35 + src/enums/messaging_provider_type.rs | 29 + src/enums/mod.rs | 84 ++ src/enums/name.rs | 59 + src/enums/o_auth_provider.rs | 137 ++ src/enums/order_by.rs | 26 + src/enums/password_hash.rs | 53 + src/enums/relation_mutate.rs | 29 + src/enums/relationship_type.rs | 32 + src/enums/runtime.rs | 536 ++++++++ src/enums/scopes.rs | 224 +++ src/enums/smtp_encryption.rs | 29 + src/enums/template_reference_type.rs | 29 + src/enums/theme.rs | 26 + src/enums/timezone.rs | 1277 +++++++++++++++++ src/enums/vcs_reference_type.rs | 29 + src/error.rs | 112 ++ src/id.rs | 118 ++ src/input_file.rs | 298 ++++ src/lib.rs | 63 + src/models/activity_event.rs | 322 +++++ src/models/activity_event_list.rs | 50 + src/models/algo_argon2.rs | 68 + src/models/algo_bcrypt.rs | 41 + src/models/algo_md5.rs | 41 + src/models/algo_phpass.rs | 41 + src/models/algo_scrypt.rs | 77 ++ src/models/algo_scrypt_modified.rs | 68 + src/models/algo_sha.rs | 41 + src/models/attribute_boolean.rs | 128 ++ src/models/attribute_datetime.rs | 136 ++ src/models/attribute_email.rs | 137 ++ src/models/attribute_enum.rs | 146 ++ src/models/attribute_float.rs | 158 +++ src/models/attribute_integer.rs | 158 +++ src/models/attribute_ip.rs | 137 ++ src/models/attribute_line.rs | 128 ++ src/models/attribute_list.rs | 50 + src/models/attribute_longtext.rs | 143 ++ src/models/attribute_mediumtext.rs | 143 ++ src/models/attribute_point.rs | 128 ++ src/models/attribute_polygon.rs | 128 ++ src/models/attribute_relationship.rs | 166 +++ src/models/attribute_string.rs | 152 +++ src/models/attribute_text.rs | 143 ++ src/models/attribute_url.rs | 137 ++ src/models/attribute_varchar.rs | 152 +++ src/models/backup_archive.rs | 155 +++ src/models/backup_archive_list.rs | 50 + src/models/backup_policy.rs | 145 ++ src/models/backup_policy_list.rs | 50 + src/models/backup_restoration.rs | 132 ++ src/models/backup_restoration_list.rs | 50 + src/models/bucket.rs | 162 +++ src/models/bucket_list.rs | 50 + src/models/collection.rs | 144 ++ src/models/collection_list.rs | 50 + src/models/column_boolean.rs | 128 ++ src/models/column_datetime.rs | 136 ++ src/models/column_email.rs | 137 ++ src/models/column_enum.rs | 146 ++ src/models/column_float.rs | 158 +++ src/models/column_index.rs | 130 ++ src/models/column_index_list.rs | 50 + src/models/column_integer.rs | 158 +++ src/models/column_ip.rs | 137 ++ src/models/column_line.rs | 128 ++ src/models/column_list.rs | 50 + src/models/column_longtext.rs | 143 ++ src/models/column_mediumtext.rs | 143 ++ src/models/column_point.rs | 128 ++ src/models/column_polygon.rs | 128 ++ src/models/column_relationship.rs | 166 +++ src/models/column_string.rs | 152 +++ src/models/column_text.rs | 143 ++ src/models/column_url.rs | 137 ++ src/models/column_varchar.rs | 152 +++ src/models/continent.rs | 50 + src/models/continent_list.rs | 50 + src/models/country.rs | 50 + src/models/country_list.rs | 50 + src/models/currency.rs | 96 ++ src/models/currency_list.rs | 50 + src/models/database.rs | 106 ++ src/models/database_list.rs | 50 + src/models/deployment.rs | 276 ++++ src/models/deployment_list.rs | 50 + src/models/document.rs | 109 ++ src/models/document_list.rs | 50 + src/models/execution.rs | 212 +++ src/models/execution_list.rs | 50 + src/models/file.rs | 152 +++ src/models/file_list.rs | 50 + src/models/framework.rs | 77 ++ src/models/framework_adapter.rs | 78 ++ src/models/framework_list.rs | 50 + src/models/function.rs | 310 +++++ src/models/function_list.rs | 50 + src/models/headers.rs | 50 + src/models/health_antivirus.rs | 50 + src/models/health_certificate.rs | 86 ++ src/models/health_queue.rs | 41 + src/models/health_status.rs | 59 + src/models/health_status_list.rs | 50 + src/models/health_time.rs | 59 + src/models/identity.rs | 122 ++ src/models/identity_list.rs | 50 + src/models/index.rs | 130 ++ src/models/index_list.rs | 50 + src/models/jwt.rs | 41 + src/models/language.rs | 59 + src/models/language_list.rs | 50 + src/models/locale.rs | 99 ++ src/models/locale_code.rs | 51 + src/models/locale_code_list.rs | 50 + src/models/log.rs | 226 +++ src/models/log_list.rs | 50 + src/models/membership.rs | 155 +++ src/models/membership_list.rs | 50 + src/models/message.rs | 167 +++ src/models/message_list.rs | 50 + src/models/mfa_challenge.rs | 68 + src/models/mfa_factors.rs | 68 + src/models/mfa_recovery_codes.rs | 41 + src/models/mfa_type.rs | 50 + src/models/mod.rs | 433 ++++++ src/models/phone.rs | 59 + src/models/phone_list.rs | 50 + src/models/preferences.rs | 45 + src/models/provider.rs | 119 ++ src/models/provider_list.rs | 50 + src/models/resource_token.rs | 96 ++ src/models/resource_token_list.rs | 50 + src/models/row.rs | 109 ++ src/models/row_list.rs | 50 + src/models/runtime.rs | 104 ++ src/models/runtime_list.rs | 50 + src/models/session.rs | 297 ++++ src/models/session_list.rs | 50 + src/models/site.rs | 329 +++++ src/models/site_list.rs | 50 + src/models/specification.rs | 68 + src/models/specification_list.rs | 50 + src/models/subscriber.rs | 114 ++ src/models/subscriber_list.rs | 50 + src/models/table.rs | 144 ++ src/models/table_list.rs | 50 + src/models/target.rs | 120 ++ src/models/target_list.rs | 50 + src/models/team.rs | 86 ++ src/models/team_list.rs | 50 + src/models/token.rs | 89 ++ src/models/topic.rs | 104 ++ src/models/topic_list.rs | 50 + src/models/transaction.rs | 87 ++ src/models/transaction_list.rs | 50 + src/models/user.rs | 256 ++++ src/models/user_list.rs | 50 + src/models/variable.rs | 107 ++ src/models/variable_list.rs | 50 + src/models/webhook.rs | 149 ++ src/models/webhook_list.rs | 50 + src/operator.rs | 396 ++++++ src/permission.rs | 91 ++ src/query.rs | 846 ++++++++++++ src/role.rs | 155 +++ src/services/account.rs | 931 +++++++++++++ src/services/activities.rs | 68 + src/services/avatars.rs | 352 +++++ src/services/backups.rs | 258 ++++ src/services/databases.rs | 1820 +++++++++++++++++++++++++ src/services/functions.rs | 697 ++++++++++ src/services/graphql.rs | 75 + src/services/health.rs | 477 +++++++ src/services/locale.rs | 144 ++ src/services/messaging.rs | 1650 ++++++++++++++++++++++ src/services/mod.rs | 166 +++ src/services/sites.rs | 651 +++++++++ src/services/storage.rs | 421 ++++++ src/services/tables_db.rs | 1817 ++++++++++++++++++++++++ src/services/teams.rs | 322 +++++ src/services/tokens.rs | 128 ++ src/services/users.rs | 906 ++++++++++++ src/services/webhooks.rs | 182 +++ tests/tests.rs | 291 ++++ 220 files changed, 34755 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/stale.yml create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 Cargo.toml create mode 100644 src/client.rs create mode 100644 src/enums/adapter.rs create mode 100644 src/enums/attribute_status.rs create mode 100644 src/enums/authentication_factor.rs create mode 100644 src/enums/authenticator_type.rs create mode 100644 src/enums/backup_services.rs create mode 100644 src/enums/browser.rs create mode 100644 src/enums/browser_permission.rs create mode 100644 src/enums/build_runtime.rs create mode 100644 src/enums/column_status.rs create mode 100644 src/enums/compression.rs create mode 100644 src/enums/credit_card.rs create mode 100644 src/enums/database_type.rs create mode 100644 src/enums/deployment_download_type.rs create mode 100644 src/enums/deployment_status.rs create mode 100644 src/enums/execution_method.rs create mode 100644 src/enums/execution_status.rs create mode 100644 src/enums/execution_trigger.rs create mode 100644 src/enums/flag.rs create mode 100644 src/enums/framework.rs create mode 100644 src/enums/health_antivirus_status.rs create mode 100644 src/enums/health_check_status.rs create mode 100644 src/enums/image_format.rs create mode 100644 src/enums/image_gravity.rs create mode 100644 src/enums/index_status.rs create mode 100644 src/enums/index_type.rs create mode 100644 src/enums/message_priority.rs create mode 100644 src/enums/message_status.rs create mode 100644 src/enums/messaging_provider_type.rs create mode 100644 src/enums/mod.rs create mode 100644 src/enums/name.rs create mode 100644 src/enums/o_auth_provider.rs create mode 100644 src/enums/order_by.rs create mode 100644 src/enums/password_hash.rs create mode 100644 src/enums/relation_mutate.rs create mode 100644 src/enums/relationship_type.rs create mode 100644 src/enums/runtime.rs create mode 100644 src/enums/scopes.rs create mode 100644 src/enums/smtp_encryption.rs create mode 100644 src/enums/template_reference_type.rs create mode 100644 src/enums/theme.rs create mode 100644 src/enums/timezone.rs create mode 100644 src/enums/vcs_reference_type.rs create mode 100644 src/error.rs create mode 100644 src/id.rs create mode 100644 src/input_file.rs create mode 100644 src/lib.rs create mode 100644 src/models/activity_event.rs create mode 100644 src/models/activity_event_list.rs create mode 100644 src/models/algo_argon2.rs create mode 100644 src/models/algo_bcrypt.rs create mode 100644 src/models/algo_md5.rs create mode 100644 src/models/algo_phpass.rs create mode 100644 src/models/algo_scrypt.rs create mode 100644 src/models/algo_scrypt_modified.rs create mode 100644 src/models/algo_sha.rs create mode 100644 src/models/attribute_boolean.rs create mode 100644 src/models/attribute_datetime.rs create mode 100644 src/models/attribute_email.rs create mode 100644 src/models/attribute_enum.rs create mode 100644 src/models/attribute_float.rs create mode 100644 src/models/attribute_integer.rs create mode 100644 src/models/attribute_ip.rs create mode 100644 src/models/attribute_line.rs create mode 100644 src/models/attribute_list.rs create mode 100644 src/models/attribute_longtext.rs create mode 100644 src/models/attribute_mediumtext.rs create mode 100644 src/models/attribute_point.rs create mode 100644 src/models/attribute_polygon.rs create mode 100644 src/models/attribute_relationship.rs create mode 100644 src/models/attribute_string.rs create mode 100644 src/models/attribute_text.rs create mode 100644 src/models/attribute_url.rs create mode 100644 src/models/attribute_varchar.rs create mode 100644 src/models/backup_archive.rs create mode 100644 src/models/backup_archive_list.rs create mode 100644 src/models/backup_policy.rs create mode 100644 src/models/backup_policy_list.rs create mode 100644 src/models/backup_restoration.rs create mode 100644 src/models/backup_restoration_list.rs create mode 100644 src/models/bucket.rs create mode 100644 src/models/bucket_list.rs create mode 100644 src/models/collection.rs create mode 100644 src/models/collection_list.rs create mode 100644 src/models/column_boolean.rs create mode 100644 src/models/column_datetime.rs create mode 100644 src/models/column_email.rs create mode 100644 src/models/column_enum.rs create mode 100644 src/models/column_float.rs create mode 100644 src/models/column_index.rs create mode 100644 src/models/column_index_list.rs create mode 100644 src/models/column_integer.rs create mode 100644 src/models/column_ip.rs create mode 100644 src/models/column_line.rs create mode 100644 src/models/column_list.rs create mode 100644 src/models/column_longtext.rs create mode 100644 src/models/column_mediumtext.rs create mode 100644 src/models/column_point.rs create mode 100644 src/models/column_polygon.rs create mode 100644 src/models/column_relationship.rs create mode 100644 src/models/column_string.rs create mode 100644 src/models/column_text.rs create mode 100644 src/models/column_url.rs create mode 100644 src/models/column_varchar.rs create mode 100644 src/models/continent.rs create mode 100644 src/models/continent_list.rs create mode 100644 src/models/country.rs create mode 100644 src/models/country_list.rs create mode 100644 src/models/currency.rs create mode 100644 src/models/currency_list.rs create mode 100644 src/models/database.rs create mode 100644 src/models/database_list.rs create mode 100644 src/models/deployment.rs create mode 100644 src/models/deployment_list.rs create mode 100644 src/models/document.rs create mode 100644 src/models/document_list.rs create mode 100644 src/models/execution.rs create mode 100644 src/models/execution_list.rs create mode 100644 src/models/file.rs create mode 100644 src/models/file_list.rs create mode 100644 src/models/framework.rs create mode 100644 src/models/framework_adapter.rs create mode 100644 src/models/framework_list.rs create mode 100644 src/models/function.rs create mode 100644 src/models/function_list.rs create mode 100644 src/models/headers.rs create mode 100644 src/models/health_antivirus.rs create mode 100644 src/models/health_certificate.rs create mode 100644 src/models/health_queue.rs create mode 100644 src/models/health_status.rs create mode 100644 src/models/health_status_list.rs create mode 100644 src/models/health_time.rs create mode 100644 src/models/identity.rs create mode 100644 src/models/identity_list.rs create mode 100644 src/models/index.rs create mode 100644 src/models/index_list.rs create mode 100644 src/models/jwt.rs create mode 100644 src/models/language.rs create mode 100644 src/models/language_list.rs create mode 100644 src/models/locale.rs create mode 100644 src/models/locale_code.rs create mode 100644 src/models/locale_code_list.rs create mode 100644 src/models/log.rs create mode 100644 src/models/log_list.rs create mode 100644 src/models/membership.rs create mode 100644 src/models/membership_list.rs create mode 100644 src/models/message.rs create mode 100644 src/models/message_list.rs create mode 100644 src/models/mfa_challenge.rs create mode 100644 src/models/mfa_factors.rs create mode 100644 src/models/mfa_recovery_codes.rs create mode 100644 src/models/mfa_type.rs create mode 100644 src/models/mod.rs create mode 100644 src/models/phone.rs create mode 100644 src/models/phone_list.rs create mode 100644 src/models/preferences.rs create mode 100644 src/models/provider.rs create mode 100644 src/models/provider_list.rs create mode 100644 src/models/resource_token.rs create mode 100644 src/models/resource_token_list.rs create mode 100644 src/models/row.rs create mode 100644 src/models/row_list.rs create mode 100644 src/models/runtime.rs create mode 100644 src/models/runtime_list.rs create mode 100644 src/models/session.rs create mode 100644 src/models/session_list.rs create mode 100644 src/models/site.rs create mode 100644 src/models/site_list.rs create mode 100644 src/models/specification.rs create mode 100644 src/models/specification_list.rs create mode 100644 src/models/subscriber.rs create mode 100644 src/models/subscriber_list.rs create mode 100644 src/models/table.rs create mode 100644 src/models/table_list.rs create mode 100644 src/models/target.rs create mode 100644 src/models/target_list.rs create mode 100644 src/models/team.rs create mode 100644 src/models/team_list.rs create mode 100644 src/models/token.rs create mode 100644 src/models/topic.rs create mode 100644 src/models/topic_list.rs create mode 100644 src/models/transaction.rs create mode 100644 src/models/transaction_list.rs create mode 100644 src/models/user.rs create mode 100644 src/models/user_list.rs create mode 100644 src/models/variable.rs create mode 100644 src/models/variable_list.rs create mode 100644 src/models/webhook.rs create mode 100644 src/models/webhook_list.rs create mode 100644 src/operator.rs create mode 100644 src/permission.rs create mode 100644 src/query.rs create mode 100644 src/role.rs create mode 100644 src/services/account.rs create mode 100644 src/services/activities.rs create mode 100644 src/services/avatars.rs create mode 100644 src/services/backups.rs create mode 100644 src/services/databases.rs create mode 100644 src/services/functions.rs create mode 100644 src/services/graphql.rs create mode 100644 src/services/health.rs create mode 100644 src/services/locale.rs create mode 100644 src/services/messaging.rs create mode 100644 src/services/mod.rs create mode 100644 src/services/sites.rs create mode 100644 src/services/storage.rs create mode 100644 src/services/tables_db.rs create mode 100644 src/services/teams.rs create mode 100644 src/services/tokens.rs create mode 100644 src/services/users.rs create mode 100644 src/services/webhooks.rs create mode 100644 tests/tests.rs diff --git a/.github/workflows/autoclose.yml b/.github/workflows/autoclose.yml index 3e2b3cb..d9629e1 100644 --- a/.github/workflows/autoclose.yml +++ b/.github/workflows/autoclose.yml @@ -6,6 +6,7 @@ on: jobs: auto_close: + if: github.head_ref != 'dev' uses: appwrite/.github/.github/workflows/autoclose.yml@main secrets: GH_AUTO_CLOSE_PR_TOKEN: ${{ secrets.GH_AUTO_CLOSE_PR_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..c77f82b --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,23 @@ +name: Publish to Crates.io + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + publish: + name: Build and publish to crates.io + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@1.83.0 + + - name: Run tests + run: cargo test --all-features + + - name: Publish to crates.io + run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..5888b61 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,9 @@ +name: Mark stale issues + +on: + schedule: + - cron: "0 0 * * *" # Midnight Runtime + +jobs: + stale: + uses: appwrite/.github/.github/workflows/stale.yml@main diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b0cbbe --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Rust build artifacts +/target + +# Cargo.lock is included for applications, excluded for libraries +# Since this is a library SDK, we exclude it +Cargo.lock + +# Backup files from rustfmt +**/*.rs.bk + +# IDE files +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS files +.DS_Store +Thumbs.db + +# Test coverage +*.profraw +*.profdata diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b84ce63 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,852 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.1] - TBD + +### Added +- Initial release of Appwrite Rust SDK +- Full support for Appwrite API 1.9.0 +- Async/await support with tokio runtime +- Built-in error handling with custom error types +- File upload support with automatic chunking +- Query builder for database operations +- Permission and role management utilities +- ID generation utilities +- Comprehensive documentation and examples +- Support for self-signed certificates +- Custom header support +- Automatic JSON serialization/deserialization + +### Features +- Account service with 54 methods +- Activities service with 2 methods +- Avatars service with 8 methods +- Backups service with 12 methods +- Databases service with 69 methods +- Functions service with 26 methods +- Graphql service with 2 methods +- Health service with 29 methods +- Locale service with 8 methods +- Messaging service with 56 methods +- Sites service with 25 methods +- Storage service with 13 methods +- TablesDB service with 69 methods +- Teams service with 13 methods +- Tokens service with 5 methods +- Users service with 49 methods +- Webhooks service with 6 methods + +### Services +#### Account +The Account service allows you to authenticate and manage a user account. +- `get()` - Get the currently logged in user. +- `create()` - Use this endpoint to allow a new user to register a new account in your project. After the user registration completes successfully, you can use the [/account/verfication](https://appwrite.io/docs/references/cloud/client-web/account#createVerification) route to start verifying the user email address. To allow the new user to login to their new account, you need to create a new [account session](https://appwrite.io/docs/references/cloud/client-web/account#createEmailSession). +- `update_email()` - Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request. +This endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password. + +- `list_identities()` - Get the list of identities for the currently logged in user. +- `delete_identity()` - Delete an identity by its unique ID. +- `create_jwt()` - Use this endpoint to create a JSON Web Token. You can use the resulting JWT to authenticate on behalf of the current user when working with the Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes from its creation and will be invalid if the user will logout in that time frame. +- `list_logs()` - Get the list of latest security activity logs for the currently logged in user. Each log returns user IP address, location and date and time of log. +- `update_mfa()` - Enable or disable MFA on an account. +- `create_mfa_authenticator()` - Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method. +- `create_mfa_authenticator()` - Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method. +- `update_mfa_authenticator()` - Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method. +- `update_mfa_authenticator()` - Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method. +- `delete_mfa_authenticator()` - Delete an authenticator for a user by ID. +- `delete_mfa_authenticator()` - Delete an authenticator for a user by ID. +- `create_mfa_challenge()` - Begin the process of MFA verification after sign-in. Finish the flow with [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) method. +- `create_mfa_challenge()` - Begin the process of MFA verification after sign-in. Finish the flow with [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) method. +- `update_mfa_challenge()` - Complete the MFA challenge by providing the one-time password. Finish the process of MFA verification by providing the one-time password. To begin the flow, use [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `update_mfa_challenge()` - Complete the MFA challenge by providing the one-time password. Finish the process of MFA verification by providing the one-time password. To begin the flow, use [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `list_mfa_factors()` - List the factors available on the account to be used as a MFA challange. +- `list_mfa_factors()` - List the factors available on the account to be used as a MFA challange. +- `get_mfa_recovery_codes()` - Get recovery codes that can be used as backup for MFA flow. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to read recovery codes. +- `get_mfa_recovery_codes()` - Get recovery codes that can be used as backup for MFA flow. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to read recovery codes. +- `create_mfa_recovery_codes()` - Generate recovery codes as backup for MFA flow. It's recommended to generate and show then immediately after user successfully adds their authehticator. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `create_mfa_recovery_codes()` - Generate recovery codes as backup for MFA flow. It's recommended to generate and show then immediately after user successfully adds their authehticator. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `update_mfa_recovery_codes()` - Regenerate recovery codes that can be used as backup for MFA flow. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to regenreate recovery codes. +- `update_mfa_recovery_codes()` - Regenerate recovery codes that can be used as backup for MFA flow. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to regenreate recovery codes. +- `update_name()` - Update currently logged in user account name. +- `update_password()` - Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth, Team Invites and Magic URL, oldPassword is optional. +- `update_phone()` - Update the currently logged in user's phone number. After updating the phone number, the phone verification status will be reset. A confirmation SMS is not sent automatically, however you can use the [POST /account/verification/phone](https://appwrite.io/docs/references/cloud/client-web/account#createPhoneVerification) endpoint to send a confirmation SMS. +- `get_prefs()` - Get the preferences as a key-value object for the currently logged in user. +- `update_prefs()` - Update currently logged in user account preferences. The object you pass is stored as is, and replaces any previous value. The maximum allowed prefs size is 64kB and throws error if exceeded. +- `create_recovery()` - Sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link he is redirected back to your app password reset URL with the secret key and email address values attached to the URL query string. Use the query string params to submit a request to the [PUT /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#updateRecovery) endpoint to complete the process. The verification link sent to the user's email address is valid for 1 hour. +- `update_recovery()` - Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#createRecovery) endpoint. + +Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. +- `list_sessions()` - Get the list of active sessions across different devices for the currently logged in user. +- `delete_sessions()` - Delete all sessions from the user account and remove any sessions cookies from the end client. +- `create_anonymous_session()` - Use this endpoint to allow a new user to register an anonymous account in your project. This route will also create a new session for the user. To allow the new user to convert an anonymous account to a normal account, you need to update its [email and password](https://appwrite.io/docs/references/cloud/client-web/account#updateEmail) or create an [OAuth2 session](https://appwrite.io/docs/references/cloud/client-web/account#CreateOAuth2Session). +- `create_email_password_session()` - Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. + +A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). +- `update_magic_url_session()` - Use this endpoint to create a session from token. Provide the **userId** and **secret** parameters from the successful response of authentication flows initiated by token creation. For example, magic URL and phone login. +- `update_phone_session()` - Use this endpoint to create a session from token. Provide the **userId** and **secret** parameters from the successful response of authentication flows initiated by token creation. For example, magic URL and phone login. +- `create_session()` - Use this endpoint to create a session from token. Provide the **userId** and **secret** parameters from the successful response of authentication flows initiated by token creation. For example, magic URL and phone login. +- `get_session()` - Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used. +- `update_session()` - Use this endpoint to extend a session's length. Extending a session is useful when session expiry is short. If the session was created using an OAuth provider, this endpoint refreshes the access token from the provider. +- `delete_session()` - Logout the user. Use 'current' as the session ID to logout on this device, use a session ID to logout on another device. If you're looking to logout the user on all devices, use [Delete Sessions](https://appwrite.io/docs/references/cloud/client-web/account#deleteSessions) instead. +- `update_status()` - Block the currently logged in user account. Behind the scene, the user record is not deleted but permanently blocked from any access. To completely delete a user, use the Users API instead. +- `create_email_token()` - Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes. + +A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). + +- `create_magic_url_token()` - Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. + +A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). + +- `create_o_auth2_token()` - Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. + +If authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint. + +A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). +- `create_phone_token()` - Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes. + +A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). +- `create_email_verification()` - Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). The verification link sent to the user's email address is valid for 7 days. + +Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. + +- `create_verification()` - Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). The verification link sent to the user's email address is valid for 7 days. + +Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. + +- `update_email_verification()` - Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code. +- `update_verification()` - Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code. +- `create_phone_verification()` - Use this endpoint to send a verification SMS to the currently logged in user. This endpoint is meant for use after updating a user's phone number using the [accountUpdatePhone](https://appwrite.io/docs/references/cloud/client-web/account#updatePhone) endpoint. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updatePhoneVerification). The verification code sent to the user's phone number is valid for 15 minutes. +- `update_phone_verification()` - Use this endpoint to complete the user phone verification process. Use the **userId** and **secret** that were sent to your user's phone number to verify the user email ownership. If confirmed this route will return a 200 status code. + +#### Activities + +- `list_events()` - List all events for selected filters. +- `get_event()` - Get event by ID. + + +#### Avatars +The Avatars service aims to help you complete everyday tasks related to your app image, icons, and avatars. +- `get_browser()` - You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET /account/sessions](https://appwrite.io/docs/references/cloud/client-web/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings. + +When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. +- `get_credit_card()` - The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings. + +When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. + +- `get_favicon()` - Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL. + +This endpoint does not follow HTTP redirects. +- `get_flag()` - You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) standard. + +When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. + +- `get_image()` - Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol. + +When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px. + +This endpoint does not follow HTTP redirects. +- `get_initials()` - Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned. + +You can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials. + +When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. + +- `get_qr()` - Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image. + +- `get_screenshot()` - Use this endpoint to capture a screenshot of any website URL. This endpoint uses a headless browser to render the webpage and capture it as an image. + +You can configure the browser viewport size, theme, user agent, geolocation, permissions, and more. Capture either just the viewport or the full page scroll. + +When width and height are specified, the image is resized accordingly. If both dimensions are 0, the API provides an image at original size. If dimensions are not specified, the default viewport size is 1280x720px. + +#### Backups + +- `list_archives()` - List all archives for a project. +- `create_archive()` - Create a new archive asynchronously for a project. +- `get_archive()` - Get a backup archive using it's ID. +- `delete_archive()` - Delete an existing archive for a project. +- `list_policies()` - List all policies for a project. +- `create_policy()` - Create a new backup policy. +- `get_policy()` - Get a backup policy using it's ID. +- `update_policy()` - Update an existing policy using it's ID. +- `delete_policy()` - Delete a policy using it's ID. +- `create_restoration()` - Create and trigger a new restoration for a backup on a project. +- `list_restorations()` - List all backup restorations for a project. +- `get_restoration()` - Get the current status of a backup restoration. + +#### Databases +The Databases service allows you to create structured collections of documents, query and filter lists of documents +- `list()` - Get a list of all databases from the current Appwrite project. You can use the search parameter to filter your results. +- `create()` - Create a new Database. + +- `list_transactions()` - List transactions across all databases. +- `create_transaction()` - Create a new transaction. +- `get_transaction()` - Get a transaction by its unique ID. +- `update_transaction()` - Update a transaction, to either commit or roll back its operations. +- `delete_transaction()` - Delete a transaction by its unique ID. +- `create_operations()` - Create multiple operations in a single transaction. +- `get()` - Get a database by its unique ID. This endpoint response returns a JSON object with the database metadata. +- `update()` - Update a database by its unique ID. +- `delete()` - Delete a database by its unique ID. Only API keys with with databases.write scope can delete a database. +- `list_collections()` - Get a list of all collections that belong to the provided databaseId. You can use the search parameter to filter your results. +- `create_collection()` - Create a new Collection. Before using this route, you should create a new database resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `get_collection()` - Get a collection by its unique ID. This endpoint response returns a JSON object with the collection metadata. +- `update_collection()` - Update a collection by its unique ID. +- `delete_collection()` - Delete a collection by its unique ID. Only users with write permissions have access to delete this resource. +- `list_attributes()` - List attributes in the collection. +- `create_boolean_attribute()` - Create a boolean attribute. + +- `update_boolean_attribute()` - Update a boolean attribute. Changing the `default` value will not update already existing documents. +- `create_datetime_attribute()` - Create a date time attribute according to the ISO 8601 standard. +- `update_datetime_attribute()` - Update a date time attribute. Changing the `default` value will not update already existing documents. +- `create_email_attribute()` - Create an email attribute. + +- `update_email_attribute()` - Update an email attribute. Changing the `default` value will not update already existing documents. + +- `create_enum_attribute()` - Create an enum attribute. The `elements` param acts as a white-list of accepted values for this attribute. + +- `update_enum_attribute()` - Update an enum attribute. Changing the `default` value will not update already existing documents. + +- `create_float_attribute()` - Create a float attribute. Optionally, minimum and maximum values can be provided. + +- `update_float_attribute()` - Update a float attribute. Changing the `default` value will not update already existing documents. + +- `create_integer_attribute()` - Create an integer attribute. Optionally, minimum and maximum values can be provided. + +- `update_integer_attribute()` - Update an integer attribute. Changing the `default` value will not update already existing documents. + +- `create_ip_attribute()` - Create IP address attribute. + +- `update_ip_attribute()` - Update an ip attribute. Changing the `default` value will not update already existing documents. + +- `create_line_attribute()` - Create a geometric line attribute. +- `update_line_attribute()` - Update a line attribute. Changing the `default` value will not update already existing documents. +- `create_longtext_attribute()` - Create a longtext attribute. + +- `update_longtext_attribute()` - Update a longtext attribute. Changing the `default` value will not update already existing documents. + +- `create_mediumtext_attribute()` - Create a mediumtext attribute. + +- `update_mediumtext_attribute()` - Update a mediumtext attribute. Changing the `default` value will not update already existing documents. + +- `create_point_attribute()` - Create a geometric point attribute. +- `update_point_attribute()` - Update a point attribute. Changing the `default` value will not update already existing documents. +- `create_polygon_attribute()` - Create a geometric polygon attribute. +- `update_polygon_attribute()` - Update a polygon attribute. Changing the `default` value will not update already existing documents. +- `create_relationship_attribute()` - Create relationship attribute. [Learn more about relationship attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + +- `update_relationship_attribute()` - Update relationship attribute. [Learn more about relationship attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + +- `create_string_attribute()` - Create a string attribute. + +- `update_string_attribute()` - Update a string attribute. Changing the `default` value will not update already existing documents. + +- `create_text_attribute()` - Create a text attribute. + +- `update_text_attribute()` - Update a text attribute. Changing the `default` value will not update already existing documents. + +- `create_url_attribute()` - Create a URL attribute. + +- `update_url_attribute()` - Update an url attribute. Changing the `default` value will not update already existing documents. + +- `create_varchar_attribute()` - Create a varchar attribute. + +- `update_varchar_attribute()` - Update a varchar attribute. Changing the `default` value will not update already existing documents. + +- `get_attribute()` - Get attribute by ID. +- `delete_attribute()` - Deletes an attribute. +- `list_documents()` - Get a list of all the user's documents in a given collection. You can use the query params to filter your results. +- `create_document()` - Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `create_documents()` - Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `upsert_documents()` - Create or update Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. + +- `update_documents()` - Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated. +- `delete_documents()` - Bulk delete documents using queries, if no queries are passed then all documents are deleted. +- `get_document()` - Get a document by its unique ID. This endpoint response returns a JSON object with the document data. +- `upsert_document()` - Create or update a Document. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `update_document()` - Update a document by its unique ID. Using the patch method you can pass only specific fields that will get updated. +- `delete_document()` - Delete a document by its unique ID. +- `decrement_document_attribute()` - Decrement a specific attribute of a document by a given value. +- `increment_document_attribute()` - Increment a specific attribute of a document by a given value. +- `list_indexes()` - List indexes in the collection. +- `create_index()` - Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request. +Attributes can be `key`, `fulltext`, and `unique`. +- `get_index()` - Get an index by its unique ID. +- `delete_index()` - Delete an index. + +#### Functions +The Functions Service allows you view, create and manage your Cloud Functions. +- `list()` - Get a list of all the project's functions. You can use the query params to filter your results. +- `create()` - Create a new function. You can pass a list of [permissions](https://appwrite.io/docs/permissions) to allow different project users or team with access to execute the function using the client API. +- `list_runtimes()` - Get a list of all runtimes that are currently active on your instance. +- `list_specifications()` - List allowed function specifications for this instance. +- `get()` - Get a function by its unique ID. +- `update()` - Update function by its unique ID. +- `delete()` - Delete a function by its unique ID. +- `update_function_deployment()` - Update the function active deployment. Use this endpoint to switch the code deployment that should be used when visitor opens your function. +- `list_deployments()` - Get a list of all the function's code deployments. You can use the query params to filter your results. +- `create_deployment()` - Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID. + +This endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https://appwrite.io/docs/functions). + +Use the "command" param to set the entrypoint used to execute your code. +- `create_duplicate_deployment()` - Create a new build for an existing function deployment. This endpoint allows you to rebuild a deployment with the updated function configuration, including its entrypoint and build commands if they have been modified. The build process will be queued and executed asynchronously. The original deployment's code will be preserved and used for the new build. +- `create_template_deployment()` - Create a deployment based on a template. + +Use this endpoint with combination of [listTemplates](https://appwrite.io/docs/products/functions/templates) to find the template details. +- `create_vcs_deployment()` - Create a deployment when a function is connected to VCS. + +This endpoint lets you create deployment from a branch, commit, or a tag. +- `get_deployment()` - Get a function deployment by its unique ID. +- `delete_deployment()` - Delete a code deployment by its unique ID. +- `get_deployment_download()` - Get a function deployment content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory. +- `update_deployment_status()` - Cancel an ongoing function deployment build. If the build is already in progress, it will be stopped and marked as canceled. If the build hasn't started yet, it will be marked as canceled without executing. You cannot cancel builds that have already completed (status 'ready') or failed. The response includes the final build status and details. +- `list_executions()` - Get a list of all the current user function execution logs. You can use the query params to filter your results. +- `create_execution()` - Trigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously. +- `get_execution()` - Get a function execution log by its unique ID. +- `delete_execution()` - Delete a function execution by its unique ID. +- `list_variables()` - Get a list of all variables of a specific function. +- `create_variable()` - Create a new function environment variable. These variables can be accessed in the function at runtime as environment variables. +- `get_variable()` - Get a variable by its unique ID. +- `update_variable()` - Update variable by its unique ID. +- `delete_variable()` - Delete a variable by its unique ID. + +#### Graphql +The GraphQL API allows you to query and mutate your Appwrite server using GraphQL. +- `query()` - Execute a GraphQL mutation. +- `mutation()` - Execute a GraphQL mutation. + +#### Health +The Health service allows you to both validate and monitor your Appwrite server's health. +- `get()` - Check the Appwrite HTTP server is up and responsive. +- `get_antivirus()` - Check the Appwrite Antivirus server is up and connection is successful. +- `get_cache()` - Check the Appwrite in-memory cache servers are up and connection is successful. +- `get_certificate()` - Get the SSL certificate for a domain +- `get_console_pausing()` - Get console pausing health status. Monitors projects approaching the pause threshold to detect potential issues with console access tracking. + +- `get_db()` - Check the Appwrite database servers are up and connection is successful. +- `get_pub_sub()` - Check the Appwrite pub-sub servers are up and connection is successful. +- `get_queue_audits()` - Get the number of audit logs that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_billing_project_aggregation()` - Get billing project aggregation queue. +- `get_queue_billing_team_aggregation()` - Get billing team aggregation queue. +- `get_queue_builds()` - Get the number of builds that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_priority_builds()` - Get the priority builds queue size. +- `get_queue_certificates()` - Get the number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server. +- `get_queue_databases()` - Get the number of database changes that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_deletes()` - Get the number of background destructive changes that are waiting to be processed in the Appwrite internal queue server. +- `get_failed_jobs()` - Returns the amount of failed jobs in a given queue. + +- `get_queue_functions()` - Get the number of function executions that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_logs()` - Get the number of logs that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_mails()` - Get the number of mails that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_messaging()` - Get the number of messages that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_migrations()` - Get the number of migrations that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_region_manager()` - Get region manager queue. +- `get_queue_stats_resources()` - Get the number of metrics that are waiting to be processed in the Appwrite stats resources queue. +- `get_queue_usage()` - Get the number of metrics that are waiting to be processed in the Appwrite internal queue server. +- `get_queue_threats()` - Get threats queue. +- `get_queue_webhooks()` - Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server. +- `get_storage()` - Check the Appwrite storage device is up and connection is successful. +- `get_storage_local()` - Check the Appwrite local storage device is up and connection is successful. +- `get_time()` - Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP. + +#### Locale +The Locale service allows you to customize your app based on your users' location. +- `get()` - Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language. + +([IP Geolocation by DB-IP](https://db-ip.com)) +- `list_codes()` - List of all locale codes in [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). +- `list_continents()` - List of all continents. You can use the locale header to get the data in a supported language. +- `list_countries()` - List of all countries. You can use the locale header to get the data in a supported language. +- `list_countries_eu()` - List of all countries that are currently members of the EU. You can use the locale header to get the data in a supported language. +- `list_countries_phones()` - List of all countries phone codes. You can use the locale header to get the data in a supported language. +- `list_currencies()` - List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in a supported language. +- `list_languages()` - List of all languages classified by ISO 639-1 including 2-letter code, name in English, and name in the respective language. + +#### Messaging +The Messaging service allows you to send messages to any provider type (SMTP, push notification, SMS, etc.). +- `list_messages()` - Get a list of all messages from the current Appwrite project. +- `create_email()` - Create a new email message. +- `update_email()` - Update an email message by its unique ID. This endpoint only works on messages that are in draft status. Messages that are already processing, sent, or failed cannot be updated. + +- `create_push()` - Create a new push notification. +- `update_push()` - Update a push notification by its unique ID. This endpoint only works on messages that are in draft status. Messages that are already processing, sent, or failed cannot be updated. + +- `create_sms()` - Create a new SMS message. +- `create_sms()` - Create a new SMS message. +- `update_sms()` - Update an SMS message by its unique ID. This endpoint only works on messages that are in draft status. Messages that are already processing, sent, or failed cannot be updated. + +- `update_sms()` - Update an SMS message by its unique ID. This endpoint only works on messages that are in draft status. Messages that are already processing, sent, or failed cannot be updated. + +- `get_message()` - Get a message by its unique ID. + +- `delete()` - Delete a message. If the message is not a draft or scheduled, but has been sent, this will not recall the message. +- `list_message_logs()` - Get the message activity logs listed by its unique ID. +- `list_targets()` - Get a list of the targets associated with a message. +- `list_providers()` - Get a list of all providers from the current Appwrite project. +- `create_apns_provider()` - Create a new Apple Push Notification service provider. +- `create_apns_provider()` - Create a new Apple Push Notification service provider. +- `update_apns_provider()` - Update a Apple Push Notification service provider by its unique ID. +- `update_apns_provider()` - Update a Apple Push Notification service provider by its unique ID. +- `create_fcm_provider()` - Create a new Firebase Cloud Messaging provider. +- `create_fcm_provider()` - Create a new Firebase Cloud Messaging provider. +- `update_fcm_provider()` - Update a Firebase Cloud Messaging provider by its unique ID. +- `update_fcm_provider()` - Update a Firebase Cloud Messaging provider by its unique ID. +- `create_mailgun_provider()` - Create a new Mailgun provider. +- `update_mailgun_provider()` - Update a Mailgun provider by its unique ID. +- `create_msg91_provider()` - Create a new MSG91 provider. +- `update_msg91_provider()` - Update a MSG91 provider by its unique ID. +- `create_resend_provider()` - Create a new Resend provider. +- `update_resend_provider()` - Update a Resend provider by its unique ID. +- `create_sendgrid_provider()` - Create a new Sendgrid provider. +- `update_sendgrid_provider()` - Update a Sendgrid provider by its unique ID. +- `create_smtp_provider()` - Create a new SMTP provider. +- `create_smtp_provider()` - Create a new SMTP provider. +- `update_smtp_provider()` - Update a SMTP provider by its unique ID. +- `update_smtp_provider()` - Update a SMTP provider by its unique ID. +- `create_telesign_provider()` - Create a new Telesign provider. +- `update_telesign_provider()` - Update a Telesign provider by its unique ID. +- `create_textmagic_provider()` - Create a new Textmagic provider. +- `update_textmagic_provider()` - Update a Textmagic provider by its unique ID. +- `create_twilio_provider()` - Create a new Twilio provider. +- `update_twilio_provider()` - Update a Twilio provider by its unique ID. +- `create_vonage_provider()` - Create a new Vonage provider. +- `update_vonage_provider()` - Update a Vonage provider by its unique ID. +- `get_provider()` - Get a provider by its unique ID. + +- `delete_provider()` - Delete a provider by its unique ID. +- `list_provider_logs()` - Get the provider activity logs listed by its unique ID. +- `list_subscriber_logs()` - Get the subscriber activity logs listed by its unique ID. +- `list_topics()` - Get a list of all topics from the current Appwrite project. +- `create_topic()` - Create a new topic. +- `get_topic()` - Get a topic by its unique ID. + +- `update_topic()` - Update a topic by its unique ID. + +- `delete_topic()` - Delete a topic by its unique ID. +- `list_topic_logs()` - Get the topic activity logs listed by its unique ID. +- `list_subscribers()` - Get a list of all subscribers from the current Appwrite project. +- `create_subscriber()` - Create a new subscriber. +- `get_subscriber()` - Get a subscriber by its unique ID. + +- `delete_subscriber()` - Delete a subscriber by its unique ID. + +#### Sites +The Sites Service allows you view, create and manage your web applications. +- `list()` - Get a list of all the project's sites. You can use the query params to filter your results. +- `create()` - Create a new site. +- `list_frameworks()` - Get a list of all frameworks that are currently available on the server instance. +- `list_specifications()` - List allowed site specifications for this instance. +- `get()` - Get a site by its unique ID. +- `update()` - Update site by its unique ID. +- `delete()` - Delete a site by its unique ID. +- `update_site_deployment()` - Update the site active deployment. Use this endpoint to switch the code deployment that should be used when visitor opens your site. +- `list_deployments()` - Get a list of all the site's code deployments. You can use the query params to filter your results. +- `create_deployment()` - Create a new site code deployment. Use this endpoint to upload a new version of your site code. To activate your newly uploaded code, you'll need to update the site's deployment to use your new deployment ID. +- `create_duplicate_deployment()` - Create a new build for an existing site deployment. This endpoint allows you to rebuild a deployment with the updated site configuration, including its commands and output directory if they have been modified. The build process will be queued and executed asynchronously. The original deployment's code will be preserved and used for the new build. +- `create_template_deployment()` - Create a deployment based on a template. + +Use this endpoint with combination of [listTemplates](https://appwrite.io/docs/products/sites/templates) to find the template details. +- `create_vcs_deployment()` - Create a deployment when a site is connected to VCS. + +This endpoint lets you create deployment from a branch, commit, or a tag. +- `get_deployment()` - Get a site deployment by its unique ID. +- `delete_deployment()` - Delete a site deployment by its unique ID. +- `get_deployment_download()` - Get a site deployment content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory. +- `update_deployment_status()` - Cancel an ongoing site deployment build. If the build is already in progress, it will be stopped and marked as canceled. If the build hasn't started yet, it will be marked as canceled without executing. You cannot cancel builds that have already completed (status 'ready') or failed. The response includes the final build status and details. +- `list_logs()` - Get a list of all site logs. You can use the query params to filter your results. +- `get_log()` - Get a site request log by its unique ID. +- `delete_log()` - Delete a site log by its unique ID. +- `list_variables()` - Get a list of all variables of a specific site. +- `create_variable()` - Create a new site variable. These variables can be accessed during build and runtime (server-side rendering) as environment variables. +- `get_variable()` - Get a variable by its unique ID. +- `update_variable()` - Update variable by its unique ID. +- `delete_variable()` - Delete a variable by its unique ID. + +#### Storage +The Storage service allows you to manage your project files. +- `list_buckets()` - Get a list of all the storage buckets. You can use the query params to filter your results. +- `create_bucket()` - Create a new storage bucket. +- `get_bucket()` - Get a storage bucket by its unique ID. This endpoint response returns a JSON object with the storage bucket metadata. +- `update_bucket()` - Update a storage bucket by its unique ID. +- `delete_bucket()` - Delete a storage bucket by its unique ID. +- `list_files()` - Get a list of all the user files. You can use the query params to filter your results. +- `create_file()` - Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https://appwrite.io/docs/server/storage#storageCreateBucket) API or directly from your Appwrite console. + +Larger files should be uploaded using multiple requests with the [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes. + +When the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one. + +If you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally. + +- `get_file()` - Get a file by its unique ID. This endpoint response returns a JSON object with the file metadata. +- `update_file()` - Update a file by its unique ID. Only users with write permissions have access to update this resource. +- `delete_file()` - Delete a file by its unique ID. Only users with write permissions have access to delete this resource. +- `get_file_download()` - Get a file content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory. +- `get_file_preview()` - Get a file preview image. Currently, this method supports preview for image files (jpg, png, and gif), other supported formats, like pdf, docs, slides, and spreadsheets, will return the file icon image. You can also pass query string arguments for cutting and resizing your preview image. Preview is supported only for image files smaller than 10MB. +- `get_file_view()` - Get a file content by its unique ID. This endpoint is similar to the download method but returns with no 'Content-Disposition: attachment' header. + +#### TablesDB + +- `list()` - Get a list of all databases from the current Appwrite project. You can use the search parameter to filter your results. +- `create()` - Create a new Database. + +- `list_transactions()` - List transactions across all databases. +- `create_transaction()` - Create a new transaction. +- `get_transaction()` - Get a transaction by its unique ID. +- `update_transaction()` - Update a transaction, to either commit or roll back its operations. +- `delete_transaction()` - Delete a transaction by its unique ID. +- `create_operations()` - Create multiple operations in a single transaction. +- `get()` - Get a database by its unique ID. This endpoint response returns a JSON object with the database metadata. +- `update()` - Update a database by its unique ID. +- `delete()` - Delete a database by its unique ID. Only API keys with with databases.write scope can delete a database. +- `list_tables()` - Get a list of all tables that belong to the provided databaseId. You can use the search parameter to filter your results. +- `create_table()` - Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `get_table()` - Get a table by its unique ID. This endpoint response returns a JSON object with the table metadata. +- `update_table()` - Update a table by its unique ID. +- `delete_table()` - Delete a table by its unique ID. Only users with write permissions have access to delete this resource. +- `list_columns()` - List columns in the table. +- `create_boolean_column()` - Create a boolean column. + +- `update_boolean_column()` - Update a boolean column. Changing the `default` value will not update already existing rows. +- `create_datetime_column()` - Create a date time column according to the ISO 8601 standard. +- `update_datetime_column()` - Update a date time column. Changing the `default` value will not update already existing rows. +- `create_email_column()` - Create an email column. + +- `update_email_column()` - Update an email column. Changing the `default` value will not update already existing rows. + +- `create_enum_column()` - Create an enumeration column. The `elements` param acts as a white-list of accepted values for this column. +- `update_enum_column()` - Update an enum column. Changing the `default` value will not update already existing rows. + +- `create_float_column()` - Create a float column. Optionally, minimum and maximum values can be provided. + +- `update_float_column()` - Update a float column. Changing the `default` value will not update already existing rows. + +- `create_integer_column()` - Create an integer column. Optionally, minimum and maximum values can be provided. + +- `update_integer_column()` - Update an integer column. Changing the `default` value will not update already existing rows. + +- `create_ip_column()` - Create IP address column. + +- `update_ip_column()` - Update an ip column. Changing the `default` value will not update already existing rows. + +- `create_line_column()` - Create a geometric line column. +- `update_line_column()` - Update a line column. Changing the `default` value will not update already existing rows. +- `create_longtext_column()` - Create a longtext column. + +- `update_longtext_column()` - Update a longtext column. Changing the `default` value will not update already existing rows. + +- `create_mediumtext_column()` - Create a mediumtext column. + +- `update_mediumtext_column()` - Update a mediumtext column. Changing the `default` value will not update already existing rows. + +- `create_point_column()` - Create a geometric point column. +- `update_point_column()` - Update a point column. Changing the `default` value will not update already existing rows. +- `create_polygon_column()` - Create a geometric polygon column. +- `update_polygon_column()` - Update a polygon column. Changing the `default` value will not update already existing rows. +- `create_relationship_column()` - Create relationship column. [Learn more about relationship columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + +- `create_string_column()` - Create a string column. + +- `update_string_column()` - Update a string column. Changing the `default` value will not update already existing rows. + +- `create_text_column()` - Create a text column. + +- `update_text_column()` - Update a text column. Changing the `default` value will not update already existing rows. + +- `create_url_column()` - Create a URL column. + +- `update_url_column()` - Update an url column. Changing the `default` value will not update already existing rows. + +- `create_varchar_column()` - Create a varchar column. + +- `update_varchar_column()` - Update a varchar column. Changing the `default` value will not update already existing rows. + +- `get_column()` - Get column by ID. +- `delete_column()` - Deletes a column. +- `update_relationship_column()` - Update relationship column. [Learn more about relationship columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + +- `list_indexes()` - List indexes on the table. +- `create_index()` - Creates an index on the columns listed. Your index should include all the columns you will query in a single request. +Type can be `key`, `fulltext`, or `unique`. +- `get_index()` - Get index by ID. +- `delete_index()` - Delete an index. +- `list_rows()` - Get a list of all the user's rows in a given table. You can use the query params to filter your results. +- `create_row()` - Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `create_rows()` - Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `upsert_rows()` - Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. + +- `update_rows()` - Update all rows that match your queries, if no queries are submitted then all rows are updated. You can pass only specific fields to be updated. +- `delete_rows()` - Bulk delete rows using queries, if no queries are passed then all rows are deleted. +- `get_row()` - Get a row by its unique ID. This endpoint response returns a JSON object with the row data. +- `upsert_row()` - Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `update_row()` - Update a row by its unique ID. Using the patch method you can pass only specific fields that will get updated. +- `delete_row()` - Delete a row by its unique ID. +- `decrement_row_column()` - Decrement a specific column of a row by a given value. +- `increment_row_column()` - Increment a specific column of a row by a given value. + +#### Teams +The Teams service allows you to group users of your project and to enable them to share read and write access to your project resources +- `list()` - Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results. +- `create()` - Create a new team. The user who creates the team will automatically be assigned as the owner of the team. Only the users with the owner role can invite new members, add new owners and delete or update the team. +- `get()` - Get a team by its ID. All team members have read access for this resource. +- `update_name()` - Update the team's name by its unique ID. +- `delete()` - Delete a team using its ID. Only team members with the owner role can delete the team. +- `list_memberships()` - Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console. +- `create_membership()` - Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team. + +You only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters. + +Use the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https://appwrite.io/docs/references/cloud/client-web/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. + +Please note that to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console. + +- `get_membership()` - Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console. +- `update_membership()` - Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). + +- `delete_membership()` - This endpoint allows a user to leave a team or for a team owner to delete the membership of any other team member. You can also use this endpoint to delete a user membership even if it is not accepted. +- `update_membership_status()` - Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user. + +If the request is successful, a session for the user is automatically created. + +- `get_prefs()` - Get the team's shared preferences by its unique ID. If a preference doesn't need to be shared by all team members, prefer storing them in [user preferences](https://appwrite.io/docs/references/cloud/client-web/account#getPrefs). +- `update_prefs()` - Update the team's preferences by its unique ID. The object you pass is stored as is and replaces any previous value. The maximum allowed prefs size is 64kB and throws an error if exceeded. + +#### Tokens + +- `list()` - List all the tokens created for a specific file or bucket. You can use the query params to filter your results. +- `create_file_token()` - Create a new token. A token is linked to a file. Token can be passed as a request URL search parameter. +- `get()` - Get a token by its unique ID. +- `update()` - Update a token by its unique ID. Use this endpoint to update a token's expiry date. +- `delete()` - Delete a token by its unique ID. + +#### Users +The Users service allows you to manage your project users. +- `list()` - Get a list of all the project's users. You can use the query params to filter your results. +- `create()` - Create a new user. +- `create_argon2_user()` - Create a new user. Password provided must be hashed with the [Argon2](https://en.wikipedia.org/wiki/Argon2) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `create_bcrypt_user()` - Create a new user. Password provided must be hashed with the [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `list_identities()` - Get identities for all users. +- `delete_identity()` - Delete an identity by its unique ID. +- `create_md5_user()` - Create a new user. Password provided must be hashed with the [MD5](https://en.wikipedia.org/wiki/MD5) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `create_ph_pass_user()` - Create a new user. Password provided must be hashed with the [PHPass](https://www.openwall.com/phpass/) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `create_scrypt_user()` - Create a new user. Password provided must be hashed with the [Scrypt](https://github.com/Tarsnap/scrypt) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `create_scrypt_modified_user()` - Create a new user. Password provided must be hashed with the [Scrypt Modified](https://gist.github.com/Meldiron/eecf84a0225eccb5a378d45bb27462cc) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `create_sha_user()` - Create a new user. Password provided must be hashed with the [SHA](https://en.wikipedia.org/wiki/Secure_Hash_Algorithm) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `get()` - Get a user by its unique ID. +- `delete()` - Delete a user by its unique ID, thereby releasing it's ID. Since ID is released and can be reused, all user-related resources like documents or storage files should be deleted before user deletion. If you want to keep ID reserved, use the [updateStatus](https://appwrite.io/docs/server/users#usersUpdateStatus) endpoint instead. +- `update_email()` - Update the user email by its unique ID. +- `update_impersonator()` - Enable or disable whether a user can impersonate other users. When impersonation headers are used, the request runs as the target user for API behavior, while internal audit logs still attribute the action to the original impersonator and store the impersonated target details only in internal audit payload data. + +- `create_jwt()` - Use this endpoint to create a JSON Web Token for user by its unique ID. You can use the resulting JWT to authenticate on behalf of the user. The JWT secret will become invalid if the session it uses gets deleted. +- `update_labels()` - Update the user labels by its unique ID. + +Labels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https://appwrite.io/docs/permissions) for more info. +- `list_logs()` - Get the user activity logs list by its unique ID. +- `list_memberships()` - Get the user membership list by its unique ID. +- `update_mfa()` - Enable or disable MFA on a user account. +- `update_mfa()` - Enable or disable MFA on a user account. +- `delete_mfa_authenticator()` - Delete an authenticator app. +- `delete_mfa_authenticator()` - Delete an authenticator app. +- `list_mfa_factors()` - List the factors available on the account to be used as a MFA challange. +- `list_mfa_factors()` - List the factors available on the account to be used as a MFA challange. +- `get_mfa_recovery_codes()` - Get recovery codes that can be used as backup for MFA flow by User ID. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `get_mfa_recovery_codes()` - Get recovery codes that can be used as backup for MFA flow by User ID. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `update_mfa_recovery_codes()` - Regenerate recovery codes that can be used as backup for MFA flow by User ID. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `update_mfa_recovery_codes()` - Regenerate recovery codes that can be used as backup for MFA flow by User ID. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `create_mfa_recovery_codes()` - Generate recovery codes used as backup for MFA flow for User ID. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method by client SDK. +- `create_mfa_recovery_codes()` - Generate recovery codes used as backup for MFA flow for User ID. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method by client SDK. +- `update_name()` - Update the user name by its unique ID. +- `update_password()` - Update the user password by its unique ID. +- `update_phone()` - Update the user phone by its unique ID. +- `get_prefs()` - Get the user preferences by its unique ID. +- `update_prefs()` - Update the user preferences by its unique ID. The object you pass is stored as is, and replaces any previous value. The maximum allowed prefs size is 64kB and throws error if exceeded. +- `list_sessions()` - Get the user sessions list by its unique ID. +- `create_session()` - Creates a session for a user. Returns an immediately usable session object. + +If you want to generate a token for a custom authentication flow, use the [POST /users/{userId}/tokens](https://appwrite.io/docs/server/users#createToken) endpoint. +- `delete_sessions()` - Delete all user's sessions by using the user's unique ID. +- `delete_session()` - Delete a user sessions by its unique ID. +- `update_status()` - Update the user status by its unique ID. Use this endpoint as an alternative to deleting a user if you want to keep user's ID reserved. +- `list_targets()` - List the messaging targets that are associated with a user. +- `create_target()` - Create a messaging target. +- `get_target()` - Get a user's push notification target by ID. +- `update_target()` - Update a messaging target. +- `delete_target()` - Delete a messaging target. +- `create_token()` - Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT /account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. + +- `update_email_verification()` - Update the user email verification status by its unique ID. +- `update_phone_verification()` - Update the user phone verification status by its unique ID. + +#### Webhooks + +- `list()` - Get a list of all webhooks belonging to the project. You can use the query params to filter your results. +- `create()` - Create a new webhook. Use this endpoint to configure a URL that will receive events from Appwrite when specific events occur. +- `get()` - Get a webhook by its unique ID. This endpoint returns details about a specific webhook configured for a project. +- `update()` - Update a webhook by its unique ID. Use this endpoint to update the URL, events, or status of an existing webhook. +- `delete()` - Delete a webhook by its unique ID. Once deleted, the webhook will no longer receive project events. +- `update_signature()` - Update the webhook signature key. This endpoint can be used to regenerate the signature key used to sign and validate payload deliveries for a specific webhook. + + +### Models +- `RowList` - Rows List +- `DocumentList` - Documents List +- `TableList` - Tables List +- `CollectionList` - Collections List +- `DatabaseList` - Databases List +- `IndexList` - Indexes List +- `ColumnIndexList` - Column Indexes List +- `UserList` - Users List +- `SessionList` - Sessions List +- `IdentityList` - Identities List +- `LogList` - Logs List +- `FileList` - Files List +- `BucketList` - Buckets List +- `ResourceTokenList` - Resource Tokens List +- `TeamList` - Teams List +- `MembershipList` - Memberships List +- `SiteList` - Sites List +- `FunctionList` - Functions List +- `FrameworkList` - Frameworks List +- `RuntimeList` - Runtimes List +- `DeploymentList` - Deployments List +- `ExecutionList` - Executions List +- `WebhookList` - Webhooks List +- `CountryList` - Countries List +- `ContinentList` - Continents List +- `LanguageList` - Languages List +- `CurrencyList` - Currencies List +- `PhoneList` - Phones List +- `VariableList` - Variables List +- `HealthStatusList` - Status List +- `LocaleCodeList` - Locale codes list +- `ProviderList` - Provider list +- `MessageList` - Message list +- `TopicList` - Topic list +- `SubscriberList` - Subscriber list +- `TargetList` - Target list +- `TransactionList` - Transaction List +- `SpecificationList` - Specifications List +- `Database` - Database +- `Collection` - Collection +- `AttributeList` - Attributes List +- `AttributeString` - AttributeString +- `AttributeInteger` - AttributeInteger +- `AttributeFloat` - AttributeFloat +- `AttributeBoolean` - AttributeBoolean +- `AttributeEmail` - AttributeEmail +- `AttributeEnum` - AttributeEnum +- `AttributeIp` - AttributeIP +- `AttributeUrl` - AttributeURL +- `AttributeDatetime` - AttributeDatetime +- `AttributeRelationship` - AttributeRelationship +- `AttributePoint` - AttributePoint +- `AttributeLine` - AttributeLine +- `AttributePolygon` - AttributePolygon +- `AttributeVarchar` - AttributeVarchar +- `AttributeText` - AttributeText +- `AttributeMediumtext` - AttributeMediumtext +- `AttributeLongtext` - AttributeLongtext +- `Table` - Table +- `ColumnList` - Columns List +- `ColumnString` - ColumnString +- `ColumnInteger` - ColumnInteger +- `ColumnFloat` - ColumnFloat +- `ColumnBoolean` - ColumnBoolean +- `ColumnEmail` - ColumnEmail +- `ColumnEnum` - ColumnEnum +- `ColumnIp` - ColumnIP +- `ColumnUrl` - ColumnURL +- `ColumnDatetime` - ColumnDatetime +- `ColumnRelationship` - ColumnRelationship +- `ColumnPoint` - ColumnPoint +- `ColumnLine` - ColumnLine +- `ColumnPolygon` - ColumnPolygon +- `ColumnVarchar` - ColumnVarchar +- `ColumnText` - ColumnText +- `ColumnMediumtext` - ColumnMediumtext +- `ColumnLongtext` - ColumnLongtext +- `Index` - Index +- `ColumnIndex` - Index +- `Row` - Row +- `Document` - Document +- `Log` - Log +- `User` - User +- `AlgoMd5` - AlgoMD5 +- `AlgoSha` - AlgoSHA +- `AlgoPhpass` - AlgoPHPass +- `AlgoBcrypt` - AlgoBcrypt +- `AlgoScrypt` - AlgoScrypt +- `AlgoScryptModified` - AlgoScryptModified +- `AlgoArgon2` - AlgoArgon2 +- `Preferences` - Preferences +- `Session` - Session +- `Identity` - Identity +- `Token` - Token +- `Jwt` - JWT +- `Locale` - Locale +- `LocaleCode` - LocaleCode +- `File` - File +- `Bucket` - Bucket +- `ResourceToken` - ResourceToken +- `Team` - Team +- `Membership` - Membership +- `Site` - Site +- `Function` - Function +- `Runtime` - Runtime +- `Framework` - Framework +- `FrameworkAdapter` - Framework Adapter +- `Deployment` - Deployment +- `Execution` - Execution +- `Webhook` - Webhook +- `Variable` - Variable +- `Country` - Country +- `Continent` - Continent +- `Language` - Language +- `Currency` - Currency +- `Phone` - Phone +- `HealthAntivirus` - Health Antivirus +- `HealthQueue` - Health Queue +- `HealthStatus` - Health Status +- `HealthCertificate` - Health Certificate +- `HealthTime` - Health Time +- `Headers` - Headers +- `Specification` - Specification +- `MfaChallenge` - MFA Challenge +- `MfaRecoveryCodes` - MFA Recovery Codes +- `MfaType` - MFAType +- `MfaFactors` - MFAFactors +- `Provider` - Provider +- `Message` - Message +- `Topic` - Topic +- `Transaction` - Transaction +- `Subscriber` - Subscriber +- `Target` - Target +- `ActivityEvent` - ActivityEvent +- `BackupArchive` - Archive +- `BackupPolicy` - backup +- `BackupRestoration` - Restoration +- `ActivityEventList` - Activity event list +- `BackupArchiveList` - Backup archive list +- `BackupPolicyList` - Backup policy list +- `BackupRestorationList` - Backup restoration list + +### Dependencies +- reqwest 0.12+ for HTTP client +- serde 1.0+ for JSON serialization +- tokio 1.0+ for async runtime +- fastrand 2.0+ for ID generation +- thiserror 1.0+ for error handling + +### Documentation +- Complete API documentation +- Usage examples for all methods +- Error handling guide +- File upload examples +- Query builder documentation + +[0.1.1]: https://github.com/appwrite/sdk-for-rust/releases/tag/0.1.1 diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c38baea --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "appwrite" +version = "0.1.1" +edition = "2021" +rust-version = "1.83" +authors = ["appwrite"] +description = "Appwrite SDK for Rust" +documentation = "https://docs.rs/appwrite" +repository = "https://github.com/appwrite/sdk-for-rust" +license = "BSD-3-Clause" +keywords = ["appwrite", "sdk", "api", "backend", "baas"] +categories = ["api-bindings", "web-programming"] +readme = "README.md" +autobins = false +autoexamples = false +autotests = false +autobenches = false + +[dependencies] +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0" +reqwest = { version = "0.12.28", features = ["json", "multipart", "stream"] } +tokio = { version = "1.48.0", features = ["full"] } +url = "2.4" +mime = "0.3" +fastrand = "2.0" +thiserror = "1.0" +bytes = "1.0" +arc-swap = "1.8.0" + +[dev-dependencies] +tokio-test = "0.4" +wiremock = "0.5" + +[lib] +name = "appwrite" +path = "src/lib.rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/LICENSE b/LICENSE index a160c94..9b1eea7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,29 +1,12 @@ -BSD 3-Clause License - -Copyright (c) 2021, Appwrite +Copyright (c) 2026 Appwrite (https://appwrite.io) and individual contributors. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index b2d0165..3317665 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,107 @@ -# sdk-for-rust -[READ-ONLY] Official Appwrite Rust SDK ⚙️ +# Appwrite Rust SDK + +![License](https://img.shields.io/github/license/appwrite/sdk-for-rust.svg) +![Version](https://img.shields.io/badge/api%20version-1.9.0-blue.svg) +[![Crates.io](https://img.shields.io/crates/v/appwrite.svg)](https://crates.io/crates/appwrite) +[![Documentation](https://docs.rs/appwrite/badge.svg)](https://docs.rs/appwrite) + +**This SDK is compatible with Appwrite server version 1.8.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-rust/releases).** + +Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Rust SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) + +![Appwrite](https://github.com/appwrite/appwrite/raw/main/public/images/github.png) + +## Installation + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +appwrite = "0.1.1" +tokio = { version = "1.48", features = ["full"] } +``` + +Or using `cargo add`: + +```bash +cargo add appwrite +``` + + +## Getting Started + +### Init your SDK +Initialize your SDK with your Appwrite server API endpoint and project ID which can be found on your project settings page and your new API secret Key from project's API keys section. + +```rust +use appwrite::client::Client; + +let client = Client::new() + .set_endpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint + .set_project("5df5acd0d48c2") // Your project ID + .set_key("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key + .set_self_signed(true); // Use only on dev mode with a self-signed SSL cert +``` + +### Make Your First Request +Once your SDK object is set, create any of the Appwrite service objects and choose any request to send. Full documentation for any service method you would like to use can be found in your SDK documentation or in the [API References](https://appwrite.io/docs) section. + +```rust +use appwrite::client::Client; +use appwrite::services::users::Users; +use appwrite::id::ID; + +let client = Client::new() + .set_endpoint("https://[HOSTNAME_OR_IP]/v1") + .set_project("5df5acd0d48c2") + .set_key("919c2d18fb5d4...a2ae413da83346ad2") + .set_self_signed(true); + +let users = Users::new(&client); + +let user = users.create( + ID::unique(), + Some("email@example.com"), + Some("+123456789"), + Some("password"), + Some("Walter O'Brien"), +).await?; + +println!("{}", user.name); +println!("{}", user.email); +``` + +### Error Handling +The Appwrite Rust SDK returns `Result` types. You can handle errors using standard Rust error handling patterns. Below is an example. + +```rust +use appwrite::error::AppwriteError; + +match users.create( + ID::unique(), + Some("email@example.com"), + Some("+123456789"), + Some("password"), + Some("Walter O'Brien"), +).await { + Ok(user) => println!("{}", user.name), + Err(AppwriteError { message, code, .. }) => { + eprintln!("Error {}: {}", code, message); + } +} +``` + +### Learn more +You can use the following resources to learn more and get help +- 🚀 [Getting Started Tutorial](https://appwrite.io/docs/getting-started-for-server) +- 📜 [Appwrite Docs](https://appwrite.io/docs) +- 💬 [Discord Community](https://appwrite.io/discord) + + +## Contribution + +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. + +## License + +Please see the [BSD-3-Clause license](https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE) file for more information. diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..3ef3d65 --- /dev/null +++ b/src/client.rs @@ -0,0 +1,904 @@ +//! HTTP client for Appwrite API + +use crate::error::AppwriteError; +use crate::error::Result; +use crate::input_file::InputFile; +use arc_swap::ArcSwap; +use reqwest::{header::HeaderMap, multipart, Client as HttpClient, Method, Response}; +use serde::de::DeserializeOwned; +use serde_json::Value; +use std::collections::HashMap; +use std::sync::Arc; +use std::time::Duration; +use url::Url; + +/// Default request timeout in seconds +const DEFAULT_TIMEOUT: u64 = 10; + +/// Default chunk size for file uploads (5MB) +const DEFAULT_CHUNK_SIZE: usize = 5 * 1024 * 1024; + +/// Upload progress information +#[derive(Debug, Clone, Copy)] +pub struct UploadProgress { + /// Number of bytes uploaded so far + pub bytes_uploaded: u64, + /// Total number of bytes to upload + pub total_bytes: u64, + /// Number of chunks uploaded so far + pub chunks_uploaded: u64, + /// Total number of chunks + pub total_chunks: u64, +} + +impl UploadProgress { + /// Get the upload progress as a percentage (0.0 to 100.0) + pub fn percentage(&self) -> f64 { + if self.total_bytes == 0 { + return 0.0; + } + (self.bytes_uploaded as f64 / self.total_bytes as f64) * 100.0 + } +} + +/// Options for file upload operations +pub struct UploadOptions { + pub upload_id: Option, + pub on_progress: Option, +} + +impl Default for UploadOptions { + fn default() -> Self { + Self { + upload_id: None, + on_progress: None, + } + } +} + +/// Appwrite client for making API requests +#[derive(Debug, Clone)] +pub struct Client { + state: Arc>, +} + +#[derive(Debug, Clone)] +struct ClientState { + config: Config, + http: HttpClient, + http_no_redirect: HttpClient, +} + +#[derive(Debug, Clone)] +struct Config { + endpoint: String, + headers: HeaderMap, + self_signed: bool, + chunk_size: usize, + timeout_secs: u64, +} + +impl Default for Client { + fn default() -> Self { + Self::new() + } +} + +impl Client { + /// Create a new Appwrite client + pub fn new() -> Self { + let mut headers = HeaderMap::new(); + headers.insert("X-Appwrite-Response-Format", "1.9.0".parse().unwrap()); + headers.insert("user-agent", format!("AppwriteRustSDK/0.1.1 ({}; {})", std::env::consts::OS, std::env::consts::ARCH).parse().unwrap()); + headers.insert("x-sdk-name", "Rust".parse().unwrap()); + headers.insert("x-sdk-platform", "server".parse().unwrap()); + headers.insert("x-sdk-language", "rust".parse().unwrap()); + headers.insert("x-sdk-version", "0.1.1".parse().unwrap()); + + let config = Config { + endpoint: "https://cloud.appwrite.io/v1".to_string(), + headers, + self_signed: false, + chunk_size: DEFAULT_CHUNK_SIZE, + timeout_secs: DEFAULT_TIMEOUT, + }; + + let http = Self::build_http_client(&config); + let http_no_redirect = Self::build_http_client_no_redirect(&config); + + let state = ClientState { config, http, http_no_redirect }; + + Self { + state: Arc::new(ArcSwap::from_pointee(state)), + } + } + + fn build_http_client(config: &Config) -> HttpClient { + let mut builder = HttpClient::builder().timeout(Duration::from_secs(config.timeout_secs)); + + if config.self_signed { + builder = builder.danger_accept_invalid_certs(true); + } + + builder.build().expect("Failed to create HTTP client") + } + + fn build_http_client_no_redirect(config: &Config) -> HttpClient { + let mut builder = HttpClient::builder() + .redirect(reqwest::redirect::Policy::none()) + .timeout(Duration::from_secs(config.timeout_secs)); + + if config.self_signed { + builder = builder.danger_accept_invalid_certs(true); + } + + builder.build().expect("Failed to create no-redirect HTTP client") + } + + /// Set the API endpoint + pub fn set_endpoint>(&self, endpoint: S) -> Self { + let endpoint = endpoint.into(); + if !endpoint.starts_with("http://") && !endpoint.starts_with("https://") { + panic!("Invalid endpoint URL: {}. Endpoint must start with http:// or https://", endpoint); + } + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.endpoint = endpoint.clone(); + Arc::new(next) + }); + self.clone() + } + + /// Set the project ID + pub fn set_project>(&self, project: S) -> Self { + let project = project.into(); + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.headers.insert("x-appwrite-project", project.clone().parse().unwrap()); + Arc::new(next) + }); + self.clone() + } + + /// Set the API key + pub fn set_key>(&self, key: S) -> Self { + let key = key.into(); + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.headers.insert("x-appwrite-key", key.clone().parse().unwrap()); + Arc::new(next) + }); + self.clone() + } + + /// Set the JWT token + pub fn set_jwt>(&self, jwt: S) -> Self { + let jwt = jwt.into(); + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.headers.insert("x-appwrite-jwt", jwt.clone().parse().unwrap()); + Arc::new(next) + }); + self.clone() + } + + /// Set the locale + pub fn set_locale>(&self, locale: S) -> Self { + let locale = locale.into(); + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.headers.insert("x-appwrite-locale", locale.clone().parse().unwrap()); + Arc::new(next) + }); + self.clone() + } + + /// Set the session + pub fn set_session>(&self, session: S) -> Self { + let session = session.into(); + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.headers.insert("x-appwrite-session", session.clone().parse().unwrap()); + Arc::new(next) + }); + self.clone() + } + + /// Enable or disable self-signed certificates + pub fn set_self_signed(&self, self_signed: bool) -> Self { + self.state.rcu(|state| { + let mut next = (**state).clone(); + if next.config.self_signed != self_signed { + next.config.self_signed = self_signed; + next.http = Self::build_http_client(&next.config); + next.http_no_redirect = Self::build_http_client_no_redirect(&next.config); + } + Arc::new(next) + }); + self.clone() + } + + /// Set chunk size for file uploads (minimum 1 byte) + pub fn set_chunk_size(&self, chunk_size: usize) -> Self { + self.state.rcu(|state| { + let mut next = (**state).clone(); + next.config.chunk_size = chunk_size.max(1); + Arc::new(next) + }); + self.clone() + } + + /// Set request timeout in seconds + pub fn set_timeout(&self, timeout_secs: u64) -> Self { + self.state.rcu(|state| { + let mut next = (**state).clone(); + if next.config.timeout_secs != timeout_secs { + next.config.timeout_secs = timeout_secs; + next.http = Self::build_http_client(&next.config); + next.http_no_redirect = Self::build_http_client_no_redirect(&next.config); + } + Arc::new(next) + }); + self.clone() + } + + /// Add a custom header + pub fn add_header, V: AsRef>(&self, key: K, value: V) -> Self { + use reqwest::header::{HeaderName, HeaderValue}; + + let key = key.as_ref().to_string(); + let value = value.as_ref().to_string(); + + self.state.rcu(|state| { + let mut next = (**state).clone(); + if let (Ok(header_name), Ok(header_value)) = ( + key.parse::(), + value.parse::(), + ) { + next.config.headers.insert(header_name, header_value); + } + Arc::new(next) + }); + self.clone() + } + + /// Get the current endpoint + pub fn endpoint(&self) -> String { + let state = self.state.load(); + state.config.endpoint.clone() + } + + /// Serialize primitive parameter value to string + fn serialize_param_value(value: &Value) -> String { + match value { + Value::String(s) => s.clone(), + Value::Number(n) => n.to_string(), + Value::Bool(b) => b.to_string(), + Value::Null => String::new(), + _ => value.to_string(), + } + } + + /// Flatten parameters for GET query strings + /// Converts nested arrays/objects to bracket notation: key[0], key[subkey], etc. + fn flatten_query_params(params: &HashMap) -> Vec<(String, String)> { + let mut result = Vec::new(); + + for (key, value) in params { + match value { + Value::Array(arr) => { + for item in arr { + match item { + Value::String(s) => result.push((format!("{}[]", key), s.clone())), + Value::Number(n) => result.push((format!("{}[]", key), n.to_string())), + Value::Bool(b) => result.push((format!("{}[]", key), b.to_string())), + Value::Null => result.push((format!("{}[]", key), String::new())), + _ => { + result.push((format!("{}[]", key), serde_json::to_string(item).unwrap_or_default())); + } + } + } + } + Value::Object(_) => { + result.push((key.clone(), serde_json::to_string(value).unwrap_or_default())); + } + _ => { + result.push((key.clone(), Self::serialize_param_value(value))); + } + } + } + + result + } + + /// Flatten nested parameters for multipart form data + /// Converts nested arrays/objects to bracket notation: key[0], key[subkey], etc. + fn flatten_multipart_params(params: &HashMap, prefix: &str) -> Vec<(String, String)> { + let mut result = Vec::new(); + + for (key, value) in params { + let final_key = if prefix.is_empty() { + key.clone() + } else { + format!("{}[{}]", prefix, key) + }; + + match value { + Value::Array(arr) => { + for (i, item) in arr.iter().enumerate() { + let array_key = format!("{}[{}]", final_key, i); + if item.is_object() || item.is_array() { + let mut nested = HashMap::new(); + nested.insert(String::new(), item.clone()); + let flattened = Self::flatten_multipart_params(&nested, &array_key); + result.extend(flattened); + } else { + result.push((array_key, Self::serialize_param_value(item))); + } + } + } + Value::Object(obj) => { + let mut nested_map = HashMap::new(); + for (nested_key, nested_value) in obj { + nested_map.insert(nested_key.clone(), nested_value.clone()); + } + let flattened = Self::flatten_multipart_params(&nested_map, &final_key); + result.extend(flattened); + } + _ => { + result.push((final_key, Self::serialize_param_value(value))); + } + } + } + + result + } + + pub async fn call( + &self, + method: Method, + path: &str, + headers: Option>, + params: Option>, + ) -> Result { + let state = self.state.load_full(); + let url = format!("{}{}", state.config.endpoint, path); + let mut request_builder; + + if let Some(params) = params { + if method == Method::GET { + let mut url_with_params = Url::parse(&url).map_err(|e| AppwriteError::new(0, format!("Invalid URL: {}", e), None, String::new()))?; + { + let mut query_pairs = url_with_params.query_pairs_mut(); + for (key, value) in Self::flatten_query_params(¶ms) { + query_pairs.append_pair(&key, &value); + } + } + request_builder = state.http.request(method.clone(), url_with_params); + } else { + request_builder = state.http.request(method.clone(), &url); + request_builder = request_builder.json(¶ms); + } + } else { + request_builder = state.http.request(method.clone(), &url); + } + + request_builder = request_builder.headers(state.config.headers.clone()); + + if let Some(custom_headers) = headers { + for (key, value) in custom_headers { + request_builder = request_builder.header(key, value); + } + } + + let response = request_builder.send().await?; + self.handle_response(response).await + } + + /// Make an API call that returns a location/redirect URL (for webAuth endpoints) + pub async fn call_location( + &self, + method: Method, + path: &str, + headers: Option>, + params: Option>, + ) -> Result { + let state = self.state.load_full(); + let url = format!("{}{}", state.config.endpoint, path); + + let mut request_builder = state.http_no_redirect.request(method.clone(), &url); + + request_builder = request_builder.headers(state.config.headers.clone()); + + if let Some(ref custom_headers) = headers { + for (key, value) in custom_headers { + request_builder = request_builder.header(key, value); + } + } + + if let Some(params) = params { + if method == Method::GET { + let mut url_with_params = Url::parse(&url).map_err(|e| AppwriteError::new(0, format!("Invalid URL: {}", e), None, String::new()))?; + { + let mut query_pairs = url_with_params.query_pairs_mut(); + for (key, value) in Self::flatten_query_params(¶ms) { + query_pairs.append_pair(&key, &value); + } + } + request_builder = state.http_no_redirect.request(method, url_with_params); + request_builder = request_builder.headers(state.config.headers.clone()); + if let Some(ref custom_headers) = headers { + for (key, value) in custom_headers { + request_builder = request_builder.header(key, value); + } + } + } else { + request_builder = request_builder.json(¶ms); + } + } + + let response = request_builder.send().await?; + + let status = response.status(); + + if status.is_redirection() { + response + .headers() + .get("location") + .and_then(|v| v.to_str().ok()) + .map(|s| s.to_string()) + .ok_or_else(|| AppwriteError::new( + status.as_u16(), + "Location header not found in redirect response", + None, + String::new(), + )) + } else { + let content_type = response + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("") + .to_string(); + + let error_text = response.text().await?; + + if content_type.starts_with("application/json") { + if let Ok(error_json) = serde_json::from_str::(&error_text) { + let message = error_json + .get("message") + .and_then(|v| v.as_str()) + .unwrap_or("Unknown error"); + let error_type = error_json + .get("type") + .and_then(|v| v.as_str()) + .map(|v| v.to_string()); + return Err(AppwriteError::new( + status.as_u16(), + message, + error_type, + error_text, + )); + } + } + + Err(AppwriteError::new( + status.as_u16(), + error_text.clone(), + None, + error_text, + )) + } + } + + /// Make an API call that returns raw bytes (for downloads/location endpoints) + pub async fn call_bytes( + &self, + method: Method, + path: &str, + headers: Option>, + params: Option>, + ) -> Result> { + let state = self.state.load_full(); + let url = format!("{}{}", state.config.endpoint, path); + let mut request_builder; + + if let Some(params) = params { + if method == Method::GET { + let mut url_with_params = Url::parse(&url).map_err(|e| AppwriteError::new(0, format!("Invalid URL: {}", e), None, String::new()))?; + { + let mut query_pairs = url_with_params.query_pairs_mut(); + for (key, value) in Self::flatten_query_params(¶ms) { + query_pairs.append_pair(&key, &value); + } + } + request_builder = state.http.request(method.clone(), url_with_params); + } else { + request_builder = state.http.request(method.clone(), &url); + request_builder = request_builder.json(¶ms); + } + } else { + request_builder = state.http.request(method.clone(), &url); + } + + request_builder = request_builder.headers(state.config.headers.clone()); + + if let Some(custom_headers) = headers { + for (key, value) in custom_headers { + request_builder = request_builder.header(key, value); + } + } + + let response = request_builder.send().await?; + + let status = response.status(); + if status.is_success() { + let bytes = response.bytes().await?; + Ok(bytes.to_vec()) + } else { + let content_type = response + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("") + .to_string(); + + let error_text = response.text().await?; + + if content_type.starts_with("application/json") { + if let Ok(error_json) = serde_json::from_str::(&error_text) { + let message = error_json + .get("message") + .and_then(|v| v.as_str()) + .unwrap_or("Unknown error"); + let error_type = error_json + .get("type") + .and_then(|v| v.as_str()) + .map(|v| v.to_string()); + return Err(AppwriteError::new( + status.as_u16(), + message, + error_type, + error_text, + )); + } + } + + Err(AppwriteError::new( + status.as_u16(), + error_text.clone(), + None, + error_text, + )) + } + } + + /// Upload a file + pub async fn file_upload( + &self, + path: &str, + headers: Option>, + params: HashMap, + param_name: &str, + input_file: InputFile, + upload_id: Option, + ) -> Result { + self.file_upload_with_progress( + path, + headers, + params, + param_name, + input_file, + UploadOptions { + upload_id, + on_progress: None::, + }, + ) + .await + } + + /// Upload a file with progress callback + pub async fn file_upload_with_progress( + &self, + path: &str, + headers: Option>, + params: HashMap, + param_name: &str, + input_file: InputFile, + options: UploadOptions, + ) -> Result + where + F: Fn(UploadProgress), + { + let file_size = input_file.size().await?; + let chunk_size = { + let state = self.state.load(); + state.config.chunk_size.max(1) + }; + + if file_size <= chunk_size as u64 { + let state = self.state.load_full(); + let url = if let Some(id) = &options.upload_id { + format!("{}{}/{}", state.config.endpoint, path, id) + } else { + format!("{}{}", state.config.endpoint, path) + }; + + let result = self.single_file_upload(&url, headers, params, param_name, &input_file).await?; + + if let Some(callback) = &options.on_progress { + callback(UploadProgress { + bytes_uploaded: file_size, + total_bytes: file_size, + chunks_uploaded: 1, + total_chunks: 1, + }); + } + + return Ok(result); + } + + self.chunked_file_upload_with_progress(path, headers, params, param_name, &input_file, options).await + } + + async fn single_file_upload( + &self, + url: &str, + headers: Option>, + params: HashMap, + param_name: &str, + input_file: &InputFile, + ) -> Result { + let state = self.state.load_full(); + let mut form = multipart::Form::new(); + + let file_data = input_file.read_all().await?; + let file_size = file_data.len() as u64; + let mut file_part = multipart::Part::stream_with_length(file_data, file_size) + .file_name(input_file.filename().to_string()); + + if let Some(mime_type) = input_file.mime_type() { + file_part = file_part.mime_str(mime_type) + .map_err(|e| AppwriteError::new(0, format!("Invalid MIME type: {}", e), None, String::new()))?; + } + + form = form.part(param_name.to_string(), file_part); + + let mut params_to_flatten = HashMap::new(); + for (key, value) in params { + if key != param_name { + params_to_flatten.insert(key, value); + } + } + + for (key, value_str) in Self::flatten_multipart_params(¶ms_to_flatten, "") { + form = form.text(key, value_str); + } + + let mut request_builder = state.http.post(url).headers(state.config.headers.clone()); + + if let Some(custom_headers) = headers { + for (key, value) in custom_headers { + // Skip content-type for multipart - reqwest sets it automatically with boundary + if key.to_lowercase() != "content-type" { + request_builder = request_builder.header(key, value); + } + } + } + + let response = request_builder + .multipart(form) + .send() + .await + ?; + + self.handle_response(response).await + } + + async fn chunked_file_upload_with_progress( + &self, + path: &str, + headers: Option>, + params: HashMap, + param_name: &str, + input_file: &InputFile, + options: UploadOptions, + ) -> Result + where + F: Fn(UploadProgress), + { + let file_size = input_file.size().await?; + let chunk_size = { + let state = self.state.load(); + state.config.chunk_size.max(1) + }; + let total_chunks = file_size.div_ceil(chunk_size as u64); + let mut current_upload_id = options.upload_id; + let mut start_chunk = 0u64; + if let Some(ref id) = current_upload_id { + if let Ok(response) = self.call::( + Method::GET, + &format!("{}/{}", path, id), + None, + None, + ).await { + if let Some(chunks_uploaded) = response.get("chunksUploaded").and_then(|v| v.as_u64()) { + start_chunk = chunks_uploaded; + } + } + } + + let mut reader = input_file.chunked_reader().await?; + + if start_chunk > 0 { + let resume_offset = start_chunk * chunk_size as u64; + reader.seek(resume_offset).await?; + } + + let mut last_response = None; + + for chunk_index in start_chunk..total_chunks { + let chunk_data = match reader.read_next(chunk_size).await? { + Some(data) => data, + None => break, + }; + let actual_chunk_size = chunk_data.len(); + let start = reader.position() - actual_chunk_size as u64; + + if actual_chunk_size == 0 { + break; + } + + let state = self.state.load_full(); + let mut form = multipart::Form::new(); + let mut file_part = multipart::Part::stream_with_length(chunk_data, actual_chunk_size as u64) + .file_name(input_file.filename().to_string()); + + if let Some(mime_type) = input_file.mime_type() { + file_part = file_part.mime_str(mime_type) + .map_err(|e| AppwriteError::new(0, format!("Invalid MIME type: {}", e), None, String::new()))?; + } + + form = form.part(param_name.to_string(), file_part); + + let mut params_to_flatten = HashMap::new(); + for (key, value) in ¶ms { + if key != param_name { + params_to_flatten.insert(key.clone(), value.clone()); + } + } + + for (key, value_str) in Self::flatten_multipart_params(¶ms_to_flatten, "") { + form = form.text(key, value_str); + } + + let url = format!("{}{}", state.config.endpoint, path); + let mut request_builder = state.http.post(url).headers(state.config.headers.clone()); + + if let Some(ref custom_headers) = headers { + for (key, value) in custom_headers { + // Skip content-type for multipart - reqwest sets it automatically with boundary + if key.to_lowercase() != "content-type" { + request_builder = request_builder.header(key, value); + } + } + } + + if let Some(ref id) = current_upload_id { + request_builder = request_builder.header("x-appwrite-id", id); + } + + let chunk_end = start + actual_chunk_size as u64 - 1; + let content_range = format!("bytes {}-{}/{}", start, chunk_end, file_size); + request_builder = request_builder.header("content-range", content_range); + + let response = request_builder + .multipart(form) + .send() + .await + ?; + + let result: Value = self.handle_response(response).await?; + + if current_upload_id.is_none() { + if let Some(id) = result.get("$id").and_then(|v| v.as_str()) { + current_upload_id = Some(id.to_string()); + } + } + + last_response = Some(result); + + if let Some(ref callback) = options.on_progress { + callback(UploadProgress { + bytes_uploaded: start + actual_chunk_size as u64, + total_bytes: file_size, + chunks_uploaded: chunk_index + 1, + total_chunks, + }); + } + } + + last_response + .ok_or_else(|| AppwriteError::new(0, "No chunks uploaded", None, String::new())) + .and_then(|v| serde_json::from_value(v).map_err(Into::into)) + } + + async fn handle_response(&self, response: Response) -> Result { + let status = response.status(); + let content_type = response + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .map(|s| s.to_string()) + .unwrap_or_default(); + let content_type = content_type.as_str(); + + if status.is_success() { + let bytes = response.bytes().await?; + + if !content_type.is_empty() && !content_type.starts_with("application/json") && !bytes.is_empty() { + return Err(AppwriteError::new( + status.as_u16(), + format!("Expected JSON response but received content-type: {}", content_type), + None, + String::from_utf8_lossy(&bytes).to_string(), + )); + } + + Ok(if bytes.is_empty() { + serde_json::from_slice(b"null")? + } else { + serde_json::from_slice(&bytes)? + }) + } else { + let error_text = response.text().await?; + + if content_type.starts_with("application/json") { + if let Ok(error_json) = serde_json::from_str::(&error_text) { + let message = error_json + .get("message") + .and_then(|v| v.as_str()) + .unwrap_or("Unknown error"); + let error_type = error_json + .get("type") + .and_then(|v| v.as_str()) + .map(|v| v.to_string()); + return Err(AppwriteError::new( + status.as_u16(), + message, + error_type, + error_text, + )); + } + } + + Err(AppwriteError::new( + status.as_u16(), + error_text.clone(), + None, + error_text, + )) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_client_creation() { + let client = Client::new(); + assert_eq!(client.endpoint(), "https://cloud.appwrite.io/v1"); + } + + #[test] + fn test_client_builder_pattern() { + let client = Client::new() + .set_endpoint("https://custom.example.com/v1") + .set_project("test-project") + .set_key("test-key"); + + assert_eq!(client.endpoint(), "https://custom.example.com/v1"); + } +} diff --git a/src/enums/adapter.rs b/src/enums/adapter.rs new file mode 100644 index 0000000..e2725e2 --- /dev/null +++ b/src/enums/adapter.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Adapter { + #[serde(rename = "static")] + #[default] + Static, + #[serde(rename = "ssr")] + Ssr, +} + +impl Adapter { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Adapter::Static => "static", + Adapter::Ssr => "ssr", + } + } +} + +impl std::fmt::Display for Adapter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/attribute_status.rs b/src/enums/attribute_status.rs new file mode 100644 index 0000000..a1d577f --- /dev/null +++ b/src/enums/attribute_status.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum AttributeStatus { + #[serde(rename = "available")] + #[default] + Available, + #[serde(rename = "processing")] + Processing, + #[serde(rename = "deleting")] + Deleting, + #[serde(rename = "stuck")] + Stuck, + #[serde(rename = "failed")] + Failed, +} + +impl AttributeStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + AttributeStatus::Available => "available", + AttributeStatus::Processing => "processing", + AttributeStatus::Deleting => "deleting", + AttributeStatus::Stuck => "stuck", + AttributeStatus::Failed => "failed", + } + } +} + +impl std::fmt::Display for AttributeStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/authentication_factor.rs b/src/enums/authentication_factor.rs new file mode 100644 index 0000000..fa0280d --- /dev/null +++ b/src/enums/authentication_factor.rs @@ -0,0 +1,32 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum AuthenticationFactor { + #[serde(rename = "email")] + #[default] + Email, + #[serde(rename = "phone")] + Phone, + #[serde(rename = "totp")] + Totp, + #[serde(rename = "recoverycode")] + Recoverycode, +} + +impl AuthenticationFactor { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + AuthenticationFactor::Email => "email", + AuthenticationFactor::Phone => "phone", + AuthenticationFactor::Totp => "totp", + AuthenticationFactor::Recoverycode => "recoverycode", + } + } +} + +impl std::fmt::Display for AuthenticationFactor { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/authenticator_type.rs b/src/enums/authenticator_type.rs new file mode 100644 index 0000000..b3f96a3 --- /dev/null +++ b/src/enums/authenticator_type.rs @@ -0,0 +1,23 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum AuthenticatorType { + #[serde(rename = "totp")] + #[default] + Totp, +} + +impl AuthenticatorType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + AuthenticatorType::Totp => "totp", + } + } +} + +impl std::fmt::Display for AuthenticatorType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/backup_services.rs b/src/enums/backup_services.rs new file mode 100644 index 0000000..97b0a3c --- /dev/null +++ b/src/enums/backup_services.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum BackupServices { + #[serde(rename = "databases")] + #[default] + Databases, + #[serde(rename = "functions")] + Functions, + #[serde(rename = "storage")] + Storage, +} + +impl BackupServices { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + BackupServices::Databases => "databases", + BackupServices::Functions => "functions", + BackupServices::Storage => "storage", + } + } +} + +impl std::fmt::Display for BackupServices { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/browser.rs b/src/enums/browser.rs new file mode 100644 index 0000000..ea958fb --- /dev/null +++ b/src/enums/browser.rs @@ -0,0 +1,62 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Browser { + #[serde(rename = "aa")] + #[default] + AvantBrowser, + #[serde(rename = "an")] + AndroidWebViewBeta, + #[serde(rename = "ch")] + GoogleChrome, + #[serde(rename = "ci")] + GoogleChromeIOS, + #[serde(rename = "cm")] + GoogleChromeMobile, + #[serde(rename = "cr")] + Chromium, + #[serde(rename = "ff")] + MozillaFirefox, + #[serde(rename = "sf")] + Safari, + #[serde(rename = "mf")] + MobileSafari, + #[serde(rename = "ps")] + MicrosoftEdge, + #[serde(rename = "oi")] + MicrosoftEdgeIOS, + #[serde(rename = "om")] + OperaMini, + #[serde(rename = "op")] + Opera, + #[serde(rename = "on")] + OperaNext, +} + +impl Browser { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Browser::AvantBrowser => "aa", + Browser::AndroidWebViewBeta => "an", + Browser::GoogleChrome => "ch", + Browser::GoogleChromeIOS => "ci", + Browser::GoogleChromeMobile => "cm", + Browser::Chromium => "cr", + Browser::MozillaFirefox => "ff", + Browser::Safari => "sf", + Browser::MobileSafari => "mf", + Browser::MicrosoftEdge => "ps", + Browser::MicrosoftEdgeIOS => "oi", + Browser::OperaMini => "om", + Browser::Opera => "op", + Browser::OperaNext => "on", + } + } +} + +impl std::fmt::Display for Browser { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/browser_permission.rs b/src/enums/browser_permission.rs new file mode 100644 index 0000000..c3b17db --- /dev/null +++ b/src/enums/browser_permission.rs @@ -0,0 +1,80 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum BrowserPermission { + #[serde(rename = "geolocation")] + #[default] + Geolocation, + #[serde(rename = "camera")] + Camera, + #[serde(rename = "microphone")] + Microphone, + #[serde(rename = "notifications")] + Notifications, + #[serde(rename = "midi")] + Midi, + #[serde(rename = "push")] + Push, + #[serde(rename = "clipboard-read")] + ClipboardRead, + #[serde(rename = "clipboard-write")] + ClipboardWrite, + #[serde(rename = "payment-handler")] + PaymentHandler, + #[serde(rename = "usb")] + Usb, + #[serde(rename = "bluetooth")] + Bluetooth, + #[serde(rename = "accelerometer")] + Accelerometer, + #[serde(rename = "gyroscope")] + Gyroscope, + #[serde(rename = "magnetometer")] + Magnetometer, + #[serde(rename = "ambient-light-sensor")] + AmbientLightSensor, + #[serde(rename = "background-sync")] + BackgroundSync, + #[serde(rename = "persistent-storage")] + PersistentStorage, + #[serde(rename = "screen-wake-lock")] + ScreenWakeLock, + #[serde(rename = "web-share")] + WebShare, + #[serde(rename = "xr-spatial-tracking")] + XrSpatialTracking, +} + +impl BrowserPermission { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + BrowserPermission::Geolocation => "geolocation", + BrowserPermission::Camera => "camera", + BrowserPermission::Microphone => "microphone", + BrowserPermission::Notifications => "notifications", + BrowserPermission::Midi => "midi", + BrowserPermission::Push => "push", + BrowserPermission::ClipboardRead => "clipboard-read", + BrowserPermission::ClipboardWrite => "clipboard-write", + BrowserPermission::PaymentHandler => "payment-handler", + BrowserPermission::Usb => "usb", + BrowserPermission::Bluetooth => "bluetooth", + BrowserPermission::Accelerometer => "accelerometer", + BrowserPermission::Gyroscope => "gyroscope", + BrowserPermission::Magnetometer => "magnetometer", + BrowserPermission::AmbientLightSensor => "ambient-light-sensor", + BrowserPermission::BackgroundSync => "background-sync", + BrowserPermission::PersistentStorage => "persistent-storage", + BrowserPermission::ScreenWakeLock => "screen-wake-lock", + BrowserPermission::WebShare => "web-share", + BrowserPermission::XrSpatialTracking => "xr-spatial-tracking", + } + } +} + +impl std::fmt::Display for BrowserPermission { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/build_runtime.rs b/src/enums/build_runtime.rs new file mode 100644 index 0000000..4114491 --- /dev/null +++ b/src/enums/build_runtime.rs @@ -0,0 +1,536 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum BuildRuntime { + #[serde(rename = "node-14.5")] + #[default] + Node145, + #[serde(rename = "node-16.0")] + Node160, + #[serde(rename = "node-18.0")] + Node180, + #[serde(rename = "node-19.0")] + Node190, + #[serde(rename = "node-20.0")] + Node200, + #[serde(rename = "node-21.0")] + Node210, + #[serde(rename = "node-22")] + Node22, + #[serde(rename = "node-23")] + Node23, + #[serde(rename = "node-24")] + Node24, + #[serde(rename = "node-25")] + Node25, + #[serde(rename = "php-8.0")] + Php80, + #[serde(rename = "php-8.1")] + Php81, + #[serde(rename = "php-8.2")] + Php82, + #[serde(rename = "php-8.3")] + Php83, + #[serde(rename = "php-8.4")] + Php84, + #[serde(rename = "ruby-3.0")] + Ruby30, + #[serde(rename = "ruby-3.1")] + Ruby31, + #[serde(rename = "ruby-3.2")] + Ruby32, + #[serde(rename = "ruby-3.3")] + Ruby33, + #[serde(rename = "ruby-3.4")] + Ruby34, + #[serde(rename = "ruby-4.0")] + Ruby40, + #[serde(rename = "python-3.8")] + Python38, + #[serde(rename = "python-3.9")] + Python39, + #[serde(rename = "python-3.10")] + Python310, + #[serde(rename = "python-3.11")] + Python311, + #[serde(rename = "python-3.12")] + Python312, + #[serde(rename = "python-3.13")] + Python313, + #[serde(rename = "python-3.14")] + Python314, + #[serde(rename = "python-ml-3.11")] + PythonMl311, + #[serde(rename = "python-ml-3.12")] + PythonMl312, + #[serde(rename = "python-ml-3.13")] + PythonMl313, + #[serde(rename = "deno-1.40")] + Deno140, + #[serde(rename = "deno-1.46")] + Deno146, + #[serde(rename = "deno-2.0")] + Deno20, + #[serde(rename = "deno-2.5")] + Deno25, + #[serde(rename = "deno-2.6")] + Deno26, + #[serde(rename = "dart-2.15")] + Dart215, + #[serde(rename = "dart-2.16")] + Dart216, + #[serde(rename = "dart-2.17")] + Dart217, + #[serde(rename = "dart-2.18")] + Dart218, + #[serde(rename = "dart-2.19")] + Dart219, + #[serde(rename = "dart-3.0")] + Dart30, + #[serde(rename = "dart-3.1")] + Dart31, + #[serde(rename = "dart-3.3")] + Dart33, + #[serde(rename = "dart-3.5")] + Dart35, + #[serde(rename = "dart-3.8")] + Dart38, + #[serde(rename = "dart-3.9")] + Dart39, + #[serde(rename = "dart-3.10")] + Dart310, + #[serde(rename = "dotnet-6.0")] + Dotnet60, + #[serde(rename = "dotnet-7.0")] + Dotnet70, + #[serde(rename = "dotnet-8.0")] + Dotnet80, + #[serde(rename = "dotnet-10")] + Dotnet10, + #[serde(rename = "java-8.0")] + Java80, + #[serde(rename = "java-11.0")] + Java110, + #[serde(rename = "java-17.0")] + Java170, + #[serde(rename = "java-18.0")] + Java180, + #[serde(rename = "java-21.0")] + Java210, + #[serde(rename = "java-22")] + Java22, + #[serde(rename = "java-25")] + Java25, + #[serde(rename = "swift-5.5")] + Swift55, + #[serde(rename = "swift-5.8")] + Swift58, + #[serde(rename = "swift-5.9")] + Swift59, + #[serde(rename = "swift-5.10")] + Swift510, + #[serde(rename = "swift-6.2")] + Swift62, + #[serde(rename = "kotlin-1.6")] + Kotlin16, + #[serde(rename = "kotlin-1.8")] + Kotlin18, + #[serde(rename = "kotlin-1.9")] + Kotlin19, + #[serde(rename = "kotlin-2.0")] + Kotlin20, + #[serde(rename = "kotlin-2.3")] + Kotlin23, + #[serde(rename = "cpp-17")] + Cpp17, + #[serde(rename = "cpp-20")] + Cpp20, + #[serde(rename = "bun-1.0")] + Bun10, + #[serde(rename = "bun-1.1")] + Bun11, + #[serde(rename = "bun-1.2")] + Bun12, + #[serde(rename = "bun-1.3")] + Bun13, + #[serde(rename = "go-1.23")] + Go123, + #[serde(rename = "go-1.24")] + Go124, + #[serde(rename = "go-1.25")] + Go125, + #[serde(rename = "go-1.26")] + Go126, + #[serde(rename = "static-1")] + Static1, + #[serde(rename = "flutter-3.24")] + Flutter324, + #[serde(rename = "flutter-3.27")] + Flutter327, + #[serde(rename = "flutter-3.29")] + Flutter329, + #[serde(rename = "flutter-3.32")] + Flutter332, + #[serde(rename = "flutter-3.35")] + Flutter335, + #[serde(rename = "flutter-3.38")] + Flutter338, + #[serde(rename = "node-14.5-rc")] + Node145Rc, + #[serde(rename = "node-16.0-rc")] + Node160Rc, + #[serde(rename = "node-18.0-rc")] + Node180Rc, + #[serde(rename = "node-19.0-rc")] + Node190Rc, + #[serde(rename = "node-20.0-rc")] + Node200Rc, + #[serde(rename = "node-21.0-rc")] + Node210Rc, + #[serde(rename = "node-22-rc")] + Node22Rc, + #[serde(rename = "node-23-rc")] + Node23Rc, + #[serde(rename = "node-24-rc")] + Node24Rc, + #[serde(rename = "node-25-rc")] + Node25Rc, + #[serde(rename = "php-8.0-rc")] + Php80Rc, + #[serde(rename = "php-8.1-rc")] + Php81Rc, + #[serde(rename = "php-8.2-rc")] + Php82Rc, + #[serde(rename = "php-8.3-rc")] + Php83Rc, + #[serde(rename = "php-8.4-rc")] + Php84Rc, + #[serde(rename = "ruby-3.0-rc")] + Ruby30Rc, + #[serde(rename = "ruby-3.1-rc")] + Ruby31Rc, + #[serde(rename = "ruby-3.2-rc")] + Ruby32Rc, + #[serde(rename = "ruby-3.3-rc")] + Ruby33Rc, + #[serde(rename = "ruby-3.4-rc")] + Ruby34Rc, + #[serde(rename = "ruby-4.0-rc")] + Ruby40Rc, + #[serde(rename = "python-3.8-rc")] + Python38Rc, + #[serde(rename = "python-3.9-rc")] + Python39Rc, + #[serde(rename = "python-3.10-rc")] + Python310Rc, + #[serde(rename = "python-3.11-rc")] + Python311Rc, + #[serde(rename = "python-3.12-rc")] + Python312Rc, + #[serde(rename = "python-3.13-rc")] + Python313Rc, + #[serde(rename = "python-3.14-rc")] + Python314Rc, + #[serde(rename = "python-ml-3.11-rc")] + PythonMl311Rc, + #[serde(rename = "python-ml-3.12-rc")] + PythonMl312Rc, + #[serde(rename = "python-ml-3.13-rc")] + PythonMl313Rc, + #[serde(rename = "deno-1.40-rc")] + Deno140Rc, + #[serde(rename = "deno-1.46-rc")] + Deno146Rc, + #[serde(rename = "deno-2.0-rc")] + Deno20Rc, + #[serde(rename = "deno-2.5-rc")] + Deno25Rc, + #[serde(rename = "deno-2.6-rc")] + Deno26Rc, + #[serde(rename = "dart-2.15-rc")] + Dart215Rc, + #[serde(rename = "dart-2.16-rc")] + Dart216Rc, + #[serde(rename = "dart-2.17-rc")] + Dart217Rc, + #[serde(rename = "dart-2.18-rc")] + Dart218Rc, + #[serde(rename = "dart-2.19-rc")] + Dart219Rc, + #[serde(rename = "dart-3.0-rc")] + Dart30Rc, + #[serde(rename = "dart-3.1-rc")] + Dart31Rc, + #[serde(rename = "dart-3.3-rc")] + Dart33Rc, + #[serde(rename = "dart-3.5-rc")] + Dart35Rc, + #[serde(rename = "dart-3.8-rc")] + Dart38Rc, + #[serde(rename = "dart-3.9-rc")] + Dart39Rc, + #[serde(rename = "dart-3.10-rc")] + Dart310Rc, + #[serde(rename = "dotnet-6.0-rc")] + Dotnet60Rc, + #[serde(rename = "dotnet-7.0-rc")] + Dotnet70Rc, + #[serde(rename = "dotnet-8.0-rc")] + Dotnet80Rc, + #[serde(rename = "dotnet-10-rc")] + Dotnet10Rc, + #[serde(rename = "java-8.0-rc")] + Java80Rc, + #[serde(rename = "java-11.0-rc")] + Java110Rc, + #[serde(rename = "java-17.0-rc")] + Java170Rc, + #[serde(rename = "java-18.0-rc")] + Java180Rc, + #[serde(rename = "java-21.0-rc")] + Java210Rc, + #[serde(rename = "java-22-rc")] + Java22Rc, + #[serde(rename = "java-25-rc")] + Java25Rc, + #[serde(rename = "swift-5.5-rc")] + Swift55Rc, + #[serde(rename = "swift-5.8-rc")] + Swift58Rc, + #[serde(rename = "swift-5.9-rc")] + Swift59Rc, + #[serde(rename = "swift-5.10-rc")] + Swift510Rc, + #[serde(rename = "swift-6.2-rc")] + Swift62Rc, + #[serde(rename = "kotlin-1.6-rc")] + Kotlin16Rc, + #[serde(rename = "kotlin-1.8-rc")] + Kotlin18Rc, + #[serde(rename = "kotlin-1.9-rc")] + Kotlin19Rc, + #[serde(rename = "kotlin-2.0-rc")] + Kotlin20Rc, + #[serde(rename = "kotlin-2.3-rc")] + Kotlin23Rc, + #[serde(rename = "cpp-17-rc")] + Cpp17Rc, + #[serde(rename = "cpp-20-rc")] + Cpp20Rc, + #[serde(rename = "bun-1.0-rc")] + Bun10Rc, + #[serde(rename = "bun-1.1-rc")] + Bun11Rc, + #[serde(rename = "bun-1.2-rc")] + Bun12Rc, + #[serde(rename = "bun-1.3-rc")] + Bun13Rc, + #[serde(rename = "go-1.23-rc")] + Go123Rc, + #[serde(rename = "go-1.24-rc")] + Go124Rc, + #[serde(rename = "go-1.25-rc")] + Go125Rc, + #[serde(rename = "go-1.26-rc")] + Go126Rc, + #[serde(rename = "static-1-rc")] + Static1Rc, + #[serde(rename = "flutter-3.24-rc")] + Flutter324Rc, + #[serde(rename = "flutter-3.27-rc")] + Flutter327Rc, + #[serde(rename = "flutter-3.29-rc")] + Flutter329Rc, + #[serde(rename = "flutter-3.32-rc")] + Flutter332Rc, + #[serde(rename = "flutter-3.35-rc")] + Flutter335Rc, + #[serde(rename = "flutter-3.38-rc")] + Flutter338Rc, +} + +impl BuildRuntime { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + BuildRuntime::Node145 => "node-14.5", + BuildRuntime::Node160 => "node-16.0", + BuildRuntime::Node180 => "node-18.0", + BuildRuntime::Node190 => "node-19.0", + BuildRuntime::Node200 => "node-20.0", + BuildRuntime::Node210 => "node-21.0", + BuildRuntime::Node22 => "node-22", + BuildRuntime::Node23 => "node-23", + BuildRuntime::Node24 => "node-24", + BuildRuntime::Node25 => "node-25", + BuildRuntime::Php80 => "php-8.0", + BuildRuntime::Php81 => "php-8.1", + BuildRuntime::Php82 => "php-8.2", + BuildRuntime::Php83 => "php-8.3", + BuildRuntime::Php84 => "php-8.4", + BuildRuntime::Ruby30 => "ruby-3.0", + BuildRuntime::Ruby31 => "ruby-3.1", + BuildRuntime::Ruby32 => "ruby-3.2", + BuildRuntime::Ruby33 => "ruby-3.3", + BuildRuntime::Ruby34 => "ruby-3.4", + BuildRuntime::Ruby40 => "ruby-4.0", + BuildRuntime::Python38 => "python-3.8", + BuildRuntime::Python39 => "python-3.9", + BuildRuntime::Python310 => "python-3.10", + BuildRuntime::Python311 => "python-3.11", + BuildRuntime::Python312 => "python-3.12", + BuildRuntime::Python313 => "python-3.13", + BuildRuntime::Python314 => "python-3.14", + BuildRuntime::PythonMl311 => "python-ml-3.11", + BuildRuntime::PythonMl312 => "python-ml-3.12", + BuildRuntime::PythonMl313 => "python-ml-3.13", + BuildRuntime::Deno140 => "deno-1.40", + BuildRuntime::Deno146 => "deno-1.46", + BuildRuntime::Deno20 => "deno-2.0", + BuildRuntime::Deno25 => "deno-2.5", + BuildRuntime::Deno26 => "deno-2.6", + BuildRuntime::Dart215 => "dart-2.15", + BuildRuntime::Dart216 => "dart-2.16", + BuildRuntime::Dart217 => "dart-2.17", + BuildRuntime::Dart218 => "dart-2.18", + BuildRuntime::Dart219 => "dart-2.19", + BuildRuntime::Dart30 => "dart-3.0", + BuildRuntime::Dart31 => "dart-3.1", + BuildRuntime::Dart33 => "dart-3.3", + BuildRuntime::Dart35 => "dart-3.5", + BuildRuntime::Dart38 => "dart-3.8", + BuildRuntime::Dart39 => "dart-3.9", + BuildRuntime::Dart310 => "dart-3.10", + BuildRuntime::Dotnet60 => "dotnet-6.0", + BuildRuntime::Dotnet70 => "dotnet-7.0", + BuildRuntime::Dotnet80 => "dotnet-8.0", + BuildRuntime::Dotnet10 => "dotnet-10", + BuildRuntime::Java80 => "java-8.0", + BuildRuntime::Java110 => "java-11.0", + BuildRuntime::Java170 => "java-17.0", + BuildRuntime::Java180 => "java-18.0", + BuildRuntime::Java210 => "java-21.0", + BuildRuntime::Java22 => "java-22", + BuildRuntime::Java25 => "java-25", + BuildRuntime::Swift55 => "swift-5.5", + BuildRuntime::Swift58 => "swift-5.8", + BuildRuntime::Swift59 => "swift-5.9", + BuildRuntime::Swift510 => "swift-5.10", + BuildRuntime::Swift62 => "swift-6.2", + BuildRuntime::Kotlin16 => "kotlin-1.6", + BuildRuntime::Kotlin18 => "kotlin-1.8", + BuildRuntime::Kotlin19 => "kotlin-1.9", + BuildRuntime::Kotlin20 => "kotlin-2.0", + BuildRuntime::Kotlin23 => "kotlin-2.3", + BuildRuntime::Cpp17 => "cpp-17", + BuildRuntime::Cpp20 => "cpp-20", + BuildRuntime::Bun10 => "bun-1.0", + BuildRuntime::Bun11 => "bun-1.1", + BuildRuntime::Bun12 => "bun-1.2", + BuildRuntime::Bun13 => "bun-1.3", + BuildRuntime::Go123 => "go-1.23", + BuildRuntime::Go124 => "go-1.24", + BuildRuntime::Go125 => "go-1.25", + BuildRuntime::Go126 => "go-1.26", + BuildRuntime::Static1 => "static-1", + BuildRuntime::Flutter324 => "flutter-3.24", + BuildRuntime::Flutter327 => "flutter-3.27", + BuildRuntime::Flutter329 => "flutter-3.29", + BuildRuntime::Flutter332 => "flutter-3.32", + BuildRuntime::Flutter335 => "flutter-3.35", + BuildRuntime::Flutter338 => "flutter-3.38", + BuildRuntime::Node145Rc => "node-14.5-rc", + BuildRuntime::Node160Rc => "node-16.0-rc", + BuildRuntime::Node180Rc => "node-18.0-rc", + BuildRuntime::Node190Rc => "node-19.0-rc", + BuildRuntime::Node200Rc => "node-20.0-rc", + BuildRuntime::Node210Rc => "node-21.0-rc", + BuildRuntime::Node22Rc => "node-22-rc", + BuildRuntime::Node23Rc => "node-23-rc", + BuildRuntime::Node24Rc => "node-24-rc", + BuildRuntime::Node25Rc => "node-25-rc", + BuildRuntime::Php80Rc => "php-8.0-rc", + BuildRuntime::Php81Rc => "php-8.1-rc", + BuildRuntime::Php82Rc => "php-8.2-rc", + BuildRuntime::Php83Rc => "php-8.3-rc", + BuildRuntime::Php84Rc => "php-8.4-rc", + BuildRuntime::Ruby30Rc => "ruby-3.0-rc", + BuildRuntime::Ruby31Rc => "ruby-3.1-rc", + BuildRuntime::Ruby32Rc => "ruby-3.2-rc", + BuildRuntime::Ruby33Rc => "ruby-3.3-rc", + BuildRuntime::Ruby34Rc => "ruby-3.4-rc", + BuildRuntime::Ruby40Rc => "ruby-4.0-rc", + BuildRuntime::Python38Rc => "python-3.8-rc", + BuildRuntime::Python39Rc => "python-3.9-rc", + BuildRuntime::Python310Rc => "python-3.10-rc", + BuildRuntime::Python311Rc => "python-3.11-rc", + BuildRuntime::Python312Rc => "python-3.12-rc", + BuildRuntime::Python313Rc => "python-3.13-rc", + BuildRuntime::Python314Rc => "python-3.14-rc", + BuildRuntime::PythonMl311Rc => "python-ml-3.11-rc", + BuildRuntime::PythonMl312Rc => "python-ml-3.12-rc", + BuildRuntime::PythonMl313Rc => "python-ml-3.13-rc", + BuildRuntime::Deno140Rc => "deno-1.40-rc", + BuildRuntime::Deno146Rc => "deno-1.46-rc", + BuildRuntime::Deno20Rc => "deno-2.0-rc", + BuildRuntime::Deno25Rc => "deno-2.5-rc", + BuildRuntime::Deno26Rc => "deno-2.6-rc", + BuildRuntime::Dart215Rc => "dart-2.15-rc", + BuildRuntime::Dart216Rc => "dart-2.16-rc", + BuildRuntime::Dart217Rc => "dart-2.17-rc", + BuildRuntime::Dart218Rc => "dart-2.18-rc", + BuildRuntime::Dart219Rc => "dart-2.19-rc", + BuildRuntime::Dart30Rc => "dart-3.0-rc", + BuildRuntime::Dart31Rc => "dart-3.1-rc", + BuildRuntime::Dart33Rc => "dart-3.3-rc", + BuildRuntime::Dart35Rc => "dart-3.5-rc", + BuildRuntime::Dart38Rc => "dart-3.8-rc", + BuildRuntime::Dart39Rc => "dart-3.9-rc", + BuildRuntime::Dart310Rc => "dart-3.10-rc", + BuildRuntime::Dotnet60Rc => "dotnet-6.0-rc", + BuildRuntime::Dotnet70Rc => "dotnet-7.0-rc", + BuildRuntime::Dotnet80Rc => "dotnet-8.0-rc", + BuildRuntime::Dotnet10Rc => "dotnet-10-rc", + BuildRuntime::Java80Rc => "java-8.0-rc", + BuildRuntime::Java110Rc => "java-11.0-rc", + BuildRuntime::Java170Rc => "java-17.0-rc", + BuildRuntime::Java180Rc => "java-18.0-rc", + BuildRuntime::Java210Rc => "java-21.0-rc", + BuildRuntime::Java22Rc => "java-22-rc", + BuildRuntime::Java25Rc => "java-25-rc", + BuildRuntime::Swift55Rc => "swift-5.5-rc", + BuildRuntime::Swift58Rc => "swift-5.8-rc", + BuildRuntime::Swift59Rc => "swift-5.9-rc", + BuildRuntime::Swift510Rc => "swift-5.10-rc", + BuildRuntime::Swift62Rc => "swift-6.2-rc", + BuildRuntime::Kotlin16Rc => "kotlin-1.6-rc", + BuildRuntime::Kotlin18Rc => "kotlin-1.8-rc", + BuildRuntime::Kotlin19Rc => "kotlin-1.9-rc", + BuildRuntime::Kotlin20Rc => "kotlin-2.0-rc", + BuildRuntime::Kotlin23Rc => "kotlin-2.3-rc", + BuildRuntime::Cpp17Rc => "cpp-17-rc", + BuildRuntime::Cpp20Rc => "cpp-20-rc", + BuildRuntime::Bun10Rc => "bun-1.0-rc", + BuildRuntime::Bun11Rc => "bun-1.1-rc", + BuildRuntime::Bun12Rc => "bun-1.2-rc", + BuildRuntime::Bun13Rc => "bun-1.3-rc", + BuildRuntime::Go123Rc => "go-1.23-rc", + BuildRuntime::Go124Rc => "go-1.24-rc", + BuildRuntime::Go125Rc => "go-1.25-rc", + BuildRuntime::Go126Rc => "go-1.26-rc", + BuildRuntime::Static1Rc => "static-1-rc", + BuildRuntime::Flutter324Rc => "flutter-3.24-rc", + BuildRuntime::Flutter327Rc => "flutter-3.27-rc", + BuildRuntime::Flutter329Rc => "flutter-3.29-rc", + BuildRuntime::Flutter332Rc => "flutter-3.32-rc", + BuildRuntime::Flutter335Rc => "flutter-3.35-rc", + BuildRuntime::Flutter338Rc => "flutter-3.38-rc", + } + } +} + +impl std::fmt::Display for BuildRuntime { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/column_status.rs b/src/enums/column_status.rs new file mode 100644 index 0000000..40f72f7 --- /dev/null +++ b/src/enums/column_status.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum ColumnStatus { + #[serde(rename = "available")] + #[default] + Available, + #[serde(rename = "processing")] + Processing, + #[serde(rename = "deleting")] + Deleting, + #[serde(rename = "stuck")] + Stuck, + #[serde(rename = "failed")] + Failed, +} + +impl ColumnStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + ColumnStatus::Available => "available", + ColumnStatus::Processing => "processing", + ColumnStatus::Deleting => "deleting", + ColumnStatus::Stuck => "stuck", + ColumnStatus::Failed => "failed", + } + } +} + +impl std::fmt::Display for ColumnStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/compression.rs b/src/enums/compression.rs new file mode 100644 index 0000000..d253fe3 --- /dev/null +++ b/src/enums/compression.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Compression { + #[serde(rename = "none")] + #[default] + None, + #[serde(rename = "gzip")] + Gzip, + #[serde(rename = "zstd")] + Zstd, +} + +impl Compression { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Compression::None => "none", + Compression::Gzip => "gzip", + Compression::Zstd => "zstd", + } + } +} + +impl std::fmt::Display for Compression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/credit_card.rs b/src/enums/credit_card.rs new file mode 100644 index 0000000..883a871 --- /dev/null +++ b/src/enums/credit_card.rs @@ -0,0 +1,71 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum CreditCard { + #[serde(rename = "amex")] + #[default] + AmericanExpress, + #[serde(rename = "argencard")] + Argencard, + #[serde(rename = "cabal")] + Cabal, + #[serde(rename = "cencosud")] + Cencosud, + #[serde(rename = "diners")] + DinersClub, + #[serde(rename = "discover")] + Discover, + #[serde(rename = "elo")] + Elo, + #[serde(rename = "hipercard")] + Hipercard, + #[serde(rename = "jcb")] + JCB, + #[serde(rename = "mastercard")] + Mastercard, + #[serde(rename = "naranja")] + Naranja, + #[serde(rename = "targeta-shopping")] + TarjetaShopping, + #[serde(rename = "unionpay")] + UnionPay, + #[serde(rename = "visa")] + Visa, + #[serde(rename = "mir")] + MIR, + #[serde(rename = "maestro")] + Maestro, + #[serde(rename = "rupay")] + Rupay, +} + +impl CreditCard { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + CreditCard::AmericanExpress => "amex", + CreditCard::Argencard => "argencard", + CreditCard::Cabal => "cabal", + CreditCard::Cencosud => "cencosud", + CreditCard::DinersClub => "diners", + CreditCard::Discover => "discover", + CreditCard::Elo => "elo", + CreditCard::Hipercard => "hipercard", + CreditCard::JCB => "jcb", + CreditCard::Mastercard => "mastercard", + CreditCard::Naranja => "naranja", + CreditCard::TarjetaShopping => "targeta-shopping", + CreditCard::UnionPay => "unionpay", + CreditCard::Visa => "visa", + CreditCard::MIR => "mir", + CreditCard::Maestro => "maestro", + CreditCard::Rupay => "rupay", + } + } +} + +impl std::fmt::Display for CreditCard { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/database_type.rs b/src/enums/database_type.rs new file mode 100644 index 0000000..80e5962 --- /dev/null +++ b/src/enums/database_type.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum DatabaseType { + #[serde(rename = "legacy")] + #[default] + Legacy, + #[serde(rename = "tablesdb")] + Tablesdb, +} + +impl DatabaseType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + DatabaseType::Legacy => "legacy", + DatabaseType::Tablesdb => "tablesdb", + } + } +} + +impl std::fmt::Display for DatabaseType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/deployment_download_type.rs b/src/enums/deployment_download_type.rs new file mode 100644 index 0000000..f1e40da --- /dev/null +++ b/src/enums/deployment_download_type.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum DeploymentDownloadType { + #[serde(rename = "source")] + #[default] + Source, + #[serde(rename = "output")] + Output, +} + +impl DeploymentDownloadType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + DeploymentDownloadType::Source => "source", + DeploymentDownloadType::Output => "output", + } + } +} + +impl std::fmt::Display for DeploymentDownloadType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/deployment_status.rs b/src/enums/deployment_status.rs new file mode 100644 index 0000000..04b20f9 --- /dev/null +++ b/src/enums/deployment_status.rs @@ -0,0 +1,38 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum DeploymentStatus { + #[serde(rename = "waiting")] + #[default] + Waiting, + #[serde(rename = "processing")] + Processing, + #[serde(rename = "building")] + Building, + #[serde(rename = "ready")] + Ready, + #[serde(rename = "canceled")] + Canceled, + #[serde(rename = "failed")] + Failed, +} + +impl DeploymentStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + DeploymentStatus::Waiting => "waiting", + DeploymentStatus::Processing => "processing", + DeploymentStatus::Building => "building", + DeploymentStatus::Ready => "ready", + DeploymentStatus::Canceled => "canceled", + DeploymentStatus::Failed => "failed", + } + } +} + +impl std::fmt::Display for DeploymentStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/execution_method.rs b/src/enums/execution_method.rs new file mode 100644 index 0000000..6764169 --- /dev/null +++ b/src/enums/execution_method.rs @@ -0,0 +1,41 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum ExecutionMethod { + #[serde(rename = "GET")] + #[default] + GET, + #[serde(rename = "POST")] + POST, + #[serde(rename = "PUT")] + PUT, + #[serde(rename = "PATCH")] + PATCH, + #[serde(rename = "DELETE")] + DELETE, + #[serde(rename = "OPTIONS")] + OPTIONS, + #[serde(rename = "HEAD")] + HEAD, +} + +impl ExecutionMethod { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + ExecutionMethod::GET => "GET", + ExecutionMethod::POST => "POST", + ExecutionMethod::PUT => "PUT", + ExecutionMethod::PATCH => "PATCH", + ExecutionMethod::DELETE => "DELETE", + ExecutionMethod::OPTIONS => "OPTIONS", + ExecutionMethod::HEAD => "HEAD", + } + } +} + +impl std::fmt::Display for ExecutionMethod { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/execution_status.rs b/src/enums/execution_status.rs new file mode 100644 index 0000000..bff8007 --- /dev/null +++ b/src/enums/execution_status.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum ExecutionStatus { + #[serde(rename = "waiting")] + #[default] + Waiting, + #[serde(rename = "processing")] + Processing, + #[serde(rename = "completed")] + Completed, + #[serde(rename = "failed")] + Failed, + #[serde(rename = "scheduled")] + Scheduled, +} + +impl ExecutionStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + ExecutionStatus::Waiting => "waiting", + ExecutionStatus::Processing => "processing", + ExecutionStatus::Completed => "completed", + ExecutionStatus::Failed => "failed", + ExecutionStatus::Scheduled => "scheduled", + } + } +} + +impl std::fmt::Display for ExecutionStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/execution_trigger.rs b/src/enums/execution_trigger.rs new file mode 100644 index 0000000..46fb2cd --- /dev/null +++ b/src/enums/execution_trigger.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum ExecutionTrigger { + #[serde(rename = "http")] + #[default] + Http, + #[serde(rename = "schedule")] + Schedule, + #[serde(rename = "event")] + Event, +} + +impl ExecutionTrigger { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + ExecutionTrigger::Http => "http", + ExecutionTrigger::Schedule => "schedule", + ExecutionTrigger::Event => "event", + } + } +} + +impl std::fmt::Display for ExecutionTrigger { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/flag.rs b/src/enums/flag.rs new file mode 100644 index 0000000..f4af3e1 --- /dev/null +++ b/src/enums/flag.rs @@ -0,0 +1,605 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Flag { + #[serde(rename = "af")] + #[default] + Afghanistan, + #[serde(rename = "ao")] + Angola, + #[serde(rename = "al")] + Albania, + #[serde(rename = "ad")] + Andorra, + #[serde(rename = "ae")] + UnitedArabEmirates, + #[serde(rename = "ar")] + Argentina, + #[serde(rename = "am")] + Armenia, + #[serde(rename = "ag")] + AntiguaAndBarbuda, + #[serde(rename = "au")] + Australia, + #[serde(rename = "at")] + Austria, + #[serde(rename = "az")] + Azerbaijan, + #[serde(rename = "bi")] + Burundi, + #[serde(rename = "be")] + Belgium, + #[serde(rename = "bj")] + Benin, + #[serde(rename = "bf")] + BurkinaFaso, + #[serde(rename = "bd")] + Bangladesh, + #[serde(rename = "bg")] + Bulgaria, + #[serde(rename = "bh")] + Bahrain, + #[serde(rename = "bs")] + Bahamas, + #[serde(rename = "ba")] + BosniaAndHerzegovina, + #[serde(rename = "by")] + Belarus, + #[serde(rename = "bz")] + Belize, + #[serde(rename = "bo")] + Bolivia, + #[serde(rename = "br")] + Brazil, + #[serde(rename = "bb")] + Barbados, + #[serde(rename = "bn")] + BruneiDarussalam, + #[serde(rename = "bt")] + Bhutan, + #[serde(rename = "bw")] + Botswana, + #[serde(rename = "cf")] + CentralAfricanRepublic, + #[serde(rename = "ca")] + Canada, + #[serde(rename = "ch")] + Switzerland, + #[serde(rename = "cl")] + Chile, + #[serde(rename = "cn")] + China, + #[serde(rename = "ci")] + CoteDIvoire, + #[serde(rename = "cm")] + Cameroon, + #[serde(rename = "cd")] + DemocraticRepublicOfTheCongo, + #[serde(rename = "cg")] + RepublicOfTheCongo, + #[serde(rename = "co")] + Colombia, + #[serde(rename = "km")] + Comoros, + #[serde(rename = "cv")] + CapeVerde, + #[serde(rename = "cr")] + CostaRica, + #[serde(rename = "cu")] + Cuba, + #[serde(rename = "cy")] + Cyprus, + #[serde(rename = "cz")] + CzechRepublic, + #[serde(rename = "de")] + Germany, + #[serde(rename = "dj")] + Djibouti, + #[serde(rename = "dm")] + Dominica, + #[serde(rename = "dk")] + Denmark, + #[serde(rename = "do")] + DominicanRepublic, + #[serde(rename = "dz")] + Algeria, + #[serde(rename = "ec")] + Ecuador, + #[serde(rename = "eg")] + Egypt, + #[serde(rename = "er")] + Eritrea, + #[serde(rename = "es")] + Spain, + #[serde(rename = "ee")] + Estonia, + #[serde(rename = "et")] + Ethiopia, + #[serde(rename = "fi")] + Finland, + #[serde(rename = "fj")] + Fiji, + #[serde(rename = "fr")] + France, + #[serde(rename = "fm")] + MicronesiaFederatedStatesOf, + #[serde(rename = "ga")] + Gabon, + #[serde(rename = "gb")] + UnitedKingdom, + #[serde(rename = "ge")] + Georgia, + #[serde(rename = "gh")] + Ghana, + #[serde(rename = "gn")] + Guinea, + #[serde(rename = "gm")] + Gambia, + #[serde(rename = "gw")] + GuineaBissau, + #[serde(rename = "gq")] + EquatorialGuinea, + #[serde(rename = "gr")] + Greece, + #[serde(rename = "gd")] + Grenada, + #[serde(rename = "gt")] + Guatemala, + #[serde(rename = "gy")] + Guyana, + #[serde(rename = "hn")] + Honduras, + #[serde(rename = "hr")] + Croatia, + #[serde(rename = "ht")] + Haiti, + #[serde(rename = "hu")] + Hungary, + #[serde(rename = "id")] + Indonesia, + #[serde(rename = "in")] + India, + #[serde(rename = "ie")] + Ireland, + #[serde(rename = "ir")] + IranIslamicRepublicOf, + #[serde(rename = "iq")] + Iraq, + #[serde(rename = "is")] + Iceland, + #[serde(rename = "il")] + Israel, + #[serde(rename = "it")] + Italy, + #[serde(rename = "jm")] + Jamaica, + #[serde(rename = "jo")] + Jordan, + #[serde(rename = "jp")] + Japan, + #[serde(rename = "kz")] + Kazakhstan, + #[serde(rename = "ke")] + Kenya, + #[serde(rename = "kg")] + Kyrgyzstan, + #[serde(rename = "kh")] + Cambodia, + #[serde(rename = "ki")] + Kiribati, + #[serde(rename = "kn")] + SaintKittsAndNevis, + #[serde(rename = "kr")] + SouthKorea, + #[serde(rename = "kw")] + Kuwait, + #[serde(rename = "la")] + LaoPeopleSDemocraticRepublic, + #[serde(rename = "lb")] + Lebanon, + #[serde(rename = "lr")] + Liberia, + #[serde(rename = "ly")] + Libya, + #[serde(rename = "lc")] + SaintLucia, + #[serde(rename = "li")] + Liechtenstein, + #[serde(rename = "lk")] + SriLanka, + #[serde(rename = "ls")] + Lesotho, + #[serde(rename = "lt")] + Lithuania, + #[serde(rename = "lu")] + Luxembourg, + #[serde(rename = "lv")] + Latvia, + #[serde(rename = "ma")] + Morocco, + #[serde(rename = "mc")] + Monaco, + #[serde(rename = "md")] + Moldova, + #[serde(rename = "mg")] + Madagascar, + #[serde(rename = "mv")] + Maldives, + #[serde(rename = "mx")] + Mexico, + #[serde(rename = "mh")] + MarshallIslands, + #[serde(rename = "mk")] + NorthMacedonia, + #[serde(rename = "ml")] + Mali, + #[serde(rename = "mt")] + Malta, + #[serde(rename = "mm")] + Myanmar, + #[serde(rename = "me")] + Montenegro, + #[serde(rename = "mn")] + Mongolia, + #[serde(rename = "mz")] + Mozambique, + #[serde(rename = "mr")] + Mauritania, + #[serde(rename = "mu")] + Mauritius, + #[serde(rename = "mw")] + Malawi, + #[serde(rename = "my")] + Malaysia, + #[serde(rename = "na")] + Namibia, + #[serde(rename = "ne")] + Niger, + #[serde(rename = "ng")] + Nigeria, + #[serde(rename = "ni")] + Nicaragua, + #[serde(rename = "nl")] + Netherlands, + #[serde(rename = "no")] + Norway, + #[serde(rename = "np")] + Nepal, + #[serde(rename = "nr")] + Nauru, + #[serde(rename = "nz")] + NewZealand, + #[serde(rename = "om")] + Oman, + #[serde(rename = "pk")] + Pakistan, + #[serde(rename = "pa")] + Panama, + #[serde(rename = "pe")] + Peru, + #[serde(rename = "ph")] + Philippines, + #[serde(rename = "pw")] + Palau, + #[serde(rename = "pg")] + PapuaNewGuinea, + #[serde(rename = "pl")] + Poland, + #[serde(rename = "pf")] + FrenchPolynesia, + #[serde(rename = "kp")] + NorthKorea, + #[serde(rename = "pt")] + Portugal, + #[serde(rename = "py")] + Paraguay, + #[serde(rename = "qa")] + Qatar, + #[serde(rename = "ro")] + Romania, + #[serde(rename = "ru")] + Russia, + #[serde(rename = "rw")] + Rwanda, + #[serde(rename = "sa")] + SaudiArabia, + #[serde(rename = "sd")] + Sudan, + #[serde(rename = "sn")] + Senegal, + #[serde(rename = "sg")] + Singapore, + #[serde(rename = "sb")] + SolomonIslands, + #[serde(rename = "sl")] + SierraLeone, + #[serde(rename = "sv")] + ElSalvador, + #[serde(rename = "sm")] + SanMarino, + #[serde(rename = "so")] + Somalia, + #[serde(rename = "rs")] + Serbia, + #[serde(rename = "ss")] + SouthSudan, + #[serde(rename = "st")] + SaoTomeAndPrincipe, + #[serde(rename = "sr")] + Suriname, + #[serde(rename = "sk")] + Slovakia, + #[serde(rename = "si")] + Slovenia, + #[serde(rename = "se")] + Sweden, + #[serde(rename = "sz")] + Eswatini, + #[serde(rename = "sc")] + Seychelles, + #[serde(rename = "sy")] + Syria, + #[serde(rename = "td")] + Chad, + #[serde(rename = "tg")] + Togo, + #[serde(rename = "th")] + Thailand, + #[serde(rename = "tj")] + Tajikistan, + #[serde(rename = "tm")] + Turkmenistan, + #[serde(rename = "tl")] + TimorLeste, + #[serde(rename = "to")] + Tonga, + #[serde(rename = "tt")] + TrinidadAndTobago, + #[serde(rename = "tn")] + Tunisia, + #[serde(rename = "tr")] + Turkey, + #[serde(rename = "tv")] + Tuvalu, + #[serde(rename = "tz")] + Tanzania, + #[serde(rename = "ug")] + Uganda, + #[serde(rename = "ua")] + Ukraine, + #[serde(rename = "uy")] + Uruguay, + #[serde(rename = "us")] + UnitedStates, + #[serde(rename = "uz")] + Uzbekistan, + #[serde(rename = "va")] + VaticanCity, + #[serde(rename = "vc")] + SaintVincentAndTheGrenadines, + #[serde(rename = "ve")] + Venezuela, + #[serde(rename = "vn")] + Vietnam, + #[serde(rename = "vu")] + Vanuatu, + #[serde(rename = "ws")] + Samoa, + #[serde(rename = "ye")] + Yemen, + #[serde(rename = "za")] + SouthAfrica, + #[serde(rename = "zm")] + Zambia, + #[serde(rename = "zw")] + Zimbabwe, +} + +impl Flag { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Flag::Afghanistan => "af", + Flag::Angola => "ao", + Flag::Albania => "al", + Flag::Andorra => "ad", + Flag::UnitedArabEmirates => "ae", + Flag::Argentina => "ar", + Flag::Armenia => "am", + Flag::AntiguaAndBarbuda => "ag", + Flag::Australia => "au", + Flag::Austria => "at", + Flag::Azerbaijan => "az", + Flag::Burundi => "bi", + Flag::Belgium => "be", + Flag::Benin => "bj", + Flag::BurkinaFaso => "bf", + Flag::Bangladesh => "bd", + Flag::Bulgaria => "bg", + Flag::Bahrain => "bh", + Flag::Bahamas => "bs", + Flag::BosniaAndHerzegovina => "ba", + Flag::Belarus => "by", + Flag::Belize => "bz", + Flag::Bolivia => "bo", + Flag::Brazil => "br", + Flag::Barbados => "bb", + Flag::BruneiDarussalam => "bn", + Flag::Bhutan => "bt", + Flag::Botswana => "bw", + Flag::CentralAfricanRepublic => "cf", + Flag::Canada => "ca", + Flag::Switzerland => "ch", + Flag::Chile => "cl", + Flag::China => "cn", + Flag::CoteDIvoire => "ci", + Flag::Cameroon => "cm", + Flag::DemocraticRepublicOfTheCongo => "cd", + Flag::RepublicOfTheCongo => "cg", + Flag::Colombia => "co", + Flag::Comoros => "km", + Flag::CapeVerde => "cv", + Flag::CostaRica => "cr", + Flag::Cuba => "cu", + Flag::Cyprus => "cy", + Flag::CzechRepublic => "cz", + Flag::Germany => "de", + Flag::Djibouti => "dj", + Flag::Dominica => "dm", + Flag::Denmark => "dk", + Flag::DominicanRepublic => "do", + Flag::Algeria => "dz", + Flag::Ecuador => "ec", + Flag::Egypt => "eg", + Flag::Eritrea => "er", + Flag::Spain => "es", + Flag::Estonia => "ee", + Flag::Ethiopia => "et", + Flag::Finland => "fi", + Flag::Fiji => "fj", + Flag::France => "fr", + Flag::MicronesiaFederatedStatesOf => "fm", + Flag::Gabon => "ga", + Flag::UnitedKingdom => "gb", + Flag::Georgia => "ge", + Flag::Ghana => "gh", + Flag::Guinea => "gn", + Flag::Gambia => "gm", + Flag::GuineaBissau => "gw", + Flag::EquatorialGuinea => "gq", + Flag::Greece => "gr", + Flag::Grenada => "gd", + Flag::Guatemala => "gt", + Flag::Guyana => "gy", + Flag::Honduras => "hn", + Flag::Croatia => "hr", + Flag::Haiti => "ht", + Flag::Hungary => "hu", + Flag::Indonesia => "id", + Flag::India => "in", + Flag::Ireland => "ie", + Flag::IranIslamicRepublicOf => "ir", + Flag::Iraq => "iq", + Flag::Iceland => "is", + Flag::Israel => "il", + Flag::Italy => "it", + Flag::Jamaica => "jm", + Flag::Jordan => "jo", + Flag::Japan => "jp", + Flag::Kazakhstan => "kz", + Flag::Kenya => "ke", + Flag::Kyrgyzstan => "kg", + Flag::Cambodia => "kh", + Flag::Kiribati => "ki", + Flag::SaintKittsAndNevis => "kn", + Flag::SouthKorea => "kr", + Flag::Kuwait => "kw", + Flag::LaoPeopleSDemocraticRepublic => "la", + Flag::Lebanon => "lb", + Flag::Liberia => "lr", + Flag::Libya => "ly", + Flag::SaintLucia => "lc", + Flag::Liechtenstein => "li", + Flag::SriLanka => "lk", + Flag::Lesotho => "ls", + Flag::Lithuania => "lt", + Flag::Luxembourg => "lu", + Flag::Latvia => "lv", + Flag::Morocco => "ma", + Flag::Monaco => "mc", + Flag::Moldova => "md", + Flag::Madagascar => "mg", + Flag::Maldives => "mv", + Flag::Mexico => "mx", + Flag::MarshallIslands => "mh", + Flag::NorthMacedonia => "mk", + Flag::Mali => "ml", + Flag::Malta => "mt", + Flag::Myanmar => "mm", + Flag::Montenegro => "me", + Flag::Mongolia => "mn", + Flag::Mozambique => "mz", + Flag::Mauritania => "mr", + Flag::Mauritius => "mu", + Flag::Malawi => "mw", + Flag::Malaysia => "my", + Flag::Namibia => "na", + Flag::Niger => "ne", + Flag::Nigeria => "ng", + Flag::Nicaragua => "ni", + Flag::Netherlands => "nl", + Flag::Norway => "no", + Flag::Nepal => "np", + Flag::Nauru => "nr", + Flag::NewZealand => "nz", + Flag::Oman => "om", + Flag::Pakistan => "pk", + Flag::Panama => "pa", + Flag::Peru => "pe", + Flag::Philippines => "ph", + Flag::Palau => "pw", + Flag::PapuaNewGuinea => "pg", + Flag::Poland => "pl", + Flag::FrenchPolynesia => "pf", + Flag::NorthKorea => "kp", + Flag::Portugal => "pt", + Flag::Paraguay => "py", + Flag::Qatar => "qa", + Flag::Romania => "ro", + Flag::Russia => "ru", + Flag::Rwanda => "rw", + Flag::SaudiArabia => "sa", + Flag::Sudan => "sd", + Flag::Senegal => "sn", + Flag::Singapore => "sg", + Flag::SolomonIslands => "sb", + Flag::SierraLeone => "sl", + Flag::ElSalvador => "sv", + Flag::SanMarino => "sm", + Flag::Somalia => "so", + Flag::Serbia => "rs", + Flag::SouthSudan => "ss", + Flag::SaoTomeAndPrincipe => "st", + Flag::Suriname => "sr", + Flag::Slovakia => "sk", + Flag::Slovenia => "si", + Flag::Sweden => "se", + Flag::Eswatini => "sz", + Flag::Seychelles => "sc", + Flag::Syria => "sy", + Flag::Chad => "td", + Flag::Togo => "tg", + Flag::Thailand => "th", + Flag::Tajikistan => "tj", + Flag::Turkmenistan => "tm", + Flag::TimorLeste => "tl", + Flag::Tonga => "to", + Flag::TrinidadAndTobago => "tt", + Flag::Tunisia => "tn", + Flag::Turkey => "tr", + Flag::Tuvalu => "tv", + Flag::Tanzania => "tz", + Flag::Uganda => "ug", + Flag::Ukraine => "ua", + Flag::Uruguay => "uy", + Flag::UnitedStates => "us", + Flag::Uzbekistan => "uz", + Flag::VaticanCity => "va", + Flag::SaintVincentAndTheGrenadines => "vc", + Flag::Venezuela => "ve", + Flag::Vietnam => "vn", + Flag::Vanuatu => "vu", + Flag::Samoa => "ws", + Flag::Yemen => "ye", + Flag::SouthAfrica => "za", + Flag::Zambia => "zm", + Flag::Zimbabwe => "zw", + } + } +} + +impl std::fmt::Display for Flag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/framework.rs b/src/enums/framework.rs new file mode 100644 index 0000000..a61e7e7 --- /dev/null +++ b/src/enums/framework.rs @@ -0,0 +1,65 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Framework { + #[serde(rename = "analog")] + #[default] + Analog, + #[serde(rename = "angular")] + Angular, + #[serde(rename = "nextjs")] + Nextjs, + #[serde(rename = "react")] + React, + #[serde(rename = "nuxt")] + Nuxt, + #[serde(rename = "vue")] + Vue, + #[serde(rename = "sveltekit")] + Sveltekit, + #[serde(rename = "astro")] + Astro, + #[serde(rename = "tanstack-start")] + TanstackStart, + #[serde(rename = "remix")] + Remix, + #[serde(rename = "lynx")] + Lynx, + #[serde(rename = "flutter")] + Flutter, + #[serde(rename = "react-native")] + ReactNative, + #[serde(rename = "vite")] + Vite, + #[serde(rename = "other")] + Other, +} + +impl Framework { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Framework::Analog => "analog", + Framework::Angular => "angular", + Framework::Nextjs => "nextjs", + Framework::React => "react", + Framework::Nuxt => "nuxt", + Framework::Vue => "vue", + Framework::Sveltekit => "sveltekit", + Framework::Astro => "astro", + Framework::TanstackStart => "tanstack-start", + Framework::Remix => "remix", + Framework::Lynx => "lynx", + Framework::Flutter => "flutter", + Framework::ReactNative => "react-native", + Framework::Vite => "vite", + Framework::Other => "other", + } + } +} + +impl std::fmt::Display for Framework { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/health_antivirus_status.rs b/src/enums/health_antivirus_status.rs new file mode 100644 index 0000000..b11a2d2 --- /dev/null +++ b/src/enums/health_antivirus_status.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum HealthAntivirusStatus { + #[serde(rename = "disabled")] + #[default] + Disabled, + #[serde(rename = "offline")] + Offline, + #[serde(rename = "online")] + Online, +} + +impl HealthAntivirusStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + HealthAntivirusStatus::Disabled => "disabled", + HealthAntivirusStatus::Offline => "offline", + HealthAntivirusStatus::Online => "online", + } + } +} + +impl std::fmt::Display for HealthAntivirusStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/health_check_status.rs b/src/enums/health_check_status.rs new file mode 100644 index 0000000..3964289 --- /dev/null +++ b/src/enums/health_check_status.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum HealthCheckStatus { + #[serde(rename = "pass")] + #[default] + Pass, + #[serde(rename = "fail")] + Fail, +} + +impl HealthCheckStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + HealthCheckStatus::Pass => "pass", + HealthCheckStatus::Fail => "fail", + } + } +} + +impl std::fmt::Display for HealthCheckStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/image_format.rs b/src/enums/image_format.rs new file mode 100644 index 0000000..8798c97 --- /dev/null +++ b/src/enums/image_format.rs @@ -0,0 +1,41 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum ImageFormat { + #[serde(rename = "jpg")] + #[default] + Jpg, + #[serde(rename = "jpeg")] + Jpeg, + #[serde(rename = "png")] + Png, + #[serde(rename = "webp")] + Webp, + #[serde(rename = "heic")] + Heic, + #[serde(rename = "avif")] + Avif, + #[serde(rename = "gif")] + Gif, +} + +impl ImageFormat { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + ImageFormat::Jpg => "jpg", + ImageFormat::Jpeg => "jpeg", + ImageFormat::Png => "png", + ImageFormat::Webp => "webp", + ImageFormat::Heic => "heic", + ImageFormat::Avif => "avif", + ImageFormat::Gif => "gif", + } + } +} + +impl std::fmt::Display for ImageFormat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/image_gravity.rs b/src/enums/image_gravity.rs new file mode 100644 index 0000000..18d07bb --- /dev/null +++ b/src/enums/image_gravity.rs @@ -0,0 +1,47 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum ImageGravity { + #[serde(rename = "center")] + #[default] + Center, + #[serde(rename = "top-left")] + TopLeft, + #[serde(rename = "top")] + Top, + #[serde(rename = "top-right")] + TopRight, + #[serde(rename = "left")] + Left, + #[serde(rename = "right")] + Right, + #[serde(rename = "bottom-left")] + BottomLeft, + #[serde(rename = "bottom")] + Bottom, + #[serde(rename = "bottom-right")] + BottomRight, +} + +impl ImageGravity { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + ImageGravity::Center => "center", + ImageGravity::TopLeft => "top-left", + ImageGravity::Top => "top", + ImageGravity::TopRight => "top-right", + ImageGravity::Left => "left", + ImageGravity::Right => "right", + ImageGravity::BottomLeft => "bottom-left", + ImageGravity::Bottom => "bottom", + ImageGravity::BottomRight => "bottom-right", + } + } +} + +impl std::fmt::Display for ImageGravity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/index_status.rs b/src/enums/index_status.rs new file mode 100644 index 0000000..fd30570 --- /dev/null +++ b/src/enums/index_status.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum IndexStatus { + #[serde(rename = "available")] + #[default] + Available, + #[serde(rename = "processing")] + Processing, + #[serde(rename = "deleting")] + Deleting, + #[serde(rename = "stuck")] + Stuck, + #[serde(rename = "failed")] + Failed, +} + +impl IndexStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + IndexStatus::Available => "available", + IndexStatus::Processing => "processing", + IndexStatus::Deleting => "deleting", + IndexStatus::Stuck => "stuck", + IndexStatus::Failed => "failed", + } + } +} + +impl std::fmt::Display for IndexStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/index_type.rs b/src/enums/index_type.rs new file mode 100644 index 0000000..f0f4679 --- /dev/null +++ b/src/enums/index_type.rs @@ -0,0 +1,32 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum IndexType { + #[serde(rename = "key")] + #[default] + Key, + #[serde(rename = "fulltext")] + Fulltext, + #[serde(rename = "unique")] + Unique, + #[serde(rename = "spatial")] + Spatial, +} + +impl IndexType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + IndexType::Key => "key", + IndexType::Fulltext => "fulltext", + IndexType::Unique => "unique", + IndexType::Spatial => "spatial", + } + } +} + +impl std::fmt::Display for IndexType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/message_priority.rs b/src/enums/message_priority.rs new file mode 100644 index 0000000..167616c --- /dev/null +++ b/src/enums/message_priority.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum MessagePriority { + #[serde(rename = "normal")] + #[default] + Normal, + #[serde(rename = "high")] + High, +} + +impl MessagePriority { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + MessagePriority::Normal => "normal", + MessagePriority::High => "high", + } + } +} + +impl std::fmt::Display for MessagePriority { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/message_status.rs b/src/enums/message_status.rs new file mode 100644 index 0000000..eb07211 --- /dev/null +++ b/src/enums/message_status.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum MessageStatus { + #[serde(rename = "draft")] + #[default] + Draft, + #[serde(rename = "processing")] + Processing, + #[serde(rename = "scheduled")] + Scheduled, + #[serde(rename = "sent")] + Sent, + #[serde(rename = "failed")] + Failed, +} + +impl MessageStatus { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + MessageStatus::Draft => "draft", + MessageStatus::Processing => "processing", + MessageStatus::Scheduled => "scheduled", + MessageStatus::Sent => "sent", + MessageStatus::Failed => "failed", + } + } +} + +impl std::fmt::Display for MessageStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/messaging_provider_type.rs b/src/enums/messaging_provider_type.rs new file mode 100644 index 0000000..edebe82 --- /dev/null +++ b/src/enums/messaging_provider_type.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum MessagingProviderType { + #[serde(rename = "email")] + #[default] + Email, + #[serde(rename = "sms")] + Sms, + #[serde(rename = "push")] + Push, +} + +impl MessagingProviderType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + MessagingProviderType::Email => "email", + MessagingProviderType::Sms => "sms", + MessagingProviderType::Push => "push", + } + } +} + +impl std::fmt::Display for MessagingProviderType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/mod.rs b/src/enums/mod.rs new file mode 100644 index 0000000..c6705a4 --- /dev/null +++ b/src/enums/mod.rs @@ -0,0 +1,84 @@ +//! Enums for Appwrite SDK + +pub mod authenticator_type; +pub use authenticator_type::AuthenticatorType; +pub mod authentication_factor; +pub use authentication_factor::AuthenticationFactor; +pub mod o_auth_provider; +pub use o_auth_provider::OAuthProvider; +pub mod browser; +pub use browser::Browser; +pub mod credit_card; +pub use credit_card::CreditCard; +pub mod flag; +pub use flag::Flag; +pub mod theme; +pub use theme::Theme; +pub mod timezone; +pub use timezone::Timezone; +pub mod browser_permission; +pub use browser_permission::BrowserPermission; +pub mod image_format; +pub use image_format::ImageFormat; +pub mod backup_services; +pub use backup_services::BackupServices; +pub mod relationship_type; +pub use relationship_type::RelationshipType; +pub mod relation_mutate; +pub use relation_mutate::RelationMutate; +pub mod index_type; +pub use index_type::IndexType; +pub mod order_by; +pub use order_by::OrderBy; +pub mod runtime; +pub use runtime::Runtime; +pub mod scopes; +pub use scopes::Scopes; +pub mod template_reference_type; +pub use template_reference_type::TemplateReferenceType; +pub mod vcs_reference_type; +pub use vcs_reference_type::VCSReferenceType; +pub mod deployment_download_type; +pub use deployment_download_type::DeploymentDownloadType; +pub mod execution_method; +pub use execution_method::ExecutionMethod; +pub mod name; +pub use name::Name; +pub mod message_priority; +pub use message_priority::MessagePriority; +pub mod smtp_encryption; +pub use smtp_encryption::SmtpEncryption; +pub mod framework; +pub use framework::Framework; +pub mod build_runtime; +pub use build_runtime::BuildRuntime; +pub mod adapter; +pub use adapter::Adapter; +pub mod compression; +pub use compression::Compression; +pub mod image_gravity; +pub use image_gravity::ImageGravity; +pub mod password_hash; +pub use password_hash::PasswordHash; +pub mod messaging_provider_type; +pub use messaging_provider_type::MessagingProviderType; +pub mod database_type; +pub use database_type::DatabaseType; +pub mod attribute_status; +pub use attribute_status::AttributeStatus; +pub mod column_status; +pub use column_status::ColumnStatus; +pub mod index_status; +pub use index_status::IndexStatus; +pub mod deployment_status; +pub use deployment_status::DeploymentStatus; +pub mod execution_trigger; +pub use execution_trigger::ExecutionTrigger; +pub mod execution_status; +pub use execution_status::ExecutionStatus; +pub mod health_antivirus_status; +pub use health_antivirus_status::HealthAntivirusStatus; +pub mod health_check_status; +pub use health_check_status::HealthCheckStatus; +pub mod message_status; +pub use message_status::MessageStatus; diff --git a/src/enums/name.rs b/src/enums/name.rs new file mode 100644 index 0000000..a5a7e30 --- /dev/null +++ b/src/enums/name.rs @@ -0,0 +1,59 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Name { + #[serde(rename = "v1-database")] + #[default] + V1Database, + #[serde(rename = "v1-deletes")] + V1Deletes, + #[serde(rename = "v1-audits")] + V1Audits, + #[serde(rename = "v1-mails")] + V1Mails, + #[serde(rename = "v1-functions")] + V1Functions, + #[serde(rename = "v1-stats-resources")] + V1StatsResources, + #[serde(rename = "v1-stats-usage")] + V1StatsUsage, + #[serde(rename = "v1-webhooks")] + V1Webhooks, + #[serde(rename = "v1-certificates")] + V1Certificates, + #[serde(rename = "v1-builds")] + V1Builds, + #[serde(rename = "v1-screenshots")] + V1Screenshots, + #[serde(rename = "v1-messaging")] + V1Messaging, + #[serde(rename = "v1-migrations")] + V1Migrations, +} + +impl Name { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Name::V1Database => "v1-database", + Name::V1Deletes => "v1-deletes", + Name::V1Audits => "v1-audits", + Name::V1Mails => "v1-mails", + Name::V1Functions => "v1-functions", + Name::V1StatsResources => "v1-stats-resources", + Name::V1StatsUsage => "v1-stats-usage", + Name::V1Webhooks => "v1-webhooks", + Name::V1Certificates => "v1-certificates", + Name::V1Builds => "v1-builds", + Name::V1Screenshots => "v1-screenshots", + Name::V1Messaging => "v1-messaging", + Name::V1Migrations => "v1-migrations", + } + } +} + +impl std::fmt::Display for Name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/o_auth_provider.rs b/src/enums/o_auth_provider.rs new file mode 100644 index 0000000..2514068 --- /dev/null +++ b/src/enums/o_auth_provider.rs @@ -0,0 +1,137 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum OAuthProvider { + #[serde(rename = "amazon")] + #[default] + Amazon, + #[serde(rename = "apple")] + Apple, + #[serde(rename = "auth0")] + Auth0, + #[serde(rename = "authentik")] + Authentik, + #[serde(rename = "autodesk")] + Autodesk, + #[serde(rename = "bitbucket")] + Bitbucket, + #[serde(rename = "bitly")] + Bitly, + #[serde(rename = "box")] + Box, + #[serde(rename = "dailymotion")] + Dailymotion, + #[serde(rename = "discord")] + Discord, + #[serde(rename = "disqus")] + Disqus, + #[serde(rename = "dropbox")] + Dropbox, + #[serde(rename = "etsy")] + Etsy, + #[serde(rename = "facebook")] + Facebook, + #[serde(rename = "figma")] + Figma, + #[serde(rename = "github")] + Github, + #[serde(rename = "gitlab")] + Gitlab, + #[serde(rename = "google")] + Google, + #[serde(rename = "linkedin")] + Linkedin, + #[serde(rename = "microsoft")] + Microsoft, + #[serde(rename = "notion")] + Notion, + #[serde(rename = "oidc")] + Oidc, + #[serde(rename = "okta")] + Okta, + #[serde(rename = "paypal")] + Paypal, + #[serde(rename = "paypalSandbox")] + PaypalSandbox, + #[serde(rename = "podio")] + Podio, + #[serde(rename = "salesforce")] + Salesforce, + #[serde(rename = "slack")] + Slack, + #[serde(rename = "spotify")] + Spotify, + #[serde(rename = "stripe")] + Stripe, + #[serde(rename = "tradeshift")] + Tradeshift, + #[serde(rename = "tradeshiftBox")] + TradeshiftBox, + #[serde(rename = "twitch")] + Twitch, + #[serde(rename = "wordpress")] + Wordpress, + #[serde(rename = "yahoo")] + Yahoo, + #[serde(rename = "yammer")] + Yammer, + #[serde(rename = "yandex")] + Yandex, + #[serde(rename = "zoho")] + Zoho, + #[serde(rename = "zoom")] + Zoom, +} + +impl OAuthProvider { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + OAuthProvider::Amazon => "amazon", + OAuthProvider::Apple => "apple", + OAuthProvider::Auth0 => "auth0", + OAuthProvider::Authentik => "authentik", + OAuthProvider::Autodesk => "autodesk", + OAuthProvider::Bitbucket => "bitbucket", + OAuthProvider::Bitly => "bitly", + OAuthProvider::Box => "box", + OAuthProvider::Dailymotion => "dailymotion", + OAuthProvider::Discord => "discord", + OAuthProvider::Disqus => "disqus", + OAuthProvider::Dropbox => "dropbox", + OAuthProvider::Etsy => "etsy", + OAuthProvider::Facebook => "facebook", + OAuthProvider::Figma => "figma", + OAuthProvider::Github => "github", + OAuthProvider::Gitlab => "gitlab", + OAuthProvider::Google => "google", + OAuthProvider::Linkedin => "linkedin", + OAuthProvider::Microsoft => "microsoft", + OAuthProvider::Notion => "notion", + OAuthProvider::Oidc => "oidc", + OAuthProvider::Okta => "okta", + OAuthProvider::Paypal => "paypal", + OAuthProvider::PaypalSandbox => "paypalSandbox", + OAuthProvider::Podio => "podio", + OAuthProvider::Salesforce => "salesforce", + OAuthProvider::Slack => "slack", + OAuthProvider::Spotify => "spotify", + OAuthProvider::Stripe => "stripe", + OAuthProvider::Tradeshift => "tradeshift", + OAuthProvider::TradeshiftBox => "tradeshiftBox", + OAuthProvider::Twitch => "twitch", + OAuthProvider::Wordpress => "wordpress", + OAuthProvider::Yahoo => "yahoo", + OAuthProvider::Yammer => "yammer", + OAuthProvider::Yandex => "yandex", + OAuthProvider::Zoho => "zoho", + OAuthProvider::Zoom => "zoom", + } + } +} + +impl std::fmt::Display for OAuthProvider { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/order_by.rs b/src/enums/order_by.rs new file mode 100644 index 0000000..9ff92e9 --- /dev/null +++ b/src/enums/order_by.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum OrderBy { + #[serde(rename = "asc")] + #[default] + Asc, + #[serde(rename = "desc")] + Desc, +} + +impl OrderBy { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + OrderBy::Asc => "asc", + OrderBy::Desc => "desc", + } + } +} + +impl std::fmt::Display for OrderBy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/password_hash.rs b/src/enums/password_hash.rs new file mode 100644 index 0000000..eaffe31 --- /dev/null +++ b/src/enums/password_hash.rs @@ -0,0 +1,53 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum PasswordHash { + #[serde(rename = "sha1")] + #[default] + Sha1, + #[serde(rename = "sha224")] + Sha224, + #[serde(rename = "sha256")] + Sha256, + #[serde(rename = "sha384")] + Sha384, + #[serde(rename = "sha512/224")] + Sha512224, + #[serde(rename = "sha512/256")] + Sha512256, + #[serde(rename = "sha512")] + Sha512, + #[serde(rename = "sha3-224")] + Sha3224, + #[serde(rename = "sha3-256")] + Sha3256, + #[serde(rename = "sha3-384")] + Sha3384, + #[serde(rename = "sha3-512")] + Sha3512, +} + +impl PasswordHash { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + PasswordHash::Sha1 => "sha1", + PasswordHash::Sha224 => "sha224", + PasswordHash::Sha256 => "sha256", + PasswordHash::Sha384 => "sha384", + PasswordHash::Sha512224 => "sha512/224", + PasswordHash::Sha512256 => "sha512/256", + PasswordHash::Sha512 => "sha512", + PasswordHash::Sha3224 => "sha3-224", + PasswordHash::Sha3256 => "sha3-256", + PasswordHash::Sha3384 => "sha3-384", + PasswordHash::Sha3512 => "sha3-512", + } + } +} + +impl std::fmt::Display for PasswordHash { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/relation_mutate.rs b/src/enums/relation_mutate.rs new file mode 100644 index 0000000..ae47486 --- /dev/null +++ b/src/enums/relation_mutate.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum RelationMutate { + #[serde(rename = "cascade")] + #[default] + Cascade, + #[serde(rename = "restrict")] + Restrict, + #[serde(rename = "setNull")] + SetNull, +} + +impl RelationMutate { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + RelationMutate::Cascade => "cascade", + RelationMutate::Restrict => "restrict", + RelationMutate::SetNull => "setNull", + } + } +} + +impl std::fmt::Display for RelationMutate { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/relationship_type.rs b/src/enums/relationship_type.rs new file mode 100644 index 0000000..c24e7e2 --- /dev/null +++ b/src/enums/relationship_type.rs @@ -0,0 +1,32 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum RelationshipType { + #[serde(rename = "oneToOne")] + #[default] + OneToOne, + #[serde(rename = "manyToOne")] + ManyToOne, + #[serde(rename = "manyToMany")] + ManyToMany, + #[serde(rename = "oneToMany")] + OneToMany, +} + +impl RelationshipType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + RelationshipType::OneToOne => "oneToOne", + RelationshipType::ManyToOne => "manyToOne", + RelationshipType::ManyToMany => "manyToMany", + RelationshipType::OneToMany => "oneToMany", + } + } +} + +impl std::fmt::Display for RelationshipType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/runtime.rs b/src/enums/runtime.rs new file mode 100644 index 0000000..bce57ee --- /dev/null +++ b/src/enums/runtime.rs @@ -0,0 +1,536 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Runtime { + #[serde(rename = "node-14.5")] + #[default] + Node145, + #[serde(rename = "node-16.0")] + Node160, + #[serde(rename = "node-18.0")] + Node180, + #[serde(rename = "node-19.0")] + Node190, + #[serde(rename = "node-20.0")] + Node200, + #[serde(rename = "node-21.0")] + Node210, + #[serde(rename = "node-22")] + Node22, + #[serde(rename = "node-23")] + Node23, + #[serde(rename = "node-24")] + Node24, + #[serde(rename = "node-25")] + Node25, + #[serde(rename = "php-8.0")] + Php80, + #[serde(rename = "php-8.1")] + Php81, + #[serde(rename = "php-8.2")] + Php82, + #[serde(rename = "php-8.3")] + Php83, + #[serde(rename = "php-8.4")] + Php84, + #[serde(rename = "ruby-3.0")] + Ruby30, + #[serde(rename = "ruby-3.1")] + Ruby31, + #[serde(rename = "ruby-3.2")] + Ruby32, + #[serde(rename = "ruby-3.3")] + Ruby33, + #[serde(rename = "ruby-3.4")] + Ruby34, + #[serde(rename = "ruby-4.0")] + Ruby40, + #[serde(rename = "python-3.8")] + Python38, + #[serde(rename = "python-3.9")] + Python39, + #[serde(rename = "python-3.10")] + Python310, + #[serde(rename = "python-3.11")] + Python311, + #[serde(rename = "python-3.12")] + Python312, + #[serde(rename = "python-3.13")] + Python313, + #[serde(rename = "python-3.14")] + Python314, + #[serde(rename = "python-ml-3.11")] + PythonMl311, + #[serde(rename = "python-ml-3.12")] + PythonMl312, + #[serde(rename = "python-ml-3.13")] + PythonMl313, + #[serde(rename = "deno-1.40")] + Deno140, + #[serde(rename = "deno-1.46")] + Deno146, + #[serde(rename = "deno-2.0")] + Deno20, + #[serde(rename = "deno-2.5")] + Deno25, + #[serde(rename = "deno-2.6")] + Deno26, + #[serde(rename = "dart-2.15")] + Dart215, + #[serde(rename = "dart-2.16")] + Dart216, + #[serde(rename = "dart-2.17")] + Dart217, + #[serde(rename = "dart-2.18")] + Dart218, + #[serde(rename = "dart-2.19")] + Dart219, + #[serde(rename = "dart-3.0")] + Dart30, + #[serde(rename = "dart-3.1")] + Dart31, + #[serde(rename = "dart-3.3")] + Dart33, + #[serde(rename = "dart-3.5")] + Dart35, + #[serde(rename = "dart-3.8")] + Dart38, + #[serde(rename = "dart-3.9")] + Dart39, + #[serde(rename = "dart-3.10")] + Dart310, + #[serde(rename = "dotnet-6.0")] + Dotnet60, + #[serde(rename = "dotnet-7.0")] + Dotnet70, + #[serde(rename = "dotnet-8.0")] + Dotnet80, + #[serde(rename = "dotnet-10")] + Dotnet10, + #[serde(rename = "java-8.0")] + Java80, + #[serde(rename = "java-11.0")] + Java110, + #[serde(rename = "java-17.0")] + Java170, + #[serde(rename = "java-18.0")] + Java180, + #[serde(rename = "java-21.0")] + Java210, + #[serde(rename = "java-22")] + Java22, + #[serde(rename = "java-25")] + Java25, + #[serde(rename = "swift-5.5")] + Swift55, + #[serde(rename = "swift-5.8")] + Swift58, + #[serde(rename = "swift-5.9")] + Swift59, + #[serde(rename = "swift-5.10")] + Swift510, + #[serde(rename = "swift-6.2")] + Swift62, + #[serde(rename = "kotlin-1.6")] + Kotlin16, + #[serde(rename = "kotlin-1.8")] + Kotlin18, + #[serde(rename = "kotlin-1.9")] + Kotlin19, + #[serde(rename = "kotlin-2.0")] + Kotlin20, + #[serde(rename = "kotlin-2.3")] + Kotlin23, + #[serde(rename = "cpp-17")] + Cpp17, + #[serde(rename = "cpp-20")] + Cpp20, + #[serde(rename = "bun-1.0")] + Bun10, + #[serde(rename = "bun-1.1")] + Bun11, + #[serde(rename = "bun-1.2")] + Bun12, + #[serde(rename = "bun-1.3")] + Bun13, + #[serde(rename = "go-1.23")] + Go123, + #[serde(rename = "go-1.24")] + Go124, + #[serde(rename = "go-1.25")] + Go125, + #[serde(rename = "go-1.26")] + Go126, + #[serde(rename = "static-1")] + Static1, + #[serde(rename = "flutter-3.24")] + Flutter324, + #[serde(rename = "flutter-3.27")] + Flutter327, + #[serde(rename = "flutter-3.29")] + Flutter329, + #[serde(rename = "flutter-3.32")] + Flutter332, + #[serde(rename = "flutter-3.35")] + Flutter335, + #[serde(rename = "flutter-3.38")] + Flutter338, + #[serde(rename = "node-14.5-rc")] + Node145Rc, + #[serde(rename = "node-16.0-rc")] + Node160Rc, + #[serde(rename = "node-18.0-rc")] + Node180Rc, + #[serde(rename = "node-19.0-rc")] + Node190Rc, + #[serde(rename = "node-20.0-rc")] + Node200Rc, + #[serde(rename = "node-21.0-rc")] + Node210Rc, + #[serde(rename = "node-22-rc")] + Node22Rc, + #[serde(rename = "node-23-rc")] + Node23Rc, + #[serde(rename = "node-24-rc")] + Node24Rc, + #[serde(rename = "node-25-rc")] + Node25Rc, + #[serde(rename = "php-8.0-rc")] + Php80Rc, + #[serde(rename = "php-8.1-rc")] + Php81Rc, + #[serde(rename = "php-8.2-rc")] + Php82Rc, + #[serde(rename = "php-8.3-rc")] + Php83Rc, + #[serde(rename = "php-8.4-rc")] + Php84Rc, + #[serde(rename = "ruby-3.0-rc")] + Ruby30Rc, + #[serde(rename = "ruby-3.1-rc")] + Ruby31Rc, + #[serde(rename = "ruby-3.2-rc")] + Ruby32Rc, + #[serde(rename = "ruby-3.3-rc")] + Ruby33Rc, + #[serde(rename = "ruby-3.4-rc")] + Ruby34Rc, + #[serde(rename = "ruby-4.0-rc")] + Ruby40Rc, + #[serde(rename = "python-3.8-rc")] + Python38Rc, + #[serde(rename = "python-3.9-rc")] + Python39Rc, + #[serde(rename = "python-3.10-rc")] + Python310Rc, + #[serde(rename = "python-3.11-rc")] + Python311Rc, + #[serde(rename = "python-3.12-rc")] + Python312Rc, + #[serde(rename = "python-3.13-rc")] + Python313Rc, + #[serde(rename = "python-3.14-rc")] + Python314Rc, + #[serde(rename = "python-ml-3.11-rc")] + PythonMl311Rc, + #[serde(rename = "python-ml-3.12-rc")] + PythonMl312Rc, + #[serde(rename = "python-ml-3.13-rc")] + PythonMl313Rc, + #[serde(rename = "deno-1.40-rc")] + Deno140Rc, + #[serde(rename = "deno-1.46-rc")] + Deno146Rc, + #[serde(rename = "deno-2.0-rc")] + Deno20Rc, + #[serde(rename = "deno-2.5-rc")] + Deno25Rc, + #[serde(rename = "deno-2.6-rc")] + Deno26Rc, + #[serde(rename = "dart-2.15-rc")] + Dart215Rc, + #[serde(rename = "dart-2.16-rc")] + Dart216Rc, + #[serde(rename = "dart-2.17-rc")] + Dart217Rc, + #[serde(rename = "dart-2.18-rc")] + Dart218Rc, + #[serde(rename = "dart-2.19-rc")] + Dart219Rc, + #[serde(rename = "dart-3.0-rc")] + Dart30Rc, + #[serde(rename = "dart-3.1-rc")] + Dart31Rc, + #[serde(rename = "dart-3.3-rc")] + Dart33Rc, + #[serde(rename = "dart-3.5-rc")] + Dart35Rc, + #[serde(rename = "dart-3.8-rc")] + Dart38Rc, + #[serde(rename = "dart-3.9-rc")] + Dart39Rc, + #[serde(rename = "dart-3.10-rc")] + Dart310Rc, + #[serde(rename = "dotnet-6.0-rc")] + Dotnet60Rc, + #[serde(rename = "dotnet-7.0-rc")] + Dotnet70Rc, + #[serde(rename = "dotnet-8.0-rc")] + Dotnet80Rc, + #[serde(rename = "dotnet-10-rc")] + Dotnet10Rc, + #[serde(rename = "java-8.0-rc")] + Java80Rc, + #[serde(rename = "java-11.0-rc")] + Java110Rc, + #[serde(rename = "java-17.0-rc")] + Java170Rc, + #[serde(rename = "java-18.0-rc")] + Java180Rc, + #[serde(rename = "java-21.0-rc")] + Java210Rc, + #[serde(rename = "java-22-rc")] + Java22Rc, + #[serde(rename = "java-25-rc")] + Java25Rc, + #[serde(rename = "swift-5.5-rc")] + Swift55Rc, + #[serde(rename = "swift-5.8-rc")] + Swift58Rc, + #[serde(rename = "swift-5.9-rc")] + Swift59Rc, + #[serde(rename = "swift-5.10-rc")] + Swift510Rc, + #[serde(rename = "swift-6.2-rc")] + Swift62Rc, + #[serde(rename = "kotlin-1.6-rc")] + Kotlin16Rc, + #[serde(rename = "kotlin-1.8-rc")] + Kotlin18Rc, + #[serde(rename = "kotlin-1.9-rc")] + Kotlin19Rc, + #[serde(rename = "kotlin-2.0-rc")] + Kotlin20Rc, + #[serde(rename = "kotlin-2.3-rc")] + Kotlin23Rc, + #[serde(rename = "cpp-17-rc")] + Cpp17Rc, + #[serde(rename = "cpp-20-rc")] + Cpp20Rc, + #[serde(rename = "bun-1.0-rc")] + Bun10Rc, + #[serde(rename = "bun-1.1-rc")] + Bun11Rc, + #[serde(rename = "bun-1.2-rc")] + Bun12Rc, + #[serde(rename = "bun-1.3-rc")] + Bun13Rc, + #[serde(rename = "go-1.23-rc")] + Go123Rc, + #[serde(rename = "go-1.24-rc")] + Go124Rc, + #[serde(rename = "go-1.25-rc")] + Go125Rc, + #[serde(rename = "go-1.26-rc")] + Go126Rc, + #[serde(rename = "static-1-rc")] + Static1Rc, + #[serde(rename = "flutter-3.24-rc")] + Flutter324Rc, + #[serde(rename = "flutter-3.27-rc")] + Flutter327Rc, + #[serde(rename = "flutter-3.29-rc")] + Flutter329Rc, + #[serde(rename = "flutter-3.32-rc")] + Flutter332Rc, + #[serde(rename = "flutter-3.35-rc")] + Flutter335Rc, + #[serde(rename = "flutter-3.38-rc")] + Flutter338Rc, +} + +impl Runtime { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Runtime::Node145 => "node-14.5", + Runtime::Node160 => "node-16.0", + Runtime::Node180 => "node-18.0", + Runtime::Node190 => "node-19.0", + Runtime::Node200 => "node-20.0", + Runtime::Node210 => "node-21.0", + Runtime::Node22 => "node-22", + Runtime::Node23 => "node-23", + Runtime::Node24 => "node-24", + Runtime::Node25 => "node-25", + Runtime::Php80 => "php-8.0", + Runtime::Php81 => "php-8.1", + Runtime::Php82 => "php-8.2", + Runtime::Php83 => "php-8.3", + Runtime::Php84 => "php-8.4", + Runtime::Ruby30 => "ruby-3.0", + Runtime::Ruby31 => "ruby-3.1", + Runtime::Ruby32 => "ruby-3.2", + Runtime::Ruby33 => "ruby-3.3", + Runtime::Ruby34 => "ruby-3.4", + Runtime::Ruby40 => "ruby-4.0", + Runtime::Python38 => "python-3.8", + Runtime::Python39 => "python-3.9", + Runtime::Python310 => "python-3.10", + Runtime::Python311 => "python-3.11", + Runtime::Python312 => "python-3.12", + Runtime::Python313 => "python-3.13", + Runtime::Python314 => "python-3.14", + Runtime::PythonMl311 => "python-ml-3.11", + Runtime::PythonMl312 => "python-ml-3.12", + Runtime::PythonMl313 => "python-ml-3.13", + Runtime::Deno140 => "deno-1.40", + Runtime::Deno146 => "deno-1.46", + Runtime::Deno20 => "deno-2.0", + Runtime::Deno25 => "deno-2.5", + Runtime::Deno26 => "deno-2.6", + Runtime::Dart215 => "dart-2.15", + Runtime::Dart216 => "dart-2.16", + Runtime::Dart217 => "dart-2.17", + Runtime::Dart218 => "dart-2.18", + Runtime::Dart219 => "dart-2.19", + Runtime::Dart30 => "dart-3.0", + Runtime::Dart31 => "dart-3.1", + Runtime::Dart33 => "dart-3.3", + Runtime::Dart35 => "dart-3.5", + Runtime::Dart38 => "dart-3.8", + Runtime::Dart39 => "dart-3.9", + Runtime::Dart310 => "dart-3.10", + Runtime::Dotnet60 => "dotnet-6.0", + Runtime::Dotnet70 => "dotnet-7.0", + Runtime::Dotnet80 => "dotnet-8.0", + Runtime::Dotnet10 => "dotnet-10", + Runtime::Java80 => "java-8.0", + Runtime::Java110 => "java-11.0", + Runtime::Java170 => "java-17.0", + Runtime::Java180 => "java-18.0", + Runtime::Java210 => "java-21.0", + Runtime::Java22 => "java-22", + Runtime::Java25 => "java-25", + Runtime::Swift55 => "swift-5.5", + Runtime::Swift58 => "swift-5.8", + Runtime::Swift59 => "swift-5.9", + Runtime::Swift510 => "swift-5.10", + Runtime::Swift62 => "swift-6.2", + Runtime::Kotlin16 => "kotlin-1.6", + Runtime::Kotlin18 => "kotlin-1.8", + Runtime::Kotlin19 => "kotlin-1.9", + Runtime::Kotlin20 => "kotlin-2.0", + Runtime::Kotlin23 => "kotlin-2.3", + Runtime::Cpp17 => "cpp-17", + Runtime::Cpp20 => "cpp-20", + Runtime::Bun10 => "bun-1.0", + Runtime::Bun11 => "bun-1.1", + Runtime::Bun12 => "bun-1.2", + Runtime::Bun13 => "bun-1.3", + Runtime::Go123 => "go-1.23", + Runtime::Go124 => "go-1.24", + Runtime::Go125 => "go-1.25", + Runtime::Go126 => "go-1.26", + Runtime::Static1 => "static-1", + Runtime::Flutter324 => "flutter-3.24", + Runtime::Flutter327 => "flutter-3.27", + Runtime::Flutter329 => "flutter-3.29", + Runtime::Flutter332 => "flutter-3.32", + Runtime::Flutter335 => "flutter-3.35", + Runtime::Flutter338 => "flutter-3.38", + Runtime::Node145Rc => "node-14.5-rc", + Runtime::Node160Rc => "node-16.0-rc", + Runtime::Node180Rc => "node-18.0-rc", + Runtime::Node190Rc => "node-19.0-rc", + Runtime::Node200Rc => "node-20.0-rc", + Runtime::Node210Rc => "node-21.0-rc", + Runtime::Node22Rc => "node-22-rc", + Runtime::Node23Rc => "node-23-rc", + Runtime::Node24Rc => "node-24-rc", + Runtime::Node25Rc => "node-25-rc", + Runtime::Php80Rc => "php-8.0-rc", + Runtime::Php81Rc => "php-8.1-rc", + Runtime::Php82Rc => "php-8.2-rc", + Runtime::Php83Rc => "php-8.3-rc", + Runtime::Php84Rc => "php-8.4-rc", + Runtime::Ruby30Rc => "ruby-3.0-rc", + Runtime::Ruby31Rc => "ruby-3.1-rc", + Runtime::Ruby32Rc => "ruby-3.2-rc", + Runtime::Ruby33Rc => "ruby-3.3-rc", + Runtime::Ruby34Rc => "ruby-3.4-rc", + Runtime::Ruby40Rc => "ruby-4.0-rc", + Runtime::Python38Rc => "python-3.8-rc", + Runtime::Python39Rc => "python-3.9-rc", + Runtime::Python310Rc => "python-3.10-rc", + Runtime::Python311Rc => "python-3.11-rc", + Runtime::Python312Rc => "python-3.12-rc", + Runtime::Python313Rc => "python-3.13-rc", + Runtime::Python314Rc => "python-3.14-rc", + Runtime::PythonMl311Rc => "python-ml-3.11-rc", + Runtime::PythonMl312Rc => "python-ml-3.12-rc", + Runtime::PythonMl313Rc => "python-ml-3.13-rc", + Runtime::Deno140Rc => "deno-1.40-rc", + Runtime::Deno146Rc => "deno-1.46-rc", + Runtime::Deno20Rc => "deno-2.0-rc", + Runtime::Deno25Rc => "deno-2.5-rc", + Runtime::Deno26Rc => "deno-2.6-rc", + Runtime::Dart215Rc => "dart-2.15-rc", + Runtime::Dart216Rc => "dart-2.16-rc", + Runtime::Dart217Rc => "dart-2.17-rc", + Runtime::Dart218Rc => "dart-2.18-rc", + Runtime::Dart219Rc => "dart-2.19-rc", + Runtime::Dart30Rc => "dart-3.0-rc", + Runtime::Dart31Rc => "dart-3.1-rc", + Runtime::Dart33Rc => "dart-3.3-rc", + Runtime::Dart35Rc => "dart-3.5-rc", + Runtime::Dart38Rc => "dart-3.8-rc", + Runtime::Dart39Rc => "dart-3.9-rc", + Runtime::Dart310Rc => "dart-3.10-rc", + Runtime::Dotnet60Rc => "dotnet-6.0-rc", + Runtime::Dotnet70Rc => "dotnet-7.0-rc", + Runtime::Dotnet80Rc => "dotnet-8.0-rc", + Runtime::Dotnet10Rc => "dotnet-10-rc", + Runtime::Java80Rc => "java-8.0-rc", + Runtime::Java110Rc => "java-11.0-rc", + Runtime::Java170Rc => "java-17.0-rc", + Runtime::Java180Rc => "java-18.0-rc", + Runtime::Java210Rc => "java-21.0-rc", + Runtime::Java22Rc => "java-22-rc", + Runtime::Java25Rc => "java-25-rc", + Runtime::Swift55Rc => "swift-5.5-rc", + Runtime::Swift58Rc => "swift-5.8-rc", + Runtime::Swift59Rc => "swift-5.9-rc", + Runtime::Swift510Rc => "swift-5.10-rc", + Runtime::Swift62Rc => "swift-6.2-rc", + Runtime::Kotlin16Rc => "kotlin-1.6-rc", + Runtime::Kotlin18Rc => "kotlin-1.8-rc", + Runtime::Kotlin19Rc => "kotlin-1.9-rc", + Runtime::Kotlin20Rc => "kotlin-2.0-rc", + Runtime::Kotlin23Rc => "kotlin-2.3-rc", + Runtime::Cpp17Rc => "cpp-17-rc", + Runtime::Cpp20Rc => "cpp-20-rc", + Runtime::Bun10Rc => "bun-1.0-rc", + Runtime::Bun11Rc => "bun-1.1-rc", + Runtime::Bun12Rc => "bun-1.2-rc", + Runtime::Bun13Rc => "bun-1.3-rc", + Runtime::Go123Rc => "go-1.23-rc", + Runtime::Go124Rc => "go-1.24-rc", + Runtime::Go125Rc => "go-1.25-rc", + Runtime::Go126Rc => "go-1.26-rc", + Runtime::Static1Rc => "static-1-rc", + Runtime::Flutter324Rc => "flutter-3.24-rc", + Runtime::Flutter327Rc => "flutter-3.27-rc", + Runtime::Flutter329Rc => "flutter-3.29-rc", + Runtime::Flutter332Rc => "flutter-3.32-rc", + Runtime::Flutter335Rc => "flutter-3.35-rc", + Runtime::Flutter338Rc => "flutter-3.38-rc", + } + } +} + +impl std::fmt::Display for Runtime { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/scopes.rs b/src/enums/scopes.rs new file mode 100644 index 0000000..1cdc0c1 --- /dev/null +++ b/src/enums/scopes.rs @@ -0,0 +1,224 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Scopes { + #[serde(rename = "sessions.write")] + #[default] + SessionsWrite, + #[serde(rename = "users.read")] + UsersRead, + #[serde(rename = "users.write")] + UsersWrite, + #[serde(rename = "teams.read")] + TeamsRead, + #[serde(rename = "teams.write")] + TeamsWrite, + #[serde(rename = "databases.read")] + DatabasesRead, + #[serde(rename = "databases.write")] + DatabasesWrite, + #[serde(rename = "collections.read")] + CollectionsRead, + #[serde(rename = "collections.write")] + CollectionsWrite, + #[serde(rename = "tables.read")] + TablesRead, + #[serde(rename = "tables.write")] + TablesWrite, + #[serde(rename = "attributes.read")] + AttributesRead, + #[serde(rename = "attributes.write")] + AttributesWrite, + #[serde(rename = "columns.read")] + ColumnsRead, + #[serde(rename = "columns.write")] + ColumnsWrite, + #[serde(rename = "indexes.read")] + IndexesRead, + #[serde(rename = "indexes.write")] + IndexesWrite, + #[serde(rename = "documents.read")] + DocumentsRead, + #[serde(rename = "documents.write")] + DocumentsWrite, + #[serde(rename = "rows.read")] + RowsRead, + #[serde(rename = "rows.write")] + RowsWrite, + #[serde(rename = "files.read")] + FilesRead, + #[serde(rename = "files.write")] + FilesWrite, + #[serde(rename = "buckets.read")] + BucketsRead, + #[serde(rename = "buckets.write")] + BucketsWrite, + #[serde(rename = "functions.read")] + FunctionsRead, + #[serde(rename = "functions.write")] + FunctionsWrite, + #[serde(rename = "sites.read")] + SitesRead, + #[serde(rename = "sites.write")] + SitesWrite, + #[serde(rename = "log.read")] + LogRead, + #[serde(rename = "log.write")] + LogWrite, + #[serde(rename = "execution.read")] + ExecutionRead, + #[serde(rename = "execution.write")] + ExecutionWrite, + #[serde(rename = "locale.read")] + LocaleRead, + #[serde(rename = "avatars.read")] + AvatarsRead, + #[serde(rename = "health.read")] + HealthRead, + #[serde(rename = "providers.read")] + ProvidersRead, + #[serde(rename = "providers.write")] + ProvidersWrite, + #[serde(rename = "messages.read")] + MessagesRead, + #[serde(rename = "messages.write")] + MessagesWrite, + #[serde(rename = "topics.read")] + TopicsRead, + #[serde(rename = "topics.write")] + TopicsWrite, + #[serde(rename = "subscribers.read")] + SubscribersRead, + #[serde(rename = "subscribers.write")] + SubscribersWrite, + #[serde(rename = "targets.read")] + TargetsRead, + #[serde(rename = "targets.write")] + TargetsWrite, + #[serde(rename = "rules.read")] + RulesRead, + #[serde(rename = "rules.write")] + RulesWrite, + #[serde(rename = "schedules.read")] + SchedulesRead, + #[serde(rename = "schedules.write")] + SchedulesWrite, + #[serde(rename = "migrations.read")] + MigrationsRead, + #[serde(rename = "migrations.write")] + MigrationsWrite, + #[serde(rename = "vcs.read")] + VcsRead, + #[serde(rename = "vcs.write")] + VcsWrite, + #[serde(rename = "assistant.read")] + AssistantRead, + #[serde(rename = "tokens.read")] + TokensRead, + #[serde(rename = "tokens.write")] + TokensWrite, + #[serde(rename = "webhooks.read")] + WebhooksRead, + #[serde(rename = "webhooks.write")] + WebhooksWrite, + #[serde(rename = "policies.write")] + PoliciesWrite, + #[serde(rename = "policies.read")] + PoliciesRead, + #[serde(rename = "archives.read")] + ArchivesRead, + #[serde(rename = "archives.write")] + ArchivesWrite, + #[serde(rename = "restorations.read")] + RestorationsRead, + #[serde(rename = "restorations.write")] + RestorationsWrite, + #[serde(rename = "domains.read")] + DomainsRead, + #[serde(rename = "domains.write")] + DomainsWrite, + #[serde(rename = "events.read")] + EventsRead, +} + +impl Scopes { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Scopes::SessionsWrite => "sessions.write", + Scopes::UsersRead => "users.read", + Scopes::UsersWrite => "users.write", + Scopes::TeamsRead => "teams.read", + Scopes::TeamsWrite => "teams.write", + Scopes::DatabasesRead => "databases.read", + Scopes::DatabasesWrite => "databases.write", + Scopes::CollectionsRead => "collections.read", + Scopes::CollectionsWrite => "collections.write", + Scopes::TablesRead => "tables.read", + Scopes::TablesWrite => "tables.write", + Scopes::AttributesRead => "attributes.read", + Scopes::AttributesWrite => "attributes.write", + Scopes::ColumnsRead => "columns.read", + Scopes::ColumnsWrite => "columns.write", + Scopes::IndexesRead => "indexes.read", + Scopes::IndexesWrite => "indexes.write", + Scopes::DocumentsRead => "documents.read", + Scopes::DocumentsWrite => "documents.write", + Scopes::RowsRead => "rows.read", + Scopes::RowsWrite => "rows.write", + Scopes::FilesRead => "files.read", + Scopes::FilesWrite => "files.write", + Scopes::BucketsRead => "buckets.read", + Scopes::BucketsWrite => "buckets.write", + Scopes::FunctionsRead => "functions.read", + Scopes::FunctionsWrite => "functions.write", + Scopes::SitesRead => "sites.read", + Scopes::SitesWrite => "sites.write", + Scopes::LogRead => "log.read", + Scopes::LogWrite => "log.write", + Scopes::ExecutionRead => "execution.read", + Scopes::ExecutionWrite => "execution.write", + Scopes::LocaleRead => "locale.read", + Scopes::AvatarsRead => "avatars.read", + Scopes::HealthRead => "health.read", + Scopes::ProvidersRead => "providers.read", + Scopes::ProvidersWrite => "providers.write", + Scopes::MessagesRead => "messages.read", + Scopes::MessagesWrite => "messages.write", + Scopes::TopicsRead => "topics.read", + Scopes::TopicsWrite => "topics.write", + Scopes::SubscribersRead => "subscribers.read", + Scopes::SubscribersWrite => "subscribers.write", + Scopes::TargetsRead => "targets.read", + Scopes::TargetsWrite => "targets.write", + Scopes::RulesRead => "rules.read", + Scopes::RulesWrite => "rules.write", + Scopes::SchedulesRead => "schedules.read", + Scopes::SchedulesWrite => "schedules.write", + Scopes::MigrationsRead => "migrations.read", + Scopes::MigrationsWrite => "migrations.write", + Scopes::VcsRead => "vcs.read", + Scopes::VcsWrite => "vcs.write", + Scopes::AssistantRead => "assistant.read", + Scopes::TokensRead => "tokens.read", + Scopes::TokensWrite => "tokens.write", + Scopes::WebhooksRead => "webhooks.read", + Scopes::WebhooksWrite => "webhooks.write", + Scopes::PoliciesWrite => "policies.write", + Scopes::PoliciesRead => "policies.read", + Scopes::ArchivesRead => "archives.read", + Scopes::ArchivesWrite => "archives.write", + Scopes::RestorationsRead => "restorations.read", + Scopes::RestorationsWrite => "restorations.write", + Scopes::DomainsRead => "domains.read", + Scopes::DomainsWrite => "domains.write", + Scopes::EventsRead => "events.read", + } + } +} + +impl std::fmt::Display for Scopes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/smtp_encryption.rs b/src/enums/smtp_encryption.rs new file mode 100644 index 0000000..db7d2e0 --- /dev/null +++ b/src/enums/smtp_encryption.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum SmtpEncryption { + #[serde(rename = "none")] + #[default] + None, + #[serde(rename = "ssl")] + Ssl, + #[serde(rename = "tls")] + Tls, +} + +impl SmtpEncryption { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + SmtpEncryption::None => "none", + SmtpEncryption::Ssl => "ssl", + SmtpEncryption::Tls => "tls", + } + } +} + +impl std::fmt::Display for SmtpEncryption { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/template_reference_type.rs b/src/enums/template_reference_type.rs new file mode 100644 index 0000000..69a3dcd --- /dev/null +++ b/src/enums/template_reference_type.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum TemplateReferenceType { + #[serde(rename = "branch")] + #[default] + Branch, + #[serde(rename = "commit")] + Commit, + #[serde(rename = "tag")] + Tag, +} + +impl TemplateReferenceType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + TemplateReferenceType::Branch => "branch", + TemplateReferenceType::Commit => "commit", + TemplateReferenceType::Tag => "tag", + } + } +} + +impl std::fmt::Display for TemplateReferenceType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/theme.rs b/src/enums/theme.rs new file mode 100644 index 0000000..b5f0ff2 --- /dev/null +++ b/src/enums/theme.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Theme { + #[serde(rename = "light")] + #[default] + Light, + #[serde(rename = "dark")] + Dark, +} + +impl Theme { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Theme::Light => "light", + Theme::Dark => "dark", + } + } +} + +impl std::fmt::Display for Theme { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/timezone.rs b/src/enums/timezone.rs new file mode 100644 index 0000000..7915543 --- /dev/null +++ b/src/enums/timezone.rs @@ -0,0 +1,1277 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum Timezone { + #[serde(rename = "africa/abidjan")] + #[default] + AfricaAbidjan, + #[serde(rename = "africa/accra")] + AfricaAccra, + #[serde(rename = "africa/addis_ababa")] + AfricaAddisAbaba, + #[serde(rename = "africa/algiers")] + AfricaAlgiers, + #[serde(rename = "africa/asmara")] + AfricaAsmara, + #[serde(rename = "africa/bamako")] + AfricaBamako, + #[serde(rename = "africa/bangui")] + AfricaBangui, + #[serde(rename = "africa/banjul")] + AfricaBanjul, + #[serde(rename = "africa/bissau")] + AfricaBissau, + #[serde(rename = "africa/blantyre")] + AfricaBlantyre, + #[serde(rename = "africa/brazzaville")] + AfricaBrazzaville, + #[serde(rename = "africa/bujumbura")] + AfricaBujumbura, + #[serde(rename = "africa/cairo")] + AfricaCairo, + #[serde(rename = "africa/casablanca")] + AfricaCasablanca, + #[serde(rename = "africa/ceuta")] + AfricaCeuta, + #[serde(rename = "africa/conakry")] + AfricaConakry, + #[serde(rename = "africa/dakar")] + AfricaDakar, + #[serde(rename = "africa/dar_es_salaam")] + AfricaDarEsSalaam, + #[serde(rename = "africa/djibouti")] + AfricaDjibouti, + #[serde(rename = "africa/douala")] + AfricaDouala, + #[serde(rename = "africa/el_aaiun")] + AfricaElAaiun, + #[serde(rename = "africa/freetown")] + AfricaFreetown, + #[serde(rename = "africa/gaborone")] + AfricaGaborone, + #[serde(rename = "africa/harare")] + AfricaHarare, + #[serde(rename = "africa/johannesburg")] + AfricaJohannesburg, + #[serde(rename = "africa/juba")] + AfricaJuba, + #[serde(rename = "africa/kampala")] + AfricaKampala, + #[serde(rename = "africa/khartoum")] + AfricaKhartoum, + #[serde(rename = "africa/kigali")] + AfricaKigali, + #[serde(rename = "africa/kinshasa")] + AfricaKinshasa, + #[serde(rename = "africa/lagos")] + AfricaLagos, + #[serde(rename = "africa/libreville")] + AfricaLibreville, + #[serde(rename = "africa/lome")] + AfricaLome, + #[serde(rename = "africa/luanda")] + AfricaLuanda, + #[serde(rename = "africa/lubumbashi")] + AfricaLubumbashi, + #[serde(rename = "africa/lusaka")] + AfricaLusaka, + #[serde(rename = "africa/malabo")] + AfricaMalabo, + #[serde(rename = "africa/maputo")] + AfricaMaputo, + #[serde(rename = "africa/maseru")] + AfricaMaseru, + #[serde(rename = "africa/mbabane")] + AfricaMbabane, + #[serde(rename = "africa/mogadishu")] + AfricaMogadishu, + #[serde(rename = "africa/monrovia")] + AfricaMonrovia, + #[serde(rename = "africa/nairobi")] + AfricaNairobi, + #[serde(rename = "africa/ndjamena")] + AfricaNdjamena, + #[serde(rename = "africa/niamey")] + AfricaNiamey, + #[serde(rename = "africa/nouakchott")] + AfricaNouakchott, + #[serde(rename = "africa/ouagadougou")] + AfricaOuagadougou, + #[serde(rename = "africa/porto-novo")] + AfricaPortoNovo, + #[serde(rename = "africa/sao_tome")] + AfricaSaoTome, + #[serde(rename = "africa/tripoli")] + AfricaTripoli, + #[serde(rename = "africa/tunis")] + AfricaTunis, + #[serde(rename = "africa/windhoek")] + AfricaWindhoek, + #[serde(rename = "america/adak")] + AmericaAdak, + #[serde(rename = "america/anchorage")] + AmericaAnchorage, + #[serde(rename = "america/anguilla")] + AmericaAnguilla, + #[serde(rename = "america/antigua")] + AmericaAntigua, + #[serde(rename = "america/araguaina")] + AmericaAraguaina, + #[serde(rename = "america/argentina/buenos_aires")] + AmericaArgentinaBuenosAires, + #[serde(rename = "america/argentina/catamarca")] + AmericaArgentinaCatamarca, + #[serde(rename = "america/argentina/cordoba")] + AmericaArgentinaCordoba, + #[serde(rename = "america/argentina/jujuy")] + AmericaArgentinaJujuy, + #[serde(rename = "america/argentina/la_rioja")] + AmericaArgentinaLaRioja, + #[serde(rename = "america/argentina/mendoza")] + AmericaArgentinaMendoza, + #[serde(rename = "america/argentina/rio_gallegos")] + AmericaArgentinaRioGallegos, + #[serde(rename = "america/argentina/salta")] + AmericaArgentinaSalta, + #[serde(rename = "america/argentina/san_juan")] + AmericaArgentinaSanJuan, + #[serde(rename = "america/argentina/san_luis")] + AmericaArgentinaSanLuis, + #[serde(rename = "america/argentina/tucuman")] + AmericaArgentinaTucuman, + #[serde(rename = "america/argentina/ushuaia")] + AmericaArgentinaUshuaia, + #[serde(rename = "america/aruba")] + AmericaAruba, + #[serde(rename = "america/asuncion")] + AmericaAsuncion, + #[serde(rename = "america/atikokan")] + AmericaAtikokan, + #[serde(rename = "america/bahia")] + AmericaBahia, + #[serde(rename = "america/bahia_banderas")] + AmericaBahiaBanderas, + #[serde(rename = "america/barbados")] + AmericaBarbados, + #[serde(rename = "america/belem")] + AmericaBelem, + #[serde(rename = "america/belize")] + AmericaBelize, + #[serde(rename = "america/blanc-sablon")] + AmericaBlancSablon, + #[serde(rename = "america/boa_vista")] + AmericaBoaVista, + #[serde(rename = "america/bogota")] + AmericaBogota, + #[serde(rename = "america/boise")] + AmericaBoise, + #[serde(rename = "america/cambridge_bay")] + AmericaCambridgeBay, + #[serde(rename = "america/campo_grande")] + AmericaCampoGrande, + #[serde(rename = "america/cancun")] + AmericaCancun, + #[serde(rename = "america/caracas")] + AmericaCaracas, + #[serde(rename = "america/cayenne")] + AmericaCayenne, + #[serde(rename = "america/cayman")] + AmericaCayman, + #[serde(rename = "america/chicago")] + AmericaChicago, + #[serde(rename = "america/chihuahua")] + AmericaChihuahua, + #[serde(rename = "america/ciudad_juarez")] + AmericaCiudadJuarez, + #[serde(rename = "america/costa_rica")] + AmericaCostaRica, + #[serde(rename = "america/coyhaique")] + AmericaCoyhaique, + #[serde(rename = "america/creston")] + AmericaCreston, + #[serde(rename = "america/cuiaba")] + AmericaCuiaba, + #[serde(rename = "america/curacao")] + AmericaCuracao, + #[serde(rename = "america/danmarkshavn")] + AmericaDanmarkshavn, + #[serde(rename = "america/dawson")] + AmericaDawson, + #[serde(rename = "america/dawson_creek")] + AmericaDawsonCreek, + #[serde(rename = "america/denver")] + AmericaDenver, + #[serde(rename = "america/detroit")] + AmericaDetroit, + #[serde(rename = "america/dominica")] + AmericaDominica, + #[serde(rename = "america/edmonton")] + AmericaEdmonton, + #[serde(rename = "america/eirunepe")] + AmericaEirunepe, + #[serde(rename = "america/el_salvador")] + AmericaElSalvador, + #[serde(rename = "america/fort_nelson")] + AmericaFortNelson, + #[serde(rename = "america/fortaleza")] + AmericaFortaleza, + #[serde(rename = "america/glace_bay")] + AmericaGlaceBay, + #[serde(rename = "america/goose_bay")] + AmericaGooseBay, + #[serde(rename = "america/grand_turk")] + AmericaGrandTurk, + #[serde(rename = "america/grenada")] + AmericaGrenada, + #[serde(rename = "america/guadeloupe")] + AmericaGuadeloupe, + #[serde(rename = "america/guatemala")] + AmericaGuatemala, + #[serde(rename = "america/guayaquil")] + AmericaGuayaquil, + #[serde(rename = "america/guyana")] + AmericaGuyana, + #[serde(rename = "america/halifax")] + AmericaHalifax, + #[serde(rename = "america/havana")] + AmericaHavana, + #[serde(rename = "america/hermosillo")] + AmericaHermosillo, + #[serde(rename = "america/indiana/indianapolis")] + AmericaIndianaIndianapolis, + #[serde(rename = "america/indiana/knox")] + AmericaIndianaKnox, + #[serde(rename = "america/indiana/marengo")] + AmericaIndianaMarengo, + #[serde(rename = "america/indiana/petersburg")] + AmericaIndianaPetersburg, + #[serde(rename = "america/indiana/tell_city")] + AmericaIndianaTellCity, + #[serde(rename = "america/indiana/vevay")] + AmericaIndianaVevay, + #[serde(rename = "america/indiana/vincennes")] + AmericaIndianaVincennes, + #[serde(rename = "america/indiana/winamac")] + AmericaIndianaWinamac, + #[serde(rename = "america/inuvik")] + AmericaInuvik, + #[serde(rename = "america/iqaluit")] + AmericaIqaluit, + #[serde(rename = "america/jamaica")] + AmericaJamaica, + #[serde(rename = "america/juneau")] + AmericaJuneau, + #[serde(rename = "america/kentucky/louisville")] + AmericaKentuckyLouisville, + #[serde(rename = "america/kentucky/monticello")] + AmericaKentuckyMonticello, + #[serde(rename = "america/kralendijk")] + AmericaKralendijk, + #[serde(rename = "america/la_paz")] + AmericaLaPaz, + #[serde(rename = "america/lima")] + AmericaLima, + #[serde(rename = "america/los_angeles")] + AmericaLosAngeles, + #[serde(rename = "america/lower_princes")] + AmericaLowerPrinces, + #[serde(rename = "america/maceio")] + AmericaMaceio, + #[serde(rename = "america/managua")] + AmericaManagua, + #[serde(rename = "america/manaus")] + AmericaManaus, + #[serde(rename = "america/marigot")] + AmericaMarigot, + #[serde(rename = "america/martinique")] + AmericaMartinique, + #[serde(rename = "america/matamoros")] + AmericaMatamoros, + #[serde(rename = "america/mazatlan")] + AmericaMazatlan, + #[serde(rename = "america/menominee")] + AmericaMenominee, + #[serde(rename = "america/merida")] + AmericaMerida, + #[serde(rename = "america/metlakatla")] + AmericaMetlakatla, + #[serde(rename = "america/mexico_city")] + AmericaMexicoCity, + #[serde(rename = "america/miquelon")] + AmericaMiquelon, + #[serde(rename = "america/moncton")] + AmericaMoncton, + #[serde(rename = "america/monterrey")] + AmericaMonterrey, + #[serde(rename = "america/montevideo")] + AmericaMontevideo, + #[serde(rename = "america/montserrat")] + AmericaMontserrat, + #[serde(rename = "america/nassau")] + AmericaNassau, + #[serde(rename = "america/new_york")] + AmericaNewYork, + #[serde(rename = "america/nome")] + AmericaNome, + #[serde(rename = "america/noronha")] + AmericaNoronha, + #[serde(rename = "america/north_dakota/beulah")] + AmericaNorthDakotaBeulah, + #[serde(rename = "america/north_dakota/center")] + AmericaNorthDakotaCenter, + #[serde(rename = "america/north_dakota/new_salem")] + AmericaNorthDakotaNewSalem, + #[serde(rename = "america/nuuk")] + AmericaNuuk, + #[serde(rename = "america/ojinaga")] + AmericaOjinaga, + #[serde(rename = "america/panama")] + AmericaPanama, + #[serde(rename = "america/paramaribo")] + AmericaParamaribo, + #[serde(rename = "america/phoenix")] + AmericaPhoenix, + #[serde(rename = "america/port-au-prince")] + AmericaPortAuPrince, + #[serde(rename = "america/port_of_spain")] + AmericaPortOfSpain, + #[serde(rename = "america/porto_velho")] + AmericaPortoVelho, + #[serde(rename = "america/puerto_rico")] + AmericaPuertoRico, + #[serde(rename = "america/punta_arenas")] + AmericaPuntaArenas, + #[serde(rename = "america/rankin_inlet")] + AmericaRankinInlet, + #[serde(rename = "america/recife")] + AmericaRecife, + #[serde(rename = "america/regina")] + AmericaRegina, + #[serde(rename = "america/resolute")] + AmericaResolute, + #[serde(rename = "america/rio_branco")] + AmericaRioBranco, + #[serde(rename = "america/santarem")] + AmericaSantarem, + #[serde(rename = "america/santiago")] + AmericaSantiago, + #[serde(rename = "america/santo_domingo")] + AmericaSantoDomingo, + #[serde(rename = "america/sao_paulo")] + AmericaSaoPaulo, + #[serde(rename = "america/scoresbysund")] + AmericaScoresbysund, + #[serde(rename = "america/sitka")] + AmericaSitka, + #[serde(rename = "america/st_barthelemy")] + AmericaStBarthelemy, + #[serde(rename = "america/st_johns")] + AmericaStJohns, + #[serde(rename = "america/st_kitts")] + AmericaStKitts, + #[serde(rename = "america/st_lucia")] + AmericaStLucia, + #[serde(rename = "america/st_thomas")] + AmericaStThomas, + #[serde(rename = "america/st_vincent")] + AmericaStVincent, + #[serde(rename = "america/swift_current")] + AmericaSwiftCurrent, + #[serde(rename = "america/tegucigalpa")] + AmericaTegucigalpa, + #[serde(rename = "america/thule")] + AmericaThule, + #[serde(rename = "america/tijuana")] + AmericaTijuana, + #[serde(rename = "america/toronto")] + AmericaToronto, + #[serde(rename = "america/tortola")] + AmericaTortola, + #[serde(rename = "america/vancouver")] + AmericaVancouver, + #[serde(rename = "america/whitehorse")] + AmericaWhitehorse, + #[serde(rename = "america/winnipeg")] + AmericaWinnipeg, + #[serde(rename = "america/yakutat")] + AmericaYakutat, + #[serde(rename = "antarctica/casey")] + AntarcticaCasey, + #[serde(rename = "antarctica/davis")] + AntarcticaDavis, + #[serde(rename = "antarctica/dumontdurville")] + AntarcticaDumontdurville, + #[serde(rename = "antarctica/macquarie")] + AntarcticaMacquarie, + #[serde(rename = "antarctica/mawson")] + AntarcticaMawson, + #[serde(rename = "antarctica/mcmurdo")] + AntarcticaMcmurdo, + #[serde(rename = "antarctica/palmer")] + AntarcticaPalmer, + #[serde(rename = "antarctica/rothera")] + AntarcticaRothera, + #[serde(rename = "antarctica/syowa")] + AntarcticaSyowa, + #[serde(rename = "antarctica/troll")] + AntarcticaTroll, + #[serde(rename = "antarctica/vostok")] + AntarcticaVostok, + #[serde(rename = "arctic/longyearbyen")] + ArcticLongyearbyen, + #[serde(rename = "asia/aden")] + AsiaAden, + #[serde(rename = "asia/almaty")] + AsiaAlmaty, + #[serde(rename = "asia/amman")] + AsiaAmman, + #[serde(rename = "asia/anadyr")] + AsiaAnadyr, + #[serde(rename = "asia/aqtau")] + AsiaAqtau, + #[serde(rename = "asia/aqtobe")] + AsiaAqtobe, + #[serde(rename = "asia/ashgabat")] + AsiaAshgabat, + #[serde(rename = "asia/atyrau")] + AsiaAtyrau, + #[serde(rename = "asia/baghdad")] + AsiaBaghdad, + #[serde(rename = "asia/bahrain")] + AsiaBahrain, + #[serde(rename = "asia/baku")] + AsiaBaku, + #[serde(rename = "asia/bangkok")] + AsiaBangkok, + #[serde(rename = "asia/barnaul")] + AsiaBarnaul, + #[serde(rename = "asia/beirut")] + AsiaBeirut, + #[serde(rename = "asia/bishkek")] + AsiaBishkek, + #[serde(rename = "asia/brunei")] + AsiaBrunei, + #[serde(rename = "asia/chita")] + AsiaChita, + #[serde(rename = "asia/colombo")] + AsiaColombo, + #[serde(rename = "asia/damascus")] + AsiaDamascus, + #[serde(rename = "asia/dhaka")] + AsiaDhaka, + #[serde(rename = "asia/dili")] + AsiaDili, + #[serde(rename = "asia/dubai")] + AsiaDubai, + #[serde(rename = "asia/dushanbe")] + AsiaDushanbe, + #[serde(rename = "asia/famagusta")] + AsiaFamagusta, + #[serde(rename = "asia/gaza")] + AsiaGaza, + #[serde(rename = "asia/hebron")] + AsiaHebron, + #[serde(rename = "asia/ho_chi_minh")] + AsiaHoChiMinh, + #[serde(rename = "asia/hong_kong")] + AsiaHongKong, + #[serde(rename = "asia/hovd")] + AsiaHovd, + #[serde(rename = "asia/irkutsk")] + AsiaIrkutsk, + #[serde(rename = "asia/jakarta")] + AsiaJakarta, + #[serde(rename = "asia/jayapura")] + AsiaJayapura, + #[serde(rename = "asia/jerusalem")] + AsiaJerusalem, + #[serde(rename = "asia/kabul")] + AsiaKabul, + #[serde(rename = "asia/kamchatka")] + AsiaKamchatka, + #[serde(rename = "asia/karachi")] + AsiaKarachi, + #[serde(rename = "asia/kathmandu")] + AsiaKathmandu, + #[serde(rename = "asia/khandyga")] + AsiaKhandyga, + #[serde(rename = "asia/kolkata")] + AsiaKolkata, + #[serde(rename = "asia/krasnoyarsk")] + AsiaKrasnoyarsk, + #[serde(rename = "asia/kuala_lumpur")] + AsiaKualaLumpur, + #[serde(rename = "asia/kuching")] + AsiaKuching, + #[serde(rename = "asia/kuwait")] + AsiaKuwait, + #[serde(rename = "asia/macau")] + AsiaMacau, + #[serde(rename = "asia/magadan")] + AsiaMagadan, + #[serde(rename = "asia/makassar")] + AsiaMakassar, + #[serde(rename = "asia/manila")] + AsiaManila, + #[serde(rename = "asia/muscat")] + AsiaMuscat, + #[serde(rename = "asia/nicosia")] + AsiaNicosia, + #[serde(rename = "asia/novokuznetsk")] + AsiaNovokuznetsk, + #[serde(rename = "asia/novosibirsk")] + AsiaNovosibirsk, + #[serde(rename = "asia/omsk")] + AsiaOmsk, + #[serde(rename = "asia/oral")] + AsiaOral, + #[serde(rename = "asia/phnom_penh")] + AsiaPhnomPenh, + #[serde(rename = "asia/pontianak")] + AsiaPontianak, + #[serde(rename = "asia/pyongyang")] + AsiaPyongyang, + #[serde(rename = "asia/qatar")] + AsiaQatar, + #[serde(rename = "asia/qostanay")] + AsiaQostanay, + #[serde(rename = "asia/qyzylorda")] + AsiaQyzylorda, + #[serde(rename = "asia/riyadh")] + AsiaRiyadh, + #[serde(rename = "asia/sakhalin")] + AsiaSakhalin, + #[serde(rename = "asia/samarkand")] + AsiaSamarkand, + #[serde(rename = "asia/seoul")] + AsiaSeoul, + #[serde(rename = "asia/shanghai")] + AsiaShanghai, + #[serde(rename = "asia/singapore")] + AsiaSingapore, + #[serde(rename = "asia/srednekolymsk")] + AsiaSrednekolymsk, + #[serde(rename = "asia/taipei")] + AsiaTaipei, + #[serde(rename = "asia/tashkent")] + AsiaTashkent, + #[serde(rename = "asia/tbilisi")] + AsiaTbilisi, + #[serde(rename = "asia/tehran")] + AsiaTehran, + #[serde(rename = "asia/thimphu")] + AsiaThimphu, + #[serde(rename = "asia/tokyo")] + AsiaTokyo, + #[serde(rename = "asia/tomsk")] + AsiaTomsk, + #[serde(rename = "asia/ulaanbaatar")] + AsiaUlaanbaatar, + #[serde(rename = "asia/urumqi")] + AsiaUrumqi, + #[serde(rename = "asia/ust-nera")] + AsiaUstNera, + #[serde(rename = "asia/vientiane")] + AsiaVientiane, + #[serde(rename = "asia/vladivostok")] + AsiaVladivostok, + #[serde(rename = "asia/yakutsk")] + AsiaYakutsk, + #[serde(rename = "asia/yangon")] + AsiaYangon, + #[serde(rename = "asia/yekaterinburg")] + AsiaYekaterinburg, + #[serde(rename = "asia/yerevan")] + AsiaYerevan, + #[serde(rename = "atlantic/azores")] + AtlanticAzores, + #[serde(rename = "atlantic/bermuda")] + AtlanticBermuda, + #[serde(rename = "atlantic/canary")] + AtlanticCanary, + #[serde(rename = "atlantic/cape_verde")] + AtlanticCapeVerde, + #[serde(rename = "atlantic/faroe")] + AtlanticFaroe, + #[serde(rename = "atlantic/madeira")] + AtlanticMadeira, + #[serde(rename = "atlantic/reykjavik")] + AtlanticReykjavik, + #[serde(rename = "atlantic/south_georgia")] + AtlanticSouthGeorgia, + #[serde(rename = "atlantic/st_helena")] + AtlanticStHelena, + #[serde(rename = "atlantic/stanley")] + AtlanticStanley, + #[serde(rename = "australia/adelaide")] + AustraliaAdelaide, + #[serde(rename = "australia/brisbane")] + AustraliaBrisbane, + #[serde(rename = "australia/broken_hill")] + AustraliaBrokenHill, + #[serde(rename = "australia/darwin")] + AustraliaDarwin, + #[serde(rename = "australia/eucla")] + AustraliaEucla, + #[serde(rename = "australia/hobart")] + AustraliaHobart, + #[serde(rename = "australia/lindeman")] + AustraliaLindeman, + #[serde(rename = "australia/lord_howe")] + AustraliaLordHowe, + #[serde(rename = "australia/melbourne")] + AustraliaMelbourne, + #[serde(rename = "australia/perth")] + AustraliaPerth, + #[serde(rename = "australia/sydney")] + AustraliaSydney, + #[serde(rename = "europe/amsterdam")] + EuropeAmsterdam, + #[serde(rename = "europe/andorra")] + EuropeAndorra, + #[serde(rename = "europe/astrakhan")] + EuropeAstrakhan, + #[serde(rename = "europe/athens")] + EuropeAthens, + #[serde(rename = "europe/belgrade")] + EuropeBelgrade, + #[serde(rename = "europe/berlin")] + EuropeBerlin, + #[serde(rename = "europe/bratislava")] + EuropeBratislava, + #[serde(rename = "europe/brussels")] + EuropeBrussels, + #[serde(rename = "europe/bucharest")] + EuropeBucharest, + #[serde(rename = "europe/budapest")] + EuropeBudapest, + #[serde(rename = "europe/busingen")] + EuropeBusingen, + #[serde(rename = "europe/chisinau")] + EuropeChisinau, + #[serde(rename = "europe/copenhagen")] + EuropeCopenhagen, + #[serde(rename = "europe/dublin")] + EuropeDublin, + #[serde(rename = "europe/gibraltar")] + EuropeGibraltar, + #[serde(rename = "europe/guernsey")] + EuropeGuernsey, + #[serde(rename = "europe/helsinki")] + EuropeHelsinki, + #[serde(rename = "europe/isle_of_man")] + EuropeIsleOfMan, + #[serde(rename = "europe/istanbul")] + EuropeIstanbul, + #[serde(rename = "europe/jersey")] + EuropeJersey, + #[serde(rename = "europe/kaliningrad")] + EuropeKaliningrad, + #[serde(rename = "europe/kirov")] + EuropeKirov, + #[serde(rename = "europe/kyiv")] + EuropeKyiv, + #[serde(rename = "europe/lisbon")] + EuropeLisbon, + #[serde(rename = "europe/ljubljana")] + EuropeLjubljana, + #[serde(rename = "europe/london")] + EuropeLondon, + #[serde(rename = "europe/luxembourg")] + EuropeLuxembourg, + #[serde(rename = "europe/madrid")] + EuropeMadrid, + #[serde(rename = "europe/malta")] + EuropeMalta, + #[serde(rename = "europe/mariehamn")] + EuropeMariehamn, + #[serde(rename = "europe/minsk")] + EuropeMinsk, + #[serde(rename = "europe/monaco")] + EuropeMonaco, + #[serde(rename = "europe/moscow")] + EuropeMoscow, + #[serde(rename = "europe/oslo")] + EuropeOslo, + #[serde(rename = "europe/paris")] + EuropeParis, + #[serde(rename = "europe/podgorica")] + EuropePodgorica, + #[serde(rename = "europe/prague")] + EuropePrague, + #[serde(rename = "europe/riga")] + EuropeRiga, + #[serde(rename = "europe/rome")] + EuropeRome, + #[serde(rename = "europe/samara")] + EuropeSamara, + #[serde(rename = "europe/san_marino")] + EuropeSanMarino, + #[serde(rename = "europe/sarajevo")] + EuropeSarajevo, + #[serde(rename = "europe/saratov")] + EuropeSaratov, + #[serde(rename = "europe/simferopol")] + EuropeSimferopol, + #[serde(rename = "europe/skopje")] + EuropeSkopje, + #[serde(rename = "europe/sofia")] + EuropeSofia, + #[serde(rename = "europe/stockholm")] + EuropeStockholm, + #[serde(rename = "europe/tallinn")] + EuropeTallinn, + #[serde(rename = "europe/tirane")] + EuropeTirane, + #[serde(rename = "europe/ulyanovsk")] + EuropeUlyanovsk, + #[serde(rename = "europe/vaduz")] + EuropeVaduz, + #[serde(rename = "europe/vatican")] + EuropeVatican, + #[serde(rename = "europe/vienna")] + EuropeVienna, + #[serde(rename = "europe/vilnius")] + EuropeVilnius, + #[serde(rename = "europe/volgograd")] + EuropeVolgograd, + #[serde(rename = "europe/warsaw")] + EuropeWarsaw, + #[serde(rename = "europe/zagreb")] + EuropeZagreb, + #[serde(rename = "europe/zurich")] + EuropeZurich, + #[serde(rename = "indian/antananarivo")] + IndianAntananarivo, + #[serde(rename = "indian/chagos")] + IndianChagos, + #[serde(rename = "indian/christmas")] + IndianChristmas, + #[serde(rename = "indian/cocos")] + IndianCocos, + #[serde(rename = "indian/comoro")] + IndianComoro, + #[serde(rename = "indian/kerguelen")] + IndianKerguelen, + #[serde(rename = "indian/mahe")] + IndianMahe, + #[serde(rename = "indian/maldives")] + IndianMaldives, + #[serde(rename = "indian/mauritius")] + IndianMauritius, + #[serde(rename = "indian/mayotte")] + IndianMayotte, + #[serde(rename = "indian/reunion")] + IndianReunion, + #[serde(rename = "pacific/apia")] + PacificApia, + #[serde(rename = "pacific/auckland")] + PacificAuckland, + #[serde(rename = "pacific/bougainville")] + PacificBougainville, + #[serde(rename = "pacific/chatham")] + PacificChatham, + #[serde(rename = "pacific/chuuk")] + PacificChuuk, + #[serde(rename = "pacific/easter")] + PacificEaster, + #[serde(rename = "pacific/efate")] + PacificEfate, + #[serde(rename = "pacific/fakaofo")] + PacificFakaofo, + #[serde(rename = "pacific/fiji")] + PacificFiji, + #[serde(rename = "pacific/funafuti")] + PacificFunafuti, + #[serde(rename = "pacific/galapagos")] + PacificGalapagos, + #[serde(rename = "pacific/gambier")] + PacificGambier, + #[serde(rename = "pacific/guadalcanal")] + PacificGuadalcanal, + #[serde(rename = "pacific/guam")] + PacificGuam, + #[serde(rename = "pacific/honolulu")] + PacificHonolulu, + #[serde(rename = "pacific/kanton")] + PacificKanton, + #[serde(rename = "pacific/kiritimati")] + PacificKiritimati, + #[serde(rename = "pacific/kosrae")] + PacificKosrae, + #[serde(rename = "pacific/kwajalein")] + PacificKwajalein, + #[serde(rename = "pacific/majuro")] + PacificMajuro, + #[serde(rename = "pacific/marquesas")] + PacificMarquesas, + #[serde(rename = "pacific/midway")] + PacificMidway, + #[serde(rename = "pacific/nauru")] + PacificNauru, + #[serde(rename = "pacific/niue")] + PacificNiue, + #[serde(rename = "pacific/norfolk")] + PacificNorfolk, + #[serde(rename = "pacific/noumea")] + PacificNoumea, + #[serde(rename = "pacific/pago_pago")] + PacificPagoPago, + #[serde(rename = "pacific/palau")] + PacificPalau, + #[serde(rename = "pacific/pitcairn")] + PacificPitcairn, + #[serde(rename = "pacific/pohnpei")] + PacificPohnpei, + #[serde(rename = "pacific/port_moresby")] + PacificPortMoresby, + #[serde(rename = "pacific/rarotonga")] + PacificRarotonga, + #[serde(rename = "pacific/saipan")] + PacificSaipan, + #[serde(rename = "pacific/tahiti")] + PacificTahiti, + #[serde(rename = "pacific/tarawa")] + PacificTarawa, + #[serde(rename = "pacific/tongatapu")] + PacificTongatapu, + #[serde(rename = "pacific/wake")] + PacificWake, + #[serde(rename = "pacific/wallis")] + PacificWallis, + #[serde(rename = "utc")] + Utc, +} + +impl Timezone { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + Timezone::AfricaAbidjan => "africa/abidjan", + Timezone::AfricaAccra => "africa/accra", + Timezone::AfricaAddisAbaba => "africa/addis_ababa", + Timezone::AfricaAlgiers => "africa/algiers", + Timezone::AfricaAsmara => "africa/asmara", + Timezone::AfricaBamako => "africa/bamako", + Timezone::AfricaBangui => "africa/bangui", + Timezone::AfricaBanjul => "africa/banjul", + Timezone::AfricaBissau => "africa/bissau", + Timezone::AfricaBlantyre => "africa/blantyre", + Timezone::AfricaBrazzaville => "africa/brazzaville", + Timezone::AfricaBujumbura => "africa/bujumbura", + Timezone::AfricaCairo => "africa/cairo", + Timezone::AfricaCasablanca => "africa/casablanca", + Timezone::AfricaCeuta => "africa/ceuta", + Timezone::AfricaConakry => "africa/conakry", + Timezone::AfricaDakar => "africa/dakar", + Timezone::AfricaDarEsSalaam => "africa/dar_es_salaam", + Timezone::AfricaDjibouti => "africa/djibouti", + Timezone::AfricaDouala => "africa/douala", + Timezone::AfricaElAaiun => "africa/el_aaiun", + Timezone::AfricaFreetown => "africa/freetown", + Timezone::AfricaGaborone => "africa/gaborone", + Timezone::AfricaHarare => "africa/harare", + Timezone::AfricaJohannesburg => "africa/johannesburg", + Timezone::AfricaJuba => "africa/juba", + Timezone::AfricaKampala => "africa/kampala", + Timezone::AfricaKhartoum => "africa/khartoum", + Timezone::AfricaKigali => "africa/kigali", + Timezone::AfricaKinshasa => "africa/kinshasa", + Timezone::AfricaLagos => "africa/lagos", + Timezone::AfricaLibreville => "africa/libreville", + Timezone::AfricaLome => "africa/lome", + Timezone::AfricaLuanda => "africa/luanda", + Timezone::AfricaLubumbashi => "africa/lubumbashi", + Timezone::AfricaLusaka => "africa/lusaka", + Timezone::AfricaMalabo => "africa/malabo", + Timezone::AfricaMaputo => "africa/maputo", + Timezone::AfricaMaseru => "africa/maseru", + Timezone::AfricaMbabane => "africa/mbabane", + Timezone::AfricaMogadishu => "africa/mogadishu", + Timezone::AfricaMonrovia => "africa/monrovia", + Timezone::AfricaNairobi => "africa/nairobi", + Timezone::AfricaNdjamena => "africa/ndjamena", + Timezone::AfricaNiamey => "africa/niamey", + Timezone::AfricaNouakchott => "africa/nouakchott", + Timezone::AfricaOuagadougou => "africa/ouagadougou", + Timezone::AfricaPortoNovo => "africa/porto-novo", + Timezone::AfricaSaoTome => "africa/sao_tome", + Timezone::AfricaTripoli => "africa/tripoli", + Timezone::AfricaTunis => "africa/tunis", + Timezone::AfricaWindhoek => "africa/windhoek", + Timezone::AmericaAdak => "america/adak", + Timezone::AmericaAnchorage => "america/anchorage", + Timezone::AmericaAnguilla => "america/anguilla", + Timezone::AmericaAntigua => "america/antigua", + Timezone::AmericaAraguaina => "america/araguaina", + Timezone::AmericaArgentinaBuenosAires => "america/argentina/buenos_aires", + Timezone::AmericaArgentinaCatamarca => "america/argentina/catamarca", + Timezone::AmericaArgentinaCordoba => "america/argentina/cordoba", + Timezone::AmericaArgentinaJujuy => "america/argentina/jujuy", + Timezone::AmericaArgentinaLaRioja => "america/argentina/la_rioja", + Timezone::AmericaArgentinaMendoza => "america/argentina/mendoza", + Timezone::AmericaArgentinaRioGallegos => "america/argentina/rio_gallegos", + Timezone::AmericaArgentinaSalta => "america/argentina/salta", + Timezone::AmericaArgentinaSanJuan => "america/argentina/san_juan", + Timezone::AmericaArgentinaSanLuis => "america/argentina/san_luis", + Timezone::AmericaArgentinaTucuman => "america/argentina/tucuman", + Timezone::AmericaArgentinaUshuaia => "america/argentina/ushuaia", + Timezone::AmericaAruba => "america/aruba", + Timezone::AmericaAsuncion => "america/asuncion", + Timezone::AmericaAtikokan => "america/atikokan", + Timezone::AmericaBahia => "america/bahia", + Timezone::AmericaBahiaBanderas => "america/bahia_banderas", + Timezone::AmericaBarbados => "america/barbados", + Timezone::AmericaBelem => "america/belem", + Timezone::AmericaBelize => "america/belize", + Timezone::AmericaBlancSablon => "america/blanc-sablon", + Timezone::AmericaBoaVista => "america/boa_vista", + Timezone::AmericaBogota => "america/bogota", + Timezone::AmericaBoise => "america/boise", + Timezone::AmericaCambridgeBay => "america/cambridge_bay", + Timezone::AmericaCampoGrande => "america/campo_grande", + Timezone::AmericaCancun => "america/cancun", + Timezone::AmericaCaracas => "america/caracas", + Timezone::AmericaCayenne => "america/cayenne", + Timezone::AmericaCayman => "america/cayman", + Timezone::AmericaChicago => "america/chicago", + Timezone::AmericaChihuahua => "america/chihuahua", + Timezone::AmericaCiudadJuarez => "america/ciudad_juarez", + Timezone::AmericaCostaRica => "america/costa_rica", + Timezone::AmericaCoyhaique => "america/coyhaique", + Timezone::AmericaCreston => "america/creston", + Timezone::AmericaCuiaba => "america/cuiaba", + Timezone::AmericaCuracao => "america/curacao", + Timezone::AmericaDanmarkshavn => "america/danmarkshavn", + Timezone::AmericaDawson => "america/dawson", + Timezone::AmericaDawsonCreek => "america/dawson_creek", + Timezone::AmericaDenver => "america/denver", + Timezone::AmericaDetroit => "america/detroit", + Timezone::AmericaDominica => "america/dominica", + Timezone::AmericaEdmonton => "america/edmonton", + Timezone::AmericaEirunepe => "america/eirunepe", + Timezone::AmericaElSalvador => "america/el_salvador", + Timezone::AmericaFortNelson => "america/fort_nelson", + Timezone::AmericaFortaleza => "america/fortaleza", + Timezone::AmericaGlaceBay => "america/glace_bay", + Timezone::AmericaGooseBay => "america/goose_bay", + Timezone::AmericaGrandTurk => "america/grand_turk", + Timezone::AmericaGrenada => "america/grenada", + Timezone::AmericaGuadeloupe => "america/guadeloupe", + Timezone::AmericaGuatemala => "america/guatemala", + Timezone::AmericaGuayaquil => "america/guayaquil", + Timezone::AmericaGuyana => "america/guyana", + Timezone::AmericaHalifax => "america/halifax", + Timezone::AmericaHavana => "america/havana", + Timezone::AmericaHermosillo => "america/hermosillo", + Timezone::AmericaIndianaIndianapolis => "america/indiana/indianapolis", + Timezone::AmericaIndianaKnox => "america/indiana/knox", + Timezone::AmericaIndianaMarengo => "america/indiana/marengo", + Timezone::AmericaIndianaPetersburg => "america/indiana/petersburg", + Timezone::AmericaIndianaTellCity => "america/indiana/tell_city", + Timezone::AmericaIndianaVevay => "america/indiana/vevay", + Timezone::AmericaIndianaVincennes => "america/indiana/vincennes", + Timezone::AmericaIndianaWinamac => "america/indiana/winamac", + Timezone::AmericaInuvik => "america/inuvik", + Timezone::AmericaIqaluit => "america/iqaluit", + Timezone::AmericaJamaica => "america/jamaica", + Timezone::AmericaJuneau => "america/juneau", + Timezone::AmericaKentuckyLouisville => "america/kentucky/louisville", + Timezone::AmericaKentuckyMonticello => "america/kentucky/monticello", + Timezone::AmericaKralendijk => "america/kralendijk", + Timezone::AmericaLaPaz => "america/la_paz", + Timezone::AmericaLima => "america/lima", + Timezone::AmericaLosAngeles => "america/los_angeles", + Timezone::AmericaLowerPrinces => "america/lower_princes", + Timezone::AmericaMaceio => "america/maceio", + Timezone::AmericaManagua => "america/managua", + Timezone::AmericaManaus => "america/manaus", + Timezone::AmericaMarigot => "america/marigot", + Timezone::AmericaMartinique => "america/martinique", + Timezone::AmericaMatamoros => "america/matamoros", + Timezone::AmericaMazatlan => "america/mazatlan", + Timezone::AmericaMenominee => "america/menominee", + Timezone::AmericaMerida => "america/merida", + Timezone::AmericaMetlakatla => "america/metlakatla", + Timezone::AmericaMexicoCity => "america/mexico_city", + Timezone::AmericaMiquelon => "america/miquelon", + Timezone::AmericaMoncton => "america/moncton", + Timezone::AmericaMonterrey => "america/monterrey", + Timezone::AmericaMontevideo => "america/montevideo", + Timezone::AmericaMontserrat => "america/montserrat", + Timezone::AmericaNassau => "america/nassau", + Timezone::AmericaNewYork => "america/new_york", + Timezone::AmericaNome => "america/nome", + Timezone::AmericaNoronha => "america/noronha", + Timezone::AmericaNorthDakotaBeulah => "america/north_dakota/beulah", + Timezone::AmericaNorthDakotaCenter => "america/north_dakota/center", + Timezone::AmericaNorthDakotaNewSalem => "america/north_dakota/new_salem", + Timezone::AmericaNuuk => "america/nuuk", + Timezone::AmericaOjinaga => "america/ojinaga", + Timezone::AmericaPanama => "america/panama", + Timezone::AmericaParamaribo => "america/paramaribo", + Timezone::AmericaPhoenix => "america/phoenix", + Timezone::AmericaPortAuPrince => "america/port-au-prince", + Timezone::AmericaPortOfSpain => "america/port_of_spain", + Timezone::AmericaPortoVelho => "america/porto_velho", + Timezone::AmericaPuertoRico => "america/puerto_rico", + Timezone::AmericaPuntaArenas => "america/punta_arenas", + Timezone::AmericaRankinInlet => "america/rankin_inlet", + Timezone::AmericaRecife => "america/recife", + Timezone::AmericaRegina => "america/regina", + Timezone::AmericaResolute => "america/resolute", + Timezone::AmericaRioBranco => "america/rio_branco", + Timezone::AmericaSantarem => "america/santarem", + Timezone::AmericaSantiago => "america/santiago", + Timezone::AmericaSantoDomingo => "america/santo_domingo", + Timezone::AmericaSaoPaulo => "america/sao_paulo", + Timezone::AmericaScoresbysund => "america/scoresbysund", + Timezone::AmericaSitka => "america/sitka", + Timezone::AmericaStBarthelemy => "america/st_barthelemy", + Timezone::AmericaStJohns => "america/st_johns", + Timezone::AmericaStKitts => "america/st_kitts", + Timezone::AmericaStLucia => "america/st_lucia", + Timezone::AmericaStThomas => "america/st_thomas", + Timezone::AmericaStVincent => "america/st_vincent", + Timezone::AmericaSwiftCurrent => "america/swift_current", + Timezone::AmericaTegucigalpa => "america/tegucigalpa", + Timezone::AmericaThule => "america/thule", + Timezone::AmericaTijuana => "america/tijuana", + Timezone::AmericaToronto => "america/toronto", + Timezone::AmericaTortola => "america/tortola", + Timezone::AmericaVancouver => "america/vancouver", + Timezone::AmericaWhitehorse => "america/whitehorse", + Timezone::AmericaWinnipeg => "america/winnipeg", + Timezone::AmericaYakutat => "america/yakutat", + Timezone::AntarcticaCasey => "antarctica/casey", + Timezone::AntarcticaDavis => "antarctica/davis", + Timezone::AntarcticaDumontdurville => "antarctica/dumontdurville", + Timezone::AntarcticaMacquarie => "antarctica/macquarie", + Timezone::AntarcticaMawson => "antarctica/mawson", + Timezone::AntarcticaMcmurdo => "antarctica/mcmurdo", + Timezone::AntarcticaPalmer => "antarctica/palmer", + Timezone::AntarcticaRothera => "antarctica/rothera", + Timezone::AntarcticaSyowa => "antarctica/syowa", + Timezone::AntarcticaTroll => "antarctica/troll", + Timezone::AntarcticaVostok => "antarctica/vostok", + Timezone::ArcticLongyearbyen => "arctic/longyearbyen", + Timezone::AsiaAden => "asia/aden", + Timezone::AsiaAlmaty => "asia/almaty", + Timezone::AsiaAmman => "asia/amman", + Timezone::AsiaAnadyr => "asia/anadyr", + Timezone::AsiaAqtau => "asia/aqtau", + Timezone::AsiaAqtobe => "asia/aqtobe", + Timezone::AsiaAshgabat => "asia/ashgabat", + Timezone::AsiaAtyrau => "asia/atyrau", + Timezone::AsiaBaghdad => "asia/baghdad", + Timezone::AsiaBahrain => "asia/bahrain", + Timezone::AsiaBaku => "asia/baku", + Timezone::AsiaBangkok => "asia/bangkok", + Timezone::AsiaBarnaul => "asia/barnaul", + Timezone::AsiaBeirut => "asia/beirut", + Timezone::AsiaBishkek => "asia/bishkek", + Timezone::AsiaBrunei => "asia/brunei", + Timezone::AsiaChita => "asia/chita", + Timezone::AsiaColombo => "asia/colombo", + Timezone::AsiaDamascus => "asia/damascus", + Timezone::AsiaDhaka => "asia/dhaka", + Timezone::AsiaDili => "asia/dili", + Timezone::AsiaDubai => "asia/dubai", + Timezone::AsiaDushanbe => "asia/dushanbe", + Timezone::AsiaFamagusta => "asia/famagusta", + Timezone::AsiaGaza => "asia/gaza", + Timezone::AsiaHebron => "asia/hebron", + Timezone::AsiaHoChiMinh => "asia/ho_chi_minh", + Timezone::AsiaHongKong => "asia/hong_kong", + Timezone::AsiaHovd => "asia/hovd", + Timezone::AsiaIrkutsk => "asia/irkutsk", + Timezone::AsiaJakarta => "asia/jakarta", + Timezone::AsiaJayapura => "asia/jayapura", + Timezone::AsiaJerusalem => "asia/jerusalem", + Timezone::AsiaKabul => "asia/kabul", + Timezone::AsiaKamchatka => "asia/kamchatka", + Timezone::AsiaKarachi => "asia/karachi", + Timezone::AsiaKathmandu => "asia/kathmandu", + Timezone::AsiaKhandyga => "asia/khandyga", + Timezone::AsiaKolkata => "asia/kolkata", + Timezone::AsiaKrasnoyarsk => "asia/krasnoyarsk", + Timezone::AsiaKualaLumpur => "asia/kuala_lumpur", + Timezone::AsiaKuching => "asia/kuching", + Timezone::AsiaKuwait => "asia/kuwait", + Timezone::AsiaMacau => "asia/macau", + Timezone::AsiaMagadan => "asia/magadan", + Timezone::AsiaMakassar => "asia/makassar", + Timezone::AsiaManila => "asia/manila", + Timezone::AsiaMuscat => "asia/muscat", + Timezone::AsiaNicosia => "asia/nicosia", + Timezone::AsiaNovokuznetsk => "asia/novokuznetsk", + Timezone::AsiaNovosibirsk => "asia/novosibirsk", + Timezone::AsiaOmsk => "asia/omsk", + Timezone::AsiaOral => "asia/oral", + Timezone::AsiaPhnomPenh => "asia/phnom_penh", + Timezone::AsiaPontianak => "asia/pontianak", + Timezone::AsiaPyongyang => "asia/pyongyang", + Timezone::AsiaQatar => "asia/qatar", + Timezone::AsiaQostanay => "asia/qostanay", + Timezone::AsiaQyzylorda => "asia/qyzylorda", + Timezone::AsiaRiyadh => "asia/riyadh", + Timezone::AsiaSakhalin => "asia/sakhalin", + Timezone::AsiaSamarkand => "asia/samarkand", + Timezone::AsiaSeoul => "asia/seoul", + Timezone::AsiaShanghai => "asia/shanghai", + Timezone::AsiaSingapore => "asia/singapore", + Timezone::AsiaSrednekolymsk => "asia/srednekolymsk", + Timezone::AsiaTaipei => "asia/taipei", + Timezone::AsiaTashkent => "asia/tashkent", + Timezone::AsiaTbilisi => "asia/tbilisi", + Timezone::AsiaTehran => "asia/tehran", + Timezone::AsiaThimphu => "asia/thimphu", + Timezone::AsiaTokyo => "asia/tokyo", + Timezone::AsiaTomsk => "asia/tomsk", + Timezone::AsiaUlaanbaatar => "asia/ulaanbaatar", + Timezone::AsiaUrumqi => "asia/urumqi", + Timezone::AsiaUstNera => "asia/ust-nera", + Timezone::AsiaVientiane => "asia/vientiane", + Timezone::AsiaVladivostok => "asia/vladivostok", + Timezone::AsiaYakutsk => "asia/yakutsk", + Timezone::AsiaYangon => "asia/yangon", + Timezone::AsiaYekaterinburg => "asia/yekaterinburg", + Timezone::AsiaYerevan => "asia/yerevan", + Timezone::AtlanticAzores => "atlantic/azores", + Timezone::AtlanticBermuda => "atlantic/bermuda", + Timezone::AtlanticCanary => "atlantic/canary", + Timezone::AtlanticCapeVerde => "atlantic/cape_verde", + Timezone::AtlanticFaroe => "atlantic/faroe", + Timezone::AtlanticMadeira => "atlantic/madeira", + Timezone::AtlanticReykjavik => "atlantic/reykjavik", + Timezone::AtlanticSouthGeorgia => "atlantic/south_georgia", + Timezone::AtlanticStHelena => "atlantic/st_helena", + Timezone::AtlanticStanley => "atlantic/stanley", + Timezone::AustraliaAdelaide => "australia/adelaide", + Timezone::AustraliaBrisbane => "australia/brisbane", + Timezone::AustraliaBrokenHill => "australia/broken_hill", + Timezone::AustraliaDarwin => "australia/darwin", + Timezone::AustraliaEucla => "australia/eucla", + Timezone::AustraliaHobart => "australia/hobart", + Timezone::AustraliaLindeman => "australia/lindeman", + Timezone::AustraliaLordHowe => "australia/lord_howe", + Timezone::AustraliaMelbourne => "australia/melbourne", + Timezone::AustraliaPerth => "australia/perth", + Timezone::AustraliaSydney => "australia/sydney", + Timezone::EuropeAmsterdam => "europe/amsterdam", + Timezone::EuropeAndorra => "europe/andorra", + Timezone::EuropeAstrakhan => "europe/astrakhan", + Timezone::EuropeAthens => "europe/athens", + Timezone::EuropeBelgrade => "europe/belgrade", + Timezone::EuropeBerlin => "europe/berlin", + Timezone::EuropeBratislava => "europe/bratislava", + Timezone::EuropeBrussels => "europe/brussels", + Timezone::EuropeBucharest => "europe/bucharest", + Timezone::EuropeBudapest => "europe/budapest", + Timezone::EuropeBusingen => "europe/busingen", + Timezone::EuropeChisinau => "europe/chisinau", + Timezone::EuropeCopenhagen => "europe/copenhagen", + Timezone::EuropeDublin => "europe/dublin", + Timezone::EuropeGibraltar => "europe/gibraltar", + Timezone::EuropeGuernsey => "europe/guernsey", + Timezone::EuropeHelsinki => "europe/helsinki", + Timezone::EuropeIsleOfMan => "europe/isle_of_man", + Timezone::EuropeIstanbul => "europe/istanbul", + Timezone::EuropeJersey => "europe/jersey", + Timezone::EuropeKaliningrad => "europe/kaliningrad", + Timezone::EuropeKirov => "europe/kirov", + Timezone::EuropeKyiv => "europe/kyiv", + Timezone::EuropeLisbon => "europe/lisbon", + Timezone::EuropeLjubljana => "europe/ljubljana", + Timezone::EuropeLondon => "europe/london", + Timezone::EuropeLuxembourg => "europe/luxembourg", + Timezone::EuropeMadrid => "europe/madrid", + Timezone::EuropeMalta => "europe/malta", + Timezone::EuropeMariehamn => "europe/mariehamn", + Timezone::EuropeMinsk => "europe/minsk", + Timezone::EuropeMonaco => "europe/monaco", + Timezone::EuropeMoscow => "europe/moscow", + Timezone::EuropeOslo => "europe/oslo", + Timezone::EuropeParis => "europe/paris", + Timezone::EuropePodgorica => "europe/podgorica", + Timezone::EuropePrague => "europe/prague", + Timezone::EuropeRiga => "europe/riga", + Timezone::EuropeRome => "europe/rome", + Timezone::EuropeSamara => "europe/samara", + Timezone::EuropeSanMarino => "europe/san_marino", + Timezone::EuropeSarajevo => "europe/sarajevo", + Timezone::EuropeSaratov => "europe/saratov", + Timezone::EuropeSimferopol => "europe/simferopol", + Timezone::EuropeSkopje => "europe/skopje", + Timezone::EuropeSofia => "europe/sofia", + Timezone::EuropeStockholm => "europe/stockholm", + Timezone::EuropeTallinn => "europe/tallinn", + Timezone::EuropeTirane => "europe/tirane", + Timezone::EuropeUlyanovsk => "europe/ulyanovsk", + Timezone::EuropeVaduz => "europe/vaduz", + Timezone::EuropeVatican => "europe/vatican", + Timezone::EuropeVienna => "europe/vienna", + Timezone::EuropeVilnius => "europe/vilnius", + Timezone::EuropeVolgograd => "europe/volgograd", + Timezone::EuropeWarsaw => "europe/warsaw", + Timezone::EuropeZagreb => "europe/zagreb", + Timezone::EuropeZurich => "europe/zurich", + Timezone::IndianAntananarivo => "indian/antananarivo", + Timezone::IndianChagos => "indian/chagos", + Timezone::IndianChristmas => "indian/christmas", + Timezone::IndianCocos => "indian/cocos", + Timezone::IndianComoro => "indian/comoro", + Timezone::IndianKerguelen => "indian/kerguelen", + Timezone::IndianMahe => "indian/mahe", + Timezone::IndianMaldives => "indian/maldives", + Timezone::IndianMauritius => "indian/mauritius", + Timezone::IndianMayotte => "indian/mayotte", + Timezone::IndianReunion => "indian/reunion", + Timezone::PacificApia => "pacific/apia", + Timezone::PacificAuckland => "pacific/auckland", + Timezone::PacificBougainville => "pacific/bougainville", + Timezone::PacificChatham => "pacific/chatham", + Timezone::PacificChuuk => "pacific/chuuk", + Timezone::PacificEaster => "pacific/easter", + Timezone::PacificEfate => "pacific/efate", + Timezone::PacificFakaofo => "pacific/fakaofo", + Timezone::PacificFiji => "pacific/fiji", + Timezone::PacificFunafuti => "pacific/funafuti", + Timezone::PacificGalapagos => "pacific/galapagos", + Timezone::PacificGambier => "pacific/gambier", + Timezone::PacificGuadalcanal => "pacific/guadalcanal", + Timezone::PacificGuam => "pacific/guam", + Timezone::PacificHonolulu => "pacific/honolulu", + Timezone::PacificKanton => "pacific/kanton", + Timezone::PacificKiritimati => "pacific/kiritimati", + Timezone::PacificKosrae => "pacific/kosrae", + Timezone::PacificKwajalein => "pacific/kwajalein", + Timezone::PacificMajuro => "pacific/majuro", + Timezone::PacificMarquesas => "pacific/marquesas", + Timezone::PacificMidway => "pacific/midway", + Timezone::PacificNauru => "pacific/nauru", + Timezone::PacificNiue => "pacific/niue", + Timezone::PacificNorfolk => "pacific/norfolk", + Timezone::PacificNoumea => "pacific/noumea", + Timezone::PacificPagoPago => "pacific/pago_pago", + Timezone::PacificPalau => "pacific/palau", + Timezone::PacificPitcairn => "pacific/pitcairn", + Timezone::PacificPohnpei => "pacific/pohnpei", + Timezone::PacificPortMoresby => "pacific/port_moresby", + Timezone::PacificRarotonga => "pacific/rarotonga", + Timezone::PacificSaipan => "pacific/saipan", + Timezone::PacificTahiti => "pacific/tahiti", + Timezone::PacificTarawa => "pacific/tarawa", + Timezone::PacificTongatapu => "pacific/tongatapu", + Timezone::PacificWake => "pacific/wake", + Timezone::PacificWallis => "pacific/wallis", + Timezone::Utc => "utc", + } + } +} + +impl std::fmt::Display for Timezone { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/enums/vcs_reference_type.rs b/src/enums/vcs_reference_type.rs new file mode 100644 index 0000000..2be5e1a --- /dev/null +++ b/src/enums/vcs_reference_type.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub enum VCSReferenceType { + #[serde(rename = "branch")] + #[default] + Branch, + #[serde(rename = "commit")] + Commit, + #[serde(rename = "tag")] + Tag, +} + +impl VCSReferenceType { + /// Get the string value of the enum + pub fn as_str(&self) -> &str { + match self { + VCSReferenceType::Branch => "branch", + VCSReferenceType::Commit => "commit", + VCSReferenceType::Tag => "tag", + } + } +} + +impl std::fmt::Display for VCSReferenceType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..8715cb4 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,112 @@ +//! Error types for Appwrite SDK + +use serde_json; + +/// Result type alias for SDK operations +pub type Result = std::result::Result; + +/// Main error type for Appwrite SDK +#[derive(Debug, Clone, thiserror::Error)] +#[error("{message}")] +pub struct AppwriteError { + pub code: u16, + pub message: String, + pub error_type: Option, + pub response: String, +} + +impl AppwriteError { + pub fn new(code: u16, message: impl Into, error_type: Option, response: impl Into) -> Self { + Self { + code, + message: message.into(), + error_type, + response: response.into(), + } + } + + pub fn status_code(&self) -> u16 { + self.code + } + + pub fn get_message(&self) -> &str { + &self.message + } + + pub fn get_type(&self) -> Option<&str> { + self.error_type.as_deref() + } + + pub fn get_response(&self) -> &str { + &self.response + } + + pub fn is_client_error(&self) -> bool { + (400..500).contains(&self.code) + } + + pub fn is_server_error(&self) -> bool { + (500..600).contains(&self.code) + } +} + +impl From for AppwriteError { + fn from(err: reqwest::Error) -> Self { + let code = err.status().map(|s| s.as_u16()).unwrap_or(0); + Self::new(code, format!("HTTP error: {}", err), None, String::new()) + } +} + +impl From for AppwriteError { + fn from(err: serde_json::Error) -> Self { + Self::new(0, format!("Serialization error: {}", err), None, String::new()) + } +} + +impl From for AppwriteError { + fn from(err: std::io::Error) -> Self { + Self::new(0, format!("File error: {}", err), None, String::new()) + } +} + +/// Appwrite specific error response structure +#[derive(Debug, serde::Deserialize)] +pub struct ErrorResponse { + pub message: String, + pub code: Option, + pub r#type: Option, + pub version: Option, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_client_error() { + let error = AppwriteError::new( + 404, + "Not found", + None, + "{}", + ); + + assert_eq!(error.status_code(), 404); + assert_eq!(error.get_message(), "Not found"); + assert!(error.is_client_error()); + assert!(!error.is_server_error()); + } + + #[test] + fn test_server_error() { + let error = AppwriteError::new( + 500, + "Internal server error", + None, + "{}", + ); + + assert!(error.is_server_error()); + assert!(!error.is_client_error()); + } +} diff --git a/src/id.rs b/src/id.rs new file mode 100644 index 0000000..d70f160 --- /dev/null +++ b/src/id.rs @@ -0,0 +1,118 @@ +//! ID generation utilities for Appwrite SDK + +use std::time::{SystemTime, UNIX_EPOCH}; + +/// ID generator for Appwrite resources +pub struct ID; + +impl ID { + /// Generate a unique ID (13 hex timestamp + 7 random hex) + pub fn unique() -> String { + Self::unique_with_padding(7) + } + + /// Generate a unique ID with custom padding + pub fn unique_with_padding(padding: usize) -> String { + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards"); + + let sec = now.as_secs(); + let usec = now.subsec_micros(); + let timestamp_hex = format!("{:08x}{:05x}", sec, usec); + + if padding == 0 { + return timestamp_hex; + } + + let mut id = String::with_capacity(13 + padding); + id.push_str(×tamp_hex); + + const HEX: &[u8; 16] = b"0123456789abcdef"; + for _ in 0..padding { + let idx = fastrand::u8(..16) as usize; + id.push(HEX[idx] as char); + } + + id + } + + /// Create a custom ID + pub fn custom>(id: S) -> String { + id.into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_unique_id_length() { + let id = ID::unique(); + assert_eq!(id.len(), 20); + } + + #[test] + fn test_unique_id_uniqueness() { + let id1 = ID::unique(); + let id2 = ID::unique(); + assert_ne!(id1, id2); + } + + #[test] + fn test_unique_id_hex_format() { + let id = ID::unique(); + assert!(id.chars().all(|c| c.is_ascii_hexdigit())); + } + + #[test] + fn test_custom_id_passthrough() { + let id = ID::custom("my_custom_id_123"); + assert_eq!(id, "my_custom_id_123"); + } + + #[test] + fn test_custom_id_with_special_chars() { + let id = ID::custom("test@id-with_special.chars"); + assert_eq!(id, "test@id-with_special.chars"); + } + + #[test] + fn test_custom_id_empty() { + let id = ID::custom(""); + assert_eq!(id, ""); + } + + #[test] + fn test_multiple_unique_ids() { + let ids: Vec = (0..100).map(|_| ID::unique()).collect(); + assert!(ids.iter().all(|id| id.len() == 20)); + let unique_count = ids.iter().collect::>().len(); + assert_eq!(unique_count, 100); + } + + #[test] + fn test_unique_with_padding() { + let id_no_padding = ID::unique_with_padding(0); + assert_eq!(id_no_padding.len(), 13); + + let id_small_padding = ID::unique_with_padding(3); + assert_eq!(id_small_padding.len(), 16); + + let id_large_padding = ID::unique_with_padding(15); + assert_eq!(id_large_padding.len(), 28); + } + + #[test] + fn test_format_matches_sdk_length() { + let id = ID::unique(); + assert_eq!(id.len(), 20); + assert!(id.chars().all(|c| c.is_ascii_hexdigit())); + + let timestamp_part = &id[..13]; + let random_part = &id[13..]; + assert_eq!(timestamp_part.len(), 13); + assert_eq!(random_part.len(), 7); + } +} diff --git a/src/input_file.rs b/src/input_file.rs new file mode 100644 index 0000000..e72b3c1 --- /dev/null +++ b/src/input_file.rs @@ -0,0 +1,298 @@ +//! Input file handling for Appwrite SDK + +use crate::error::Result; +use bytes::Bytes; +use std::path::{Path, PathBuf}; +use tokio::fs; + +/// Source of the input file data +#[derive(Debug, Clone)] +pub enum InputFileSource { + Path { path: PathBuf }, + Bytes { data: Bytes }, +} + +/// Chunked reader for streaming file data without reopening +pub struct ChunkedReader { + file: Option, + data: Option, + position: u64, + total_size: u64, +} + +/// Represents a file to be uploaded to Appwrite +#[derive(Debug, Clone)] +pub struct InputFile { + source: InputFileSource, + filename: String, + mime_type: Option, +} + +impl Default for InputFile { + fn default() -> Self { + Self { + source: InputFileSource::Bytes { data: Bytes::new() }, + filename: String::new(), + mime_type: None, + } + } +} + +impl InputFile { + /// Create a new InputFile from raw bytes + pub fn from_bytes, B: Into>( + data: B, + filename: S, + mime_type: Option<&str>, + ) -> Self { + Self { + source: InputFileSource::Bytes { data: data.into() }, + filename: filename.into(), + mime_type: mime_type.map(|s| s.to_string()), + } + } + + pub async fn from_path>(path: P, mime_type: Option<&str>) -> Result { + let path = path.as_ref(); + fs::metadata(path).await?; + + let filename = path + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or("unknown") + .to_string(); + + Ok(Self { + source: InputFileSource::Path { path: path.to_path_buf() }, + filename, + mime_type: mime_type.map(|s| s.to_string()), + }) + } + + pub fn from_path_sync>(path: P, mime_type: Option<&str>) -> Result { + let path = path.as_ref(); + std::fs::metadata(path)?; + + let filename = path + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or("unknown") + .to_string(); + + Ok(Self { + source: InputFileSource::Path { path: path.to_path_buf() }, + filename, + mime_type: mime_type.map(|s| s.to_string()), + }) + } + + pub fn source(&self) -> &InputFileSource { + &self.source + } + + pub fn filename(&self) -> &str { + &self.filename + } + + pub fn mime_type(&self) -> Option<&str> { + self.mime_type.as_deref() + } + + pub async fn size(&self) -> Result { + match &self.source { + InputFileSource::Bytes { data } => Ok(data.len() as u64), + InputFileSource::Path { path } => { + Ok(fs::metadata(path).await?.len()) + } + } + } + + pub fn size_sync(&self) -> Result { + match &self.source { + InputFileSource::Bytes { data } => Ok(data.len() as u64), + InputFileSource::Path { path } => { + Ok(std::fs::metadata(path)?.len()) + } + } + } + + pub async fn read_all(&self) -> Result { + match &self.source { + InputFileSource::Bytes { data } => Ok(data.clone()), + InputFileSource::Path { path } => { + Ok(Bytes::from(fs::read(path).await?)) + } + } + } + + pub async fn chunked_reader(&self) -> Result { + match &self.source { + InputFileSource::Path { path } => { + let file = fs::File::open(path).await?; + let total_size = file.metadata().await?.len(); + Ok(ChunkedReader { + file: Some(file), + data: None, + position: 0, + total_size, + }) + } + InputFileSource::Bytes { data } => { + Ok(ChunkedReader { + file: None, + data: Some(data.clone()), + position: 0, + total_size: data.len() as u64, + }) + } + } + } + + /// Set the filename + pub fn set_filename>(mut self, filename: S) -> Self { + self.filename = filename.into(); + self + } + + /// Set the MIME type + pub fn set_mime_type>(mut self, mime_type: S) -> Self { + self.mime_type = Some(mime_type.into()); + self + } + + pub fn is_empty(&self) -> bool { + match &self.source { + InputFileSource::Bytes { data } => data.is_empty(), + InputFileSource::Path { path } => { + std::fs::metadata(path) + .map(|m| m.len() == 0) + .unwrap_or(true) + } + } + } +} + +impl ChunkedReader { + /// Read the next chunk of specified size + pub async fn read_next(&mut self, chunk_size: usize) -> Result> { + if self.position >= self.total_size { + return Ok(None); + } + + match (&mut self.file, &self.data) { + (Some(file), None) => { + use tokio::io::AsyncReadExt; + + let remaining = (self.total_size - self.position) as usize; + let to_read = remaining.min(chunk_size); + let mut buffer = vec![0u8; to_read]; + let mut total_read = 0; + + while total_read < to_read { + match file.read(&mut buffer[total_read..]).await? { + 0 => break, + n => total_read += n, + } + } + + if total_read == 0 { + return Ok(None); + } + + buffer.truncate(total_read); + self.position += total_read as u64; + Ok(Some(Bytes::from(buffer))) + } + (None, Some(data)) => { + let start = self.position as usize; + let end = ((self.position + chunk_size as u64).min(self.total_size)) as usize; + + if start >= end { + return Ok(None); + } + + self.position = end as u64; + Ok(Some(data.slice(start..end))) + } + _ => Ok(None), + } + } + + /// Get the current read position + pub fn position(&self) -> u64 { + self.position + } + + /// Get the total size + pub fn total_size(&self) -> u64 { + self.total_size + } + + pub async fn seek(&mut self, position: u64) -> Result<()> { + if position > self.total_size { + return Err(crate::error::AppwriteError::new( + 0, + format!("Seek position {} exceeds file size {}", position, self.total_size), + None, + String::new(), + )); + } + + if let Some(file) = &mut self.file { + use tokio::io::AsyncSeekExt; + file.seek(std::io::SeekFrom::Start(position)).await?; + } + + self.position = position; + Ok(()) + } +} + +impl From> for InputFile { + fn from(data: Vec) -> Self { + Self::from_bytes(data, "unknown", None) + } +} + +impl From<&[u8]> for InputFile { + fn from(data: &[u8]) -> Self { + Self::from_bytes(data.to_vec(), "unknown", None) + } +} + +impl From for InputFile { + fn from(data: Bytes) -> Self { + Self::from_bytes(data, "unknown", None) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_from_bytes() { + let data = b"Hello, world!".to_vec(); + let file = InputFile::from_bytes(data.clone(), "test.txt", Some("text/plain")); + + assert_eq!(file.read_all().await.unwrap(), data); + assert_eq!(file.filename(), "test.txt"); + assert_eq!(file.mime_type(), Some("text/plain")); + assert_eq!(file.size().await.unwrap(), 13); + } + + #[test] + fn test_empty_file() { + let file = InputFile::default(); + assert!(file.is_empty()); + assert_eq!(file.size_sync().unwrap(), 0); + } + + #[tokio::test] + async fn test_from_vec() { + let data = vec![1, 2, 3, 4, 5]; + let file = InputFile::from(data.clone()); + assert_eq!(file.read_all().await.unwrap(), data); + assert_eq!(file.filename(), "unknown"); + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..161b3ce --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,63 @@ +//! # Appwrite SDK for Rust +//! +//! Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) +//! +//! ## Installation +//! +//! Add this to your `Cargo.toml`: +//! +//! ```toml +//! [dependencies] +//! appwrite = "0.1.1" +//! ``` +//! +//! ## Usage +//! +//! ```rust +//! use appwrite::Client; +//! +//! #[tokio::main] +//! async fn main() -> Result<(), Box> { +//! let client = Client::new() +//! .set_endpoint("https://cloud.appwrite.io/v1") +//! .set_project("your-project-id") +//! .set_key("your-api-key"); +//! +//! // Use the client to make API calls +//! Ok(()) +//! } +//! ``` + +pub mod client; +pub mod enums; +pub mod error; +pub mod input_file; +pub mod models; +pub mod services; + +// Utility modules +pub mod id; +pub mod operator; +pub mod permission; +pub mod query; +pub mod role; + +// Re-export commonly used types +pub use client::Client; +pub use error::AppwriteError; +pub use input_file::InputFile; + +/// Result type alias for SDK operations +pub type Result = std::result::Result; + +/// SDK version +pub const VERSION: &str = "0.1.1"; + +/// SDK name +pub const SDK_NAME: &str = "Rust"; + +/// SDK platform +pub const SDK_PLATFORM: &str = "server"; + +/// SDK language +pub const SDK_LANGUAGE: &str = "rust"; diff --git a/src/models/activity_event.rs b/src/models/activity_event.rs new file mode 100644 index 0000000..221feca --- /dev/null +++ b/src/models/activity_event.rs @@ -0,0 +1,322 @@ +//! ActivityEvent model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ActivityEvent +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ActivityEvent { + /// Event ID. + #[serde(rename = "$id")] + pub id: String, + /// User type. + #[serde(rename = "userType")] + pub user_type: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// User Email. + #[serde(rename = "userEmail")] + pub user_email: String, + /// User Name. + #[serde(rename = "userName")] + pub user_name: String, + /// Resource parent. + #[serde(rename = "resourceParent")] + pub resource_parent: String, + /// Resource type. + #[serde(rename = "resourceType")] + pub resource_type: String, + /// Resource ID. + #[serde(rename = "resourceId")] + pub resource_id: String, + /// Resource. + #[serde(rename = "resource")] + pub resource: String, + /// Event name. + #[serde(rename = "event")] + pub event: String, + /// User agent. + #[serde(rename = "userAgent")] + pub user_agent: String, + /// IP address. + #[serde(rename = "ip")] + pub ip: String, + /// API mode when event triggered. + #[serde(rename = "mode")] + pub mode: String, + /// Location. + #[serde(rename = "country")] + pub country: String, + /// Log creation date in ISO 8601 format. + #[serde(rename = "time")] + pub time: String, + /// Project ID. + #[serde(rename = "projectId")] + pub project_id: String, + /// Team ID. + #[serde(rename = "teamId")] + pub team_id: String, + /// Hostname. + #[serde(rename = "hostname")] + pub hostname: String, + /// Operating system code name. View list of [available + /// options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). + #[serde(rename = "osCode")] + pub os_code: String, + /// Operating system name. + #[serde(rename = "osName")] + pub os_name: String, + /// Operating system version. + #[serde(rename = "osVersion")] + pub os_version: String, + /// Client type. + #[serde(rename = "clientType")] + pub client_type: String, + /// Client code name. View list of [available + /// options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). + #[serde(rename = "clientCode")] + pub client_code: String, + /// Client name. + #[serde(rename = "clientName")] + pub client_name: String, + /// Client version. + #[serde(rename = "clientVersion")] + pub client_version: String, + /// Client engine name. + #[serde(rename = "clientEngine")] + pub client_engine: String, + /// Client engine name. + #[serde(rename = "clientEngineVersion")] + pub client_engine_version: String, + /// Device name. + #[serde(rename = "deviceName")] + pub device_name: String, + /// Device brand name. + #[serde(rename = "deviceBrand")] + pub device_brand: String, + /// Device model name. + #[serde(rename = "deviceModel")] + pub device_model: String, + /// Country two-character ISO 3166-1 alpha code. + #[serde(rename = "countryCode")] + pub country_code: String, + /// Country name. + #[serde(rename = "countryName")] + pub country_name: String, +} + +impl ActivityEvent { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get user_type + pub fn user_type(&self) -> &String { + &self.user_type + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get user_email + pub fn user_email(&self) -> &String { + &self.user_email + } + + /// Get user_name + pub fn user_name(&self) -> &String { + &self.user_name + } + + /// Get resource_parent + pub fn resource_parent(&self) -> &String { + &self.resource_parent + } + + /// Get resource_type + pub fn resource_type(&self) -> &String { + &self.resource_type + } + + /// Get resource_id + pub fn resource_id(&self) -> &String { + &self.resource_id + } + + /// Get resource + pub fn resource(&self) -> &String { + &self.resource + } + + /// Get event + pub fn event(&self) -> &String { + &self.event + } + + /// Get user_agent + pub fn user_agent(&self) -> &String { + &self.user_agent + } + + /// Get ip + pub fn ip(&self) -> &String { + &self.ip + } + + /// Get mode + pub fn mode(&self) -> &String { + &self.mode + } + + /// Get country + pub fn country(&self) -> &String { + &self.country + } + + /// Get time + pub fn time(&self) -> &String { + &self.time + } + + /// Get project_id + pub fn project_id(&self) -> &String { + &self.project_id + } + + /// Get team_id + pub fn team_id(&self) -> &String { + &self.team_id + } + + /// Get hostname + pub fn hostname(&self) -> &String { + &self.hostname + } + + /// Get os_code + pub fn os_code(&self) -> &String { + &self.os_code + } + + /// Get os_name + pub fn os_name(&self) -> &String { + &self.os_name + } + + /// Get os_version + pub fn os_version(&self) -> &String { + &self.os_version + } + + /// Get client_type + pub fn client_type(&self) -> &String { + &self.client_type + } + + /// Get client_code + pub fn client_code(&self) -> &String { + &self.client_code + } + + /// Get client_name + pub fn client_name(&self) -> &String { + &self.client_name + } + + /// Get client_version + pub fn client_version(&self) -> &String { + &self.client_version + } + + /// Get client_engine + pub fn client_engine(&self) -> &String { + &self.client_engine + } + + /// Get client_engine_version + pub fn client_engine_version(&self) -> &String { + &self.client_engine_version + } + + /// Get device_name + pub fn device_name(&self) -> &String { + &self.device_name + } + + /// Get device_brand + pub fn device_brand(&self) -> &String { + &self.device_brand + } + + /// Get device_model + pub fn device_model(&self) -> &String { + &self.device_model + } + + /// Get country_code + pub fn country_code(&self) -> &String { + &self.country_code + } + + /// Get country_name + pub fn country_name(&self) -> &String { + &self.country_name + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_activity_event_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.user_type(); + let _ = _model.user_id(); + let _ = _model.user_email(); + let _ = _model.user_name(); + let _ = _model.resource_parent(); + let _ = _model.resource_type(); + let _ = _model.resource_id(); + let _ = _model.resource(); + let _ = _model.event(); + let _ = _model.user_agent(); + let _ = _model.ip(); + let _ = _model.mode(); + let _ = _model.country(); + let _ = _model.time(); + let _ = _model.project_id(); + let _ = _model.team_id(); + let _ = _model.hostname(); + let _ = _model.os_code(); + let _ = _model.os_name(); + let _ = _model.os_version(); + let _ = _model.client_type(); + let _ = _model.client_code(); + let _ = _model.client_name(); + let _ = _model.client_version(); + let _ = _model.client_engine(); + let _ = _model.client_engine_version(); + let _ = _model.device_name(); + let _ = _model.device_brand(); + let _ = _model.device_model(); + let _ = _model.country_code(); + let _ = _model.country_name(); + } + + #[test] + fn test_activity_event_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/activity_event_list.rs b/src/models/activity_event_list.rs new file mode 100644 index 0000000..4d989db --- /dev/null +++ b/src/models/activity_event_list.rs @@ -0,0 +1,50 @@ +//! ActivityEventList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Activity event list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ActivityEventList { + /// Total number of events that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of events. + #[serde(rename = "events")] + pub events: Vec, +} + +impl ActivityEventList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get events + pub fn events(&self) -> &Vec { + &self.events + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_activity_event_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.events(); + } + + #[test] + fn test_activity_event_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_argon2.rs b/src/models/algo_argon2.rs new file mode 100644 index 0000000..542f5db --- /dev/null +++ b/src/models/algo_argon2.rs @@ -0,0 +1,68 @@ +//! AlgoArgon2 model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoArgon2 +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoArgon2 { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, + /// Memory used to compute hash. + #[serde(rename = "memoryCost")] + pub memory_cost: i64, + /// Amount of time consumed to compute hash + #[serde(rename = "timeCost")] + pub time_cost: i64, + /// Number of threads used to compute hash. + #[serde(rename = "threads")] + pub threads: i64, +} + +impl AlgoArgon2 { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get memory_cost + pub fn memory_cost(&self) -> &i64 { + &self.memory_cost + } + + /// Get time_cost + pub fn time_cost(&self) -> &i64 { + &self.time_cost + } + + /// Get threads + pub fn threads(&self) -> &i64 { + &self.threads + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_argon2_creation() { + let _model = ::default(); + let _ = _model.r#type(); + let _ = _model.memory_cost(); + let _ = _model.time_cost(); + let _ = _model.threads(); + } + + #[test] + fn test_algo_argon2_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_bcrypt.rs b/src/models/algo_bcrypt.rs new file mode 100644 index 0000000..c1a832a --- /dev/null +++ b/src/models/algo_bcrypt.rs @@ -0,0 +1,41 @@ +//! AlgoBcrypt model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoBcrypt +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoBcrypt { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, +} + +impl AlgoBcrypt { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_bcrypt_creation() { + let _model = ::default(); + let _ = _model.r#type(); + } + + #[test] + fn test_algo_bcrypt_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_md5.rs b/src/models/algo_md5.rs new file mode 100644 index 0000000..d73a007 --- /dev/null +++ b/src/models/algo_md5.rs @@ -0,0 +1,41 @@ +//! AlgoMd5 model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoMD5 +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoMd5 { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, +} + +impl AlgoMd5 { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_md5_creation() { + let _model = ::default(); + let _ = _model.r#type(); + } + + #[test] + fn test_algo_md5_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_phpass.rs b/src/models/algo_phpass.rs new file mode 100644 index 0000000..f2aae71 --- /dev/null +++ b/src/models/algo_phpass.rs @@ -0,0 +1,41 @@ +//! AlgoPhpass model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoPHPass +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoPhpass { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, +} + +impl AlgoPhpass { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_phpass_creation() { + let _model = ::default(); + let _ = _model.r#type(); + } + + #[test] + fn test_algo_phpass_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_scrypt.rs b/src/models/algo_scrypt.rs new file mode 100644 index 0000000..d6123f0 --- /dev/null +++ b/src/models/algo_scrypt.rs @@ -0,0 +1,77 @@ +//! AlgoScrypt model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoScrypt +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoScrypt { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, + /// CPU complexity of computed hash. + #[serde(rename = "costCpu")] + pub cost_cpu: i64, + /// Memory complexity of computed hash. + #[serde(rename = "costMemory")] + pub cost_memory: i64, + /// Parallelization of computed hash. + #[serde(rename = "costParallel")] + pub cost_parallel: i64, + /// Length used to compute hash. + #[serde(rename = "length")] + pub length: i64, +} + +impl AlgoScrypt { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get cost_cpu + pub fn cost_cpu(&self) -> &i64 { + &self.cost_cpu + } + + /// Get cost_memory + pub fn cost_memory(&self) -> &i64 { + &self.cost_memory + } + + /// Get cost_parallel + pub fn cost_parallel(&self) -> &i64 { + &self.cost_parallel + } + + /// Get length + pub fn length(&self) -> &i64 { + &self.length + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_scrypt_creation() { + let _model = ::default(); + let _ = _model.r#type(); + let _ = _model.cost_cpu(); + let _ = _model.cost_memory(); + let _ = _model.cost_parallel(); + let _ = _model.length(); + } + + #[test] + fn test_algo_scrypt_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_scrypt_modified.rs b/src/models/algo_scrypt_modified.rs new file mode 100644 index 0000000..2f273b4 --- /dev/null +++ b/src/models/algo_scrypt_modified.rs @@ -0,0 +1,68 @@ +//! AlgoScryptModified model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoScryptModified +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoScryptModified { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, + /// Salt used to compute hash. + #[serde(rename = "salt")] + pub salt: String, + /// Separator used to compute hash. + #[serde(rename = "saltSeparator")] + pub salt_separator: String, + /// Key used to compute hash. + #[serde(rename = "signerKey")] + pub signer_key: String, +} + +impl AlgoScryptModified { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get salt + pub fn salt(&self) -> &String { + &self.salt + } + + /// Get salt_separator + pub fn salt_separator(&self) -> &String { + &self.salt_separator + } + + /// Get signer_key + pub fn signer_key(&self) -> &String { + &self.signer_key + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_scrypt_modified_creation() { + let _model = ::default(); + let _ = _model.r#type(); + let _ = _model.salt(); + let _ = _model.salt_separator(); + let _ = _model.signer_key(); + } + + #[test] + fn test_algo_scrypt_modified_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/algo_sha.rs b/src/models/algo_sha.rs new file mode 100644 index 0000000..08b454e --- /dev/null +++ b/src/models/algo_sha.rs @@ -0,0 +1,41 @@ +//! AlgoSha model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AlgoSHA +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AlgoSha { + /// Algo type. + #[serde(rename = "type")] + pub r#type: String, +} + +impl AlgoSha { + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_algo_sha_creation() { + let _model = ::default(); + let _ = _model.r#type(); + } + + #[test] + fn test_algo_sha_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_boolean.rs b/src/models/attribute_boolean.rs new file mode 100644 index 0000000..eebc91a --- /dev/null +++ b/src/models/attribute_boolean.rs @@ -0,0 +1,128 @@ +//! AttributeBoolean model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeBoolean +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeBoolean { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeBoolean { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: bool) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&bool> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_boolean_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_boolean_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_datetime.rs b/src/models/attribute_datetime.rs new file mode 100644 index 0000000..0eb6bc8 --- /dev/null +++ b/src/models/attribute_datetime.rs @@ -0,0 +1,136 @@ +//! AttributeDatetime model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeDatetime +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeDatetime { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// ISO 8601 format. + #[serde(rename = "format")] + pub format: String, + /// Default value for attribute when not provided. Only null is optional + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeDatetime { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_datetime_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_attribute_datetime_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_email.rs b/src/models/attribute_email.rs new file mode 100644 index 0000000..9780b8d --- /dev/null +++ b/src/models/attribute_email.rs @@ -0,0 +1,137 @@ +//! AttributeEmail model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeEmail +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeEmail { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeEmail { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_email_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_attribute_email_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_enum.rs b/src/models/attribute_enum.rs new file mode 100644 index 0000000..6ebc2cf --- /dev/null +++ b/src/models/attribute_enum.rs @@ -0,0 +1,146 @@ +//! AttributeEnum model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeEnum +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeEnum { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Array of elements in enumerated type. + #[serde(rename = "elements")] + pub elements: Vec, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeEnum { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get elements + pub fn elements(&self) -> &Vec { + &self.elements + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_enum_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.elements(); + let _ = _model.format(); + } + + #[test] + fn test_attribute_enum_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_float.rs b/src/models/attribute_float.rs new file mode 100644 index 0000000..c8fea5c --- /dev/null +++ b/src/models/attribute_float.rs @@ -0,0 +1,158 @@ +//! AttributeFloat model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeFloat +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeFloat { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Minimum value to enforce for new documents. + #[serde(rename = "min")] + #[serde(skip_serializing_if = "Option::is_none")] + pub min: Option, + /// Maximum value to enforce for new documents. + #[serde(rename = "max")] + #[serde(skip_serializing_if = "Option::is_none")] + pub max: Option, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeFloat { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set min + pub fn set_min(mut self, min: f64) -> Self { + self.min = Some(min); + self + } + + /// Get min + pub fn min(&self) -> Option<&f64> { + self.min.as_ref() + } + + /// Set max + pub fn set_max(mut self, max: f64) -> Self { + self.max = Some(max); + self + } + + /// Get max + pub fn max(&self) -> Option<&f64> { + self.max.as_ref() + } + + /// Set default + pub fn set_default(mut self, default: f64) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&f64> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_float_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_float_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_integer.rs b/src/models/attribute_integer.rs new file mode 100644 index 0000000..357c12f --- /dev/null +++ b/src/models/attribute_integer.rs @@ -0,0 +1,158 @@ +//! AttributeInteger model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeInteger +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeInteger { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Minimum value to enforce for new documents. + #[serde(rename = "min")] + #[serde(skip_serializing_if = "Option::is_none")] + pub min: Option, + /// Maximum value to enforce for new documents. + #[serde(rename = "max")] + #[serde(skip_serializing_if = "Option::is_none")] + pub max: Option, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeInteger { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set min + pub fn set_min(mut self, min: i64) -> Self { + self.min = Some(min); + self + } + + /// Get min + pub fn min(&self) -> Option<&i64> { + self.min.as_ref() + } + + /// Set max + pub fn set_max(mut self, max: i64) -> Self { + self.max = Some(max); + self + } + + /// Get max + pub fn max(&self) -> Option<&i64> { + self.max.as_ref() + } + + /// Set default + pub fn set_default(mut self, default: i64) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&i64> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_integer_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_integer_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_ip.rs b/src/models/attribute_ip.rs new file mode 100644 index 0000000..2bb821a --- /dev/null +++ b/src/models/attribute_ip.rs @@ -0,0 +1,137 @@ +//! AttributeIp model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeIP +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeIp { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeIp { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_ip_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_attribute_ip_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_line.rs b/src/models/attribute_line.rs new file mode 100644 index 0000000..08e6fae --- /dev/null +++ b/src/models/attribute_line.rs @@ -0,0 +1,128 @@ +//! AttributeLine model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeLine +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeLine { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, +} + +impl AttributeLine { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: Vec) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&Vec> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_line_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_line_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_list.rs b/src/models/attribute_list.rs new file mode 100644 index 0000000..d105e9e --- /dev/null +++ b/src/models/attribute_list.rs @@ -0,0 +1,50 @@ +//! AttributeList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Attributes List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeList { + /// Total number of attributes in the given collection. + #[serde(rename = "total")] + pub total: i64, + /// List of attributes. + #[serde(rename = "attributes")] + pub attributes: Vec, +} + +impl AttributeList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get attributes + pub fn attributes(&self) -> &Vec { + &self.attributes + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.attributes(); + } + + #[test] + fn test_attribute_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_longtext.rs b/src/models/attribute_longtext.rs new file mode 100644 index 0000000..addeefe --- /dev/null +++ b/src/models/attribute_longtext.rs @@ -0,0 +1,143 @@ +//! AttributeLongtext model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeLongtext +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeLongtext { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this attribute is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl AttributeLongtext { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_longtext_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_longtext_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_mediumtext.rs b/src/models/attribute_mediumtext.rs new file mode 100644 index 0000000..9e1a79f --- /dev/null +++ b/src/models/attribute_mediumtext.rs @@ -0,0 +1,143 @@ +//! AttributeMediumtext model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeMediumtext +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeMediumtext { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this attribute is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl AttributeMediumtext { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_mediumtext_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_mediumtext_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_point.rs b/src/models/attribute_point.rs new file mode 100644 index 0000000..835b2ae --- /dev/null +++ b/src/models/attribute_point.rs @@ -0,0 +1,128 @@ +//! AttributePoint model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributePoint +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributePoint { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, +} + +impl AttributePoint { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: Vec) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&Vec> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_point_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_point_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_polygon.rs b/src/models/attribute_polygon.rs new file mode 100644 index 0000000..88b91a6 --- /dev/null +++ b/src/models/attribute_polygon.rs @@ -0,0 +1,128 @@ +//! AttributePolygon model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributePolygon +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributePolygon { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, +} + +impl AttributePolygon { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: Vec) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&Vec> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_polygon_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_polygon_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_relationship.rs b/src/models/attribute_relationship.rs new file mode 100644 index 0000000..ecd2d01 --- /dev/null +++ b/src/models/attribute_relationship.rs @@ -0,0 +1,166 @@ +//! AttributeRelationship model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeRelationship +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeRelationship { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// The ID of the related collection. + #[serde(rename = "relatedCollection")] + pub related_collection: String, + /// The type of the relationship. + #[serde(rename = "relationType")] + pub relation_type: String, + /// Is the relationship two-way? + #[serde(rename = "twoWay")] + pub two_way: bool, + /// The key of the two-way relationship. + #[serde(rename = "twoWayKey")] + pub two_way_key: String, + /// How deleting the parent document will propagate to child documents. + #[serde(rename = "onDelete")] + pub on_delete: String, + /// Whether this is the parent or child side of the relationship + #[serde(rename = "side")] + pub side: String, +} + +impl AttributeRelationship { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get related_collection + pub fn related_collection(&self) -> &String { + &self.related_collection + } + + /// Get relation_type + pub fn relation_type(&self) -> &String { + &self.relation_type + } + + /// Get two_way + pub fn two_way(&self) -> &bool { + &self.two_way + } + + /// Get two_way_key + pub fn two_way_key(&self) -> &String { + &self.two_way_key + } + + /// Get on_delete + pub fn on_delete(&self) -> &String { + &self.on_delete + } + + /// Get side + pub fn side(&self) -> &String { + &self.side + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_relationship_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.related_collection(); + let _ = _model.relation_type(); + let _ = _model.two_way(); + let _ = _model.two_way_key(); + let _ = _model.on_delete(); + let _ = _model.side(); + } + + #[test] + fn test_attribute_relationship_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_string.rs b/src/models/attribute_string.rs new file mode 100644 index 0000000..416c39d --- /dev/null +++ b/src/models/attribute_string.rs @@ -0,0 +1,152 @@ +//! AttributeString model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeString +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeString { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Attribute size. + #[serde(rename = "size")] + pub size: i64, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this attribute is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl AttributeString { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get size + pub fn size(&self) -> &i64 { + &self.size + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_string_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.size(); + } + + #[test] + fn test_attribute_string_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_text.rs b/src/models/attribute_text.rs new file mode 100644 index 0000000..ddfe094 --- /dev/null +++ b/src/models/attribute_text.rs @@ -0,0 +1,143 @@ +//! AttributeText model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeText +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeText { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this attribute is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl AttributeText { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_text_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_attribute_text_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_url.rs b/src/models/attribute_url.rs new file mode 100644 index 0000000..ceb7b16 --- /dev/null +++ b/src/models/attribute_url.rs @@ -0,0 +1,137 @@ +//! AttributeUrl model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeURL +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeUrl { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl AttributeUrl { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_url_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_attribute_url_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/attribute_varchar.rs b/src/models/attribute_varchar.rs new file mode 100644 index 0000000..70ef75d --- /dev/null +++ b/src/models/attribute_varchar.rs @@ -0,0 +1,152 @@ +//! AttributeVarchar model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// AttributeVarchar +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct AttributeVarchar { + /// Attribute Key. + #[serde(rename = "key")] + pub key: String, + /// Attribute type. + #[serde(rename = "type")] + pub r#type: String, + /// Attribute status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::AttributeStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an attribute. + #[serde(rename = "error")] + pub error: String, + /// Is attribute required? + #[serde(rename = "required")] + pub required: bool, + /// Is attribute an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Attribute creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Attribute update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Attribute size. + #[serde(rename = "size")] + pub size: i64, + /// Default value for attribute when not provided. Cannot be set when attribute + /// is required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this attribute is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl AttributeVarchar { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::AttributeStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get size + pub fn size(&self) -> &i64 { + &self.size + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_attribute_varchar_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.size(); + } + + #[test] + fn test_attribute_varchar_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/backup_archive.rs b/src/models/backup_archive.rs new file mode 100644 index 0000000..76619c0 --- /dev/null +++ b/src/models/backup_archive.rs @@ -0,0 +1,155 @@ +//! BackupArchive model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Archive +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BackupArchive { + /// Archive ID. + #[serde(rename = "$id")] + pub id: String, + /// Archive creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Archive update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Archive policy ID. + #[serde(rename = "policyId")] + pub policy_id: String, + /// Archive size in bytes. + #[serde(rename = "size")] + pub size: i64, + /// The status of the archive creation. Possible values: pending, processing, + /// uploading, completed, failed. + #[serde(rename = "status")] + pub status: String, + /// The backup start time. + #[serde(rename = "startedAt")] + pub started_at: String, + /// Migration ID. + #[serde(rename = "migrationId")] + pub migration_id: String, + /// The services that are backed up by this archive. + #[serde(rename = "services")] + pub services: Vec, + /// The resources that are backed up by this archive. + #[serde(rename = "resources")] + pub resources: Vec, + /// The resource ID to backup. Set only if this archive should backup a single + /// resource. + #[serde(rename = "resourceId")] + #[serde(skip_serializing_if = "Option::is_none")] + pub resource_id: Option, + /// The resource type to backup. Set only if this archive should backup a + /// single resource. + #[serde(rename = "resourceType")] + #[serde(skip_serializing_if = "Option::is_none")] + pub resource_type: Option, +} + +impl BackupArchive { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get policy_id + pub fn policy_id(&self) -> &String { + &self.policy_id + } + + /// Get size + pub fn size(&self) -> &i64 { + &self.size + } + + /// Get status + pub fn status(&self) -> &String { + &self.status + } + + /// Get started_at + pub fn started_at(&self) -> &String { + &self.started_at + } + + /// Get migration_id + pub fn migration_id(&self) -> &String { + &self.migration_id + } + + /// Get services + pub fn services(&self) -> &Vec { + &self.services + } + + /// Get resources + pub fn resources(&self) -> &Vec { + &self.resources + } + + /// Set resource_id + pub fn set_resource_id(mut self, resource_id: String) -> Self { + self.resource_id = Some(resource_id); + self + } + + /// Get resource_id + pub fn resource_id(&self) -> Option<&String> { + self.resource_id.as_ref() + } + + /// Set resource_type + pub fn set_resource_type(mut self, resource_type: String) -> Self { + self.resource_type = Some(resource_type); + self + } + + /// Get resource_type + pub fn resource_type(&self) -> Option<&String> { + self.resource_type.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backup_archive_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.policy_id(); + let _ = _model.size(); + let _ = _model.status(); + let _ = _model.started_at(); + let _ = _model.migration_id(); + let _ = _model.services(); + let _ = _model.resources(); + } + + #[test] + fn test_backup_archive_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/backup_archive_list.rs b/src/models/backup_archive_list.rs new file mode 100644 index 0000000..ca94c96 --- /dev/null +++ b/src/models/backup_archive_list.rs @@ -0,0 +1,50 @@ +//! BackupArchiveList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Backup archive list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BackupArchiveList { + /// Total number of archives that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of archives. + #[serde(rename = "archives")] + pub archives: Vec, +} + +impl BackupArchiveList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get archives + pub fn archives(&self) -> &Vec { + &self.archives + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backup_archive_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.archives(); + } + + #[test] + fn test_backup_archive_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/backup_policy.rs b/src/models/backup_policy.rs new file mode 100644 index 0000000..b0188fe --- /dev/null +++ b/src/models/backup_policy.rs @@ -0,0 +1,145 @@ +//! BackupPolicy model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// backup +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BackupPolicy { + /// Backup policy ID. + #[serde(rename = "$id")] + pub id: String, + /// Backup policy name. + #[serde(rename = "name")] + pub name: String, + /// Policy creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Policy update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// The services that are backed up by this policy. + #[serde(rename = "services")] + pub services: Vec, + /// The resources that are backed up by this policy. + #[serde(rename = "resources")] + pub resources: Vec, + /// The resource ID to backup. Set only if this policy should backup a single + /// resource. + #[serde(rename = "resourceId")] + #[serde(skip_serializing_if = "Option::is_none")] + pub resource_id: Option, + /// The resource type to backup. Set only if this policy should backup a single + /// resource. + #[serde(rename = "resourceType")] + #[serde(skip_serializing_if = "Option::is_none")] + pub resource_type: Option, + /// How many days to keep the backup before it will be automatically deleted. + #[serde(rename = "retention")] + pub retention: i64, + /// Policy backup schedule in CRON format. + #[serde(rename = "schedule")] + pub schedule: String, + /// Is this policy enabled. + #[serde(rename = "enabled")] + pub enabled: bool, +} + +impl BackupPolicy { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get services + pub fn services(&self) -> &Vec { + &self.services + } + + /// Get resources + pub fn resources(&self) -> &Vec { + &self.resources + } + + /// Set resource_id + pub fn set_resource_id(mut self, resource_id: String) -> Self { + self.resource_id = Some(resource_id); + self + } + + /// Get resource_id + pub fn resource_id(&self) -> Option<&String> { + self.resource_id.as_ref() + } + + /// Set resource_type + pub fn set_resource_type(mut self, resource_type: String) -> Self { + self.resource_type = Some(resource_type); + self + } + + /// Get resource_type + pub fn resource_type(&self) -> Option<&String> { + self.resource_type.as_ref() + } + + /// Get retention + pub fn retention(&self) -> &i64 { + &self.retention + } + + /// Get schedule + pub fn schedule(&self) -> &String { + &self.schedule + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backup_policy_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.name(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.services(); + let _ = _model.resources(); + let _ = _model.retention(); + let _ = _model.schedule(); + let _ = _model.enabled(); + } + + #[test] + fn test_backup_policy_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/backup_policy_list.rs b/src/models/backup_policy_list.rs new file mode 100644 index 0000000..07e5476 --- /dev/null +++ b/src/models/backup_policy_list.rs @@ -0,0 +1,50 @@ +//! BackupPolicyList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Backup policy list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BackupPolicyList { + /// Total number of policies that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of policies. + #[serde(rename = "policies")] + pub policies: Vec, +} + +impl BackupPolicyList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get policies + pub fn policies(&self) -> &Vec { + &self.policies + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backup_policy_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.policies(); + } + + #[test] + fn test_backup_policy_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/backup_restoration.rs b/src/models/backup_restoration.rs new file mode 100644 index 0000000..9fb005e --- /dev/null +++ b/src/models/backup_restoration.rs @@ -0,0 +1,132 @@ +//! BackupRestoration model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Restoration +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BackupRestoration { + /// Restoration ID. + #[serde(rename = "$id")] + pub id: String, + /// Restoration creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Restoration update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Backup archive ID. + #[serde(rename = "archiveId")] + pub archive_id: String, + /// Backup policy ID. + #[serde(rename = "policyId")] + pub policy_id: String, + /// The status of the restoration. Possible values: pending, downloading, + /// processing, completed, failed. + #[serde(rename = "status")] + pub status: String, + /// The backup start time. + #[serde(rename = "startedAt")] + pub started_at: String, + /// Migration ID. + #[serde(rename = "migrationId")] + pub migration_id: String, + /// The services that are backed up by this policy. + #[serde(rename = "services")] + pub services: Vec, + /// The resources that are backed up by this policy. + #[serde(rename = "resources")] + pub resources: Vec, + /// Optional data in key-value object. + #[serde(rename = "options")] + pub options: String, +} + +impl BackupRestoration { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get archive_id + pub fn archive_id(&self) -> &String { + &self.archive_id + } + + /// Get policy_id + pub fn policy_id(&self) -> &String { + &self.policy_id + } + + /// Get status + pub fn status(&self) -> &String { + &self.status + } + + /// Get started_at + pub fn started_at(&self) -> &String { + &self.started_at + } + + /// Get migration_id + pub fn migration_id(&self) -> &String { + &self.migration_id + } + + /// Get services + pub fn services(&self) -> &Vec { + &self.services + } + + /// Get resources + pub fn resources(&self) -> &Vec { + &self.resources + } + + /// Get options + pub fn options(&self) -> &String { + &self.options + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backup_restoration_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.archive_id(); + let _ = _model.policy_id(); + let _ = _model.status(); + let _ = _model.started_at(); + let _ = _model.migration_id(); + let _ = _model.services(); + let _ = _model.resources(); + let _ = _model.options(); + } + + #[test] + fn test_backup_restoration_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/backup_restoration_list.rs b/src/models/backup_restoration_list.rs new file mode 100644 index 0000000..6f33e1f --- /dev/null +++ b/src/models/backup_restoration_list.rs @@ -0,0 +1,50 @@ +//! BackupRestorationList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Backup restoration list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BackupRestorationList { + /// Total number of restorations that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of restorations. + #[serde(rename = "restorations")] + pub restorations: Vec, +} + +impl BackupRestorationList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get restorations + pub fn restorations(&self) -> &Vec { + &self.restorations + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backup_restoration_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.restorations(); + } + + #[test] + fn test_backup_restoration_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/bucket.rs b/src/models/bucket.rs new file mode 100644 index 0000000..150a3f4 --- /dev/null +++ b/src/models/bucket.rs @@ -0,0 +1,162 @@ +//! Bucket model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Bucket +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Bucket { + /// Bucket ID. + #[serde(rename = "$id")] + pub id: String, + /// Bucket creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Bucket update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Bucket permissions. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "$permissions")] + pub permissions: Vec, + /// Whether file-level security is enabled. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "fileSecurity")] + pub file_security: bool, + /// Bucket name. + #[serde(rename = "name")] + pub name: String, + /// Bucket enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Maximum file size supported. + #[serde(rename = "maximumFileSize")] + pub maximum_file_size: i64, + /// Allowed file extensions. + #[serde(rename = "allowedFileExtensions")] + pub allowed_file_extensions: Vec, + /// Compression algorithm chosen for compression. Will be one of none, + /// [gzip](https://en.wikipedia.org/wiki/Gzip), or + /// [zstd](https://en.wikipedia.org/wiki/Zstd). + #[serde(rename = "compression")] + pub compression: String, + /// Bucket is encrypted. + #[serde(rename = "encryption")] + pub encryption: bool, + /// Virus scanning is enabled. + #[serde(rename = "antivirus")] + pub antivirus: bool, + /// Image transformations are enabled. + #[serde(rename = "transformations")] + pub transformations: bool, + /// Total size of this bucket in bytes. + #[serde(rename = "totalSize")] + pub total_size: i64, +} + +impl Bucket { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + /// Get file_security + pub fn file_security(&self) -> &bool { + &self.file_security + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get maximum_file_size + pub fn maximum_file_size(&self) -> &i64 { + &self.maximum_file_size + } + + /// Get allowed_file_extensions + pub fn allowed_file_extensions(&self) -> &Vec { + &self.allowed_file_extensions + } + + /// Get compression + pub fn compression(&self) -> &String { + &self.compression + } + + /// Get encryption + pub fn encryption(&self) -> &bool { + &self.encryption + } + + /// Get antivirus + pub fn antivirus(&self) -> &bool { + &self.antivirus + } + + /// Get transformations + pub fn transformations(&self) -> &bool { + &self.transformations + } + + /// Get total_size + pub fn total_size(&self) -> &i64 { + &self.total_size + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bucket_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + let _ = _model.file_security(); + let _ = _model.name(); + let _ = _model.enabled(); + let _ = _model.maximum_file_size(); + let _ = _model.allowed_file_extensions(); + let _ = _model.compression(); + let _ = _model.encryption(); + let _ = _model.antivirus(); + let _ = _model.transformations(); + let _ = _model.total_size(); + } + + #[test] + fn test_bucket_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/bucket_list.rs b/src/models/bucket_list.rs new file mode 100644 index 0000000..6ac9e69 --- /dev/null +++ b/src/models/bucket_list.rs @@ -0,0 +1,50 @@ +//! BucketList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Buckets List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct BucketList { + /// Total number of buckets that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of buckets. + #[serde(rename = "buckets")] + pub buckets: Vec, +} + +impl BucketList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get buckets + pub fn buckets(&self) -> &Vec { + &self.buckets + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bucket_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.buckets(); + } + + #[test] + fn test_bucket_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/collection.rs b/src/models/collection.rs new file mode 100644 index 0000000..a1c6f2c --- /dev/null +++ b/src/models/collection.rs @@ -0,0 +1,144 @@ +//! Collection model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Collection +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Collection { + /// Collection ID. + #[serde(rename = "$id")] + pub id: String, + /// Collection creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Collection update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Collection permissions. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "$permissions")] + pub permissions: Vec, + /// Database ID. + #[serde(rename = "databaseId")] + pub database_id: String, + /// Collection name. + #[serde(rename = "name")] + pub name: String, + /// Collection enabled. Can be 'enabled' or 'disabled'. When disabled, the + /// collection is inaccessible to users, but remains accessible to Server SDKs + /// using API keys. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Whether document-level permissions are enabled. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "documentSecurity")] + pub document_security: bool, + /// Collection attributes. + #[serde(rename = "attributes")] + pub attributes: Vec, + /// Collection indexes. + #[serde(rename = "indexes")] + pub indexes: Vec, + /// Maximum document size in bytes. Returns 0 when no limit applies. + #[serde(rename = "bytesMax")] + pub bytes_max: i64, + /// Currently used document size in bytes based on defined attributes. + #[serde(rename = "bytesUsed")] + pub bytes_used: i64, +} + +impl Collection { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + /// Get database_id + pub fn database_id(&self) -> &String { + &self.database_id + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get document_security + pub fn document_security(&self) -> &bool { + &self.document_security + } + + /// Get attributes + pub fn attributes(&self) -> &Vec { + &self.attributes + } + + /// Get indexes + pub fn indexes(&self) -> &Vec { + &self.indexes + } + + /// Get bytes_max + pub fn bytes_max(&self) -> &i64 { + &self.bytes_max + } + + /// Get bytes_used + pub fn bytes_used(&self) -> &i64 { + &self.bytes_used + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_collection_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + let _ = _model.database_id(); + let _ = _model.name(); + let _ = _model.enabled(); + let _ = _model.document_security(); + let _ = _model.attributes(); + let _ = _model.indexes(); + let _ = _model.bytes_max(); + let _ = _model.bytes_used(); + } + + #[test] + fn test_collection_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/collection_list.rs b/src/models/collection_list.rs new file mode 100644 index 0000000..a7dbff7 --- /dev/null +++ b/src/models/collection_list.rs @@ -0,0 +1,50 @@ +//! CollectionList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Collections List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct CollectionList { + /// Total number of collections that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of collections. + #[serde(rename = "collections")] + pub collections: Vec, +} + +impl CollectionList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get collections + pub fn collections(&self) -> &Vec { + &self.collections + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_collection_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.collections(); + } + + #[test] + fn test_collection_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_boolean.rs b/src/models/column_boolean.rs new file mode 100644 index 0000000..8ddb729 --- /dev/null +++ b/src/models/column_boolean.rs @@ -0,0 +1,128 @@ +//! ColumnBoolean model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnBoolean +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnBoolean { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnBoolean { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: bool) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&bool> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_boolean_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_boolean_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_datetime.rs b/src/models/column_datetime.rs new file mode 100644 index 0000000..fcda790 --- /dev/null +++ b/src/models/column_datetime.rs @@ -0,0 +1,136 @@ +//! ColumnDatetime model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnDatetime +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnDatetime { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// ISO 8601 format. + #[serde(rename = "format")] + pub format: String, + /// Default value for column when not provided. Only null is optional + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnDatetime { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_datetime_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_column_datetime_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_email.rs b/src/models/column_email.rs new file mode 100644 index 0000000..b2b8c50 --- /dev/null +++ b/src/models/column_email.rs @@ -0,0 +1,137 @@ +//! ColumnEmail model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnEmail +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnEmail { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnEmail { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_email_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_column_email_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_enum.rs b/src/models/column_enum.rs new file mode 100644 index 0000000..cb9e825 --- /dev/null +++ b/src/models/column_enum.rs @@ -0,0 +1,146 @@ +//! ColumnEnum model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnEnum +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnEnum { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Array of elements in enumerated type. + #[serde(rename = "elements")] + pub elements: Vec, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnEnum { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get elements + pub fn elements(&self) -> &Vec { + &self.elements + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_enum_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.elements(); + let _ = _model.format(); + } + + #[test] + fn test_column_enum_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_float.rs b/src/models/column_float.rs new file mode 100644 index 0000000..1074251 --- /dev/null +++ b/src/models/column_float.rs @@ -0,0 +1,158 @@ +//! ColumnFloat model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnFloat +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnFloat { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Minimum value to enforce for new documents. + #[serde(rename = "min")] + #[serde(skip_serializing_if = "Option::is_none")] + pub min: Option, + /// Maximum value to enforce for new documents. + #[serde(rename = "max")] + #[serde(skip_serializing_if = "Option::is_none")] + pub max: Option, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnFloat { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set min + pub fn set_min(mut self, min: f64) -> Self { + self.min = Some(min); + self + } + + /// Get min + pub fn min(&self) -> Option<&f64> { + self.min.as_ref() + } + + /// Set max + pub fn set_max(mut self, max: f64) -> Self { + self.max = Some(max); + self + } + + /// Get max + pub fn max(&self) -> Option<&f64> { + self.max.as_ref() + } + + /// Set default + pub fn set_default(mut self, default: f64) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&f64> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_float_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_float_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_index.rs b/src/models/column_index.rs new file mode 100644 index 0000000..09961f0 --- /dev/null +++ b/src/models/column_index.rs @@ -0,0 +1,130 @@ +//! ColumnIndex model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Index +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnIndex { + /// Index ID. + #[serde(rename = "$id")] + pub id: String, + /// Index creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Index update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Index Key. + #[serde(rename = "key")] + pub key: String, + /// Index type. + #[serde(rename = "type")] + pub r#type: String, + /// Index status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: String, + /// Error message. Displays error generated on failure of creating or deleting + /// an index. + #[serde(rename = "error")] + pub error: String, + /// Index columns. + #[serde(rename = "columns")] + pub columns: Vec, + /// Index columns length. + #[serde(rename = "lengths")] + pub lengths: Vec, + /// Index orders. + #[serde(rename = "orders")] + #[serde(skip_serializing_if = "Option::is_none")] + pub orders: Option>, +} + +impl ColumnIndex { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &String { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get columns + pub fn columns(&self) -> &Vec { + &self.columns + } + + /// Get lengths + pub fn lengths(&self) -> &Vec { + &self.lengths + } + + /// Set orders + pub fn set_orders(mut self, orders: Vec) -> Self { + self.orders = Some(orders); + self + } + + /// Get orders + pub fn orders(&self) -> Option<&Vec> { + self.orders.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_index_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.columns(); + let _ = _model.lengths(); + } + + #[test] + fn test_column_index_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_index_list.rs b/src/models/column_index_list.rs new file mode 100644 index 0000000..815f606 --- /dev/null +++ b/src/models/column_index_list.rs @@ -0,0 +1,50 @@ +//! ColumnIndexList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Column Indexes List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnIndexList { + /// Total number of indexes that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of indexes. + #[serde(rename = "indexes")] + pub indexes: Vec, +} + +impl ColumnIndexList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get indexes + pub fn indexes(&self) -> &Vec { + &self.indexes + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_index_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.indexes(); + } + + #[test] + fn test_column_index_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_integer.rs b/src/models/column_integer.rs new file mode 100644 index 0000000..f50fdf0 --- /dev/null +++ b/src/models/column_integer.rs @@ -0,0 +1,158 @@ +//! ColumnInteger model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnInteger +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnInteger { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Minimum value to enforce for new documents. + #[serde(rename = "min")] + #[serde(skip_serializing_if = "Option::is_none")] + pub min: Option, + /// Maximum value to enforce for new documents. + #[serde(rename = "max")] + #[serde(skip_serializing_if = "Option::is_none")] + pub max: Option, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnInteger { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set min + pub fn set_min(mut self, min: i64) -> Self { + self.min = Some(min); + self + } + + /// Get min + pub fn min(&self) -> Option<&i64> { + self.min.as_ref() + } + + /// Set max + pub fn set_max(mut self, max: i64) -> Self { + self.max = Some(max); + self + } + + /// Get max + pub fn max(&self) -> Option<&i64> { + self.max.as_ref() + } + + /// Set default + pub fn set_default(mut self, default: i64) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&i64> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_integer_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_integer_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_ip.rs b/src/models/column_ip.rs new file mode 100644 index 0000000..17130c9 --- /dev/null +++ b/src/models/column_ip.rs @@ -0,0 +1,137 @@ +//! ColumnIp model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnIP +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnIp { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnIp { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_ip_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_column_ip_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_line.rs b/src/models/column_line.rs new file mode 100644 index 0000000..adbca90 --- /dev/null +++ b/src/models/column_line.rs @@ -0,0 +1,128 @@ +//! ColumnLine model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnLine +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnLine { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, +} + +impl ColumnLine { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: Vec) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&Vec> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_line_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_line_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_list.rs b/src/models/column_list.rs new file mode 100644 index 0000000..51d4d43 --- /dev/null +++ b/src/models/column_list.rs @@ -0,0 +1,50 @@ +//! ColumnList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Columns List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnList { + /// Total number of columns in the given table. + #[serde(rename = "total")] + pub total: i64, + /// List of columns. + #[serde(rename = "columns")] + pub columns: Vec, +} + +impl ColumnList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get columns + pub fn columns(&self) -> &Vec { + &self.columns + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.columns(); + } + + #[test] + fn test_column_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_longtext.rs b/src/models/column_longtext.rs new file mode 100644 index 0000000..4f4cc68 --- /dev/null +++ b/src/models/column_longtext.rs @@ -0,0 +1,143 @@ +//! ColumnLongtext model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnLongtext +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnLongtext { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this column is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl ColumnLongtext { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_longtext_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_longtext_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_mediumtext.rs b/src/models/column_mediumtext.rs new file mode 100644 index 0000000..905b798 --- /dev/null +++ b/src/models/column_mediumtext.rs @@ -0,0 +1,143 @@ +//! ColumnMediumtext model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnMediumtext +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnMediumtext { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this column is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl ColumnMediumtext { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_mediumtext_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_mediumtext_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_point.rs b/src/models/column_point.rs new file mode 100644 index 0000000..b0bb35f --- /dev/null +++ b/src/models/column_point.rs @@ -0,0 +1,128 @@ +//! ColumnPoint model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnPoint +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnPoint { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, +} + +impl ColumnPoint { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: Vec) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&Vec> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_point_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_point_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_polygon.rs b/src/models/column_polygon.rs new file mode 100644 index 0000000..c3f323c --- /dev/null +++ b/src/models/column_polygon.rs @@ -0,0 +1,128 @@ +//! ColumnPolygon model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnPolygon +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnPolygon { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, +} + +impl ColumnPolygon { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: Vec) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&Vec> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_polygon_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_polygon_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_relationship.rs b/src/models/column_relationship.rs new file mode 100644 index 0000000..7281849 --- /dev/null +++ b/src/models/column_relationship.rs @@ -0,0 +1,166 @@ +//! ColumnRelationship model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnRelationship +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnRelationship { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// The ID of the related table. + #[serde(rename = "relatedTable")] + pub related_table: String, + /// The type of the relationship. + #[serde(rename = "relationType")] + pub relation_type: String, + /// Is the relationship two-way? + #[serde(rename = "twoWay")] + pub two_way: bool, + /// The key of the two-way relationship. + #[serde(rename = "twoWayKey")] + pub two_way_key: String, + /// How deleting the parent document will propagate to child documents. + #[serde(rename = "onDelete")] + pub on_delete: String, + /// Whether this is the parent or child side of the relationship + #[serde(rename = "side")] + pub side: String, +} + +impl ColumnRelationship { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get related_table + pub fn related_table(&self) -> &String { + &self.related_table + } + + /// Get relation_type + pub fn relation_type(&self) -> &String { + &self.relation_type + } + + /// Get two_way + pub fn two_way(&self) -> &bool { + &self.two_way + } + + /// Get two_way_key + pub fn two_way_key(&self) -> &String { + &self.two_way_key + } + + /// Get on_delete + pub fn on_delete(&self) -> &String { + &self.on_delete + } + + /// Get side + pub fn side(&self) -> &String { + &self.side + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_relationship_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.related_table(); + let _ = _model.relation_type(); + let _ = _model.two_way(); + let _ = _model.two_way_key(); + let _ = _model.on_delete(); + let _ = _model.side(); + } + + #[test] + fn test_column_relationship_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_string.rs b/src/models/column_string.rs new file mode 100644 index 0000000..77c0844 --- /dev/null +++ b/src/models/column_string.rs @@ -0,0 +1,152 @@ +//! ColumnString model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnString +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnString { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Column size. + #[serde(rename = "size")] + pub size: i64, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this column is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl ColumnString { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get size + pub fn size(&self) -> &i64 { + &self.size + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_string_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.size(); + } + + #[test] + fn test_column_string_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_text.rs b/src/models/column_text.rs new file mode 100644 index 0000000..bb65f36 --- /dev/null +++ b/src/models/column_text.rs @@ -0,0 +1,143 @@ +//! ColumnText model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnText +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnText { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this column is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl ColumnText { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_text_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + } + + #[test] + fn test_column_text_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_url.rs b/src/models/column_url.rs new file mode 100644 index 0000000..9dbf22e --- /dev/null +++ b/src/models/column_url.rs @@ -0,0 +1,137 @@ +//! ColumnUrl model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnURL +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnUrl { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// String format. + #[serde(rename = "format")] + pub format: String, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, +} + +impl ColumnUrl { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get format + pub fn format(&self) -> &String { + &self.format + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_url_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.format(); + } + + #[test] + fn test_column_url_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/column_varchar.rs b/src/models/column_varchar.rs new file mode 100644 index 0000000..2e4e2b9 --- /dev/null +++ b/src/models/column_varchar.rs @@ -0,0 +1,152 @@ +//! ColumnVarchar model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ColumnVarchar +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ColumnVarchar { + /// Column Key. + #[serde(rename = "key")] + pub key: String, + /// Column type. + #[serde(rename = "type")] + pub r#type: String, + /// Column status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::ColumnStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an column. + #[serde(rename = "error")] + pub error: String, + /// Is column required? + #[serde(rename = "required")] + pub required: bool, + /// Is column an array? + #[serde(rename = "array")] + #[serde(skip_serializing_if = "Option::is_none")] + pub array: Option, + /// Column creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Column update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Column size. + #[serde(rename = "size")] + pub size: i64, + /// Default value for column when not provided. Cannot be set when column is + /// required. + #[serde(rename = "default")] + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Defines whether this column is encrypted or not. + #[serde(rename = "encrypt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub encrypt: Option, +} + +impl ColumnVarchar { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::ColumnStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get required + pub fn required(&self) -> &bool { + &self.required + } + + /// Set array + pub fn set_array(mut self, array: bool) -> Self { + self.array = Some(array); + self + } + + /// Get array + pub fn array(&self) -> Option<&bool> { + self.array.as_ref() + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get size + pub fn size(&self) -> &i64 { + &self.size + } + + /// Set default + pub fn set_default(mut self, default: String) -> Self { + self.default = Some(default); + self + } + + /// Get default + pub fn default(&self) -> Option<&String> { + self.default.as_ref() + } + + /// Set encrypt + pub fn set_encrypt(mut self, encrypt: bool) -> Self { + self.encrypt = Some(encrypt); + self + } + + /// Get encrypt + pub fn encrypt(&self) -> Option<&bool> { + self.encrypt.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_column_varchar_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.required(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.size(); + } + + #[test] + fn test_column_varchar_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/continent.rs b/src/models/continent.rs new file mode 100644 index 0000000..3c6606e --- /dev/null +++ b/src/models/continent.rs @@ -0,0 +1,50 @@ +//! Continent model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Continent +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Continent { + /// Continent name. + #[serde(rename = "name")] + pub name: String, + /// Continent two letter code. + #[serde(rename = "code")] + pub code: String, +} + +impl Continent { + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get code + pub fn code(&self) -> &String { + &self.code + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_continent_creation() { + let _model = ::default(); + let _ = _model.name(); + let _ = _model.code(); + } + + #[test] + fn test_continent_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/continent_list.rs b/src/models/continent_list.rs new file mode 100644 index 0000000..0dd6abe --- /dev/null +++ b/src/models/continent_list.rs @@ -0,0 +1,50 @@ +//! ContinentList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Continents List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ContinentList { + /// Total number of continents that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of continents. + #[serde(rename = "continents")] + pub continents: Vec, +} + +impl ContinentList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get continents + pub fn continents(&self) -> &Vec { + &self.continents + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_continent_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.continents(); + } + + #[test] + fn test_continent_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/country.rs b/src/models/country.rs new file mode 100644 index 0000000..dd91dd6 --- /dev/null +++ b/src/models/country.rs @@ -0,0 +1,50 @@ +//! Country model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Country +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Country { + /// Country name. + #[serde(rename = "name")] + pub name: String, + /// Country two-character ISO 3166-1 alpha code. + #[serde(rename = "code")] + pub code: String, +} + +impl Country { + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get code + pub fn code(&self) -> &String { + &self.code + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_country_creation() { + let _model = ::default(); + let _ = _model.name(); + let _ = _model.code(); + } + + #[test] + fn test_country_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/country_list.rs b/src/models/country_list.rs new file mode 100644 index 0000000..e056c22 --- /dev/null +++ b/src/models/country_list.rs @@ -0,0 +1,50 @@ +//! CountryList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Countries List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct CountryList { + /// Total number of countries that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of countries. + #[serde(rename = "countries")] + pub countries: Vec, +} + +impl CountryList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get countries + pub fn countries(&self) -> &Vec { + &self.countries + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_country_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.countries(); + } + + #[test] + fn test_country_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/currency.rs b/src/models/currency.rs new file mode 100644 index 0000000..0418f97 --- /dev/null +++ b/src/models/currency.rs @@ -0,0 +1,96 @@ +//! Currency model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Currency +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Currency { + /// Currency symbol. + #[serde(rename = "symbol")] + pub symbol: String, + /// Currency name. + #[serde(rename = "name")] + pub name: String, + /// Currency native symbol. + #[serde(rename = "symbolNative")] + pub symbol_native: String, + /// Number of decimal digits. + #[serde(rename = "decimalDigits")] + pub decimal_digits: i64, + /// Currency digit rounding. + #[serde(rename = "rounding")] + pub rounding: f64, + /// Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) + /// three-character format. + #[serde(rename = "code")] + pub code: String, + /// Currency plural name + #[serde(rename = "namePlural")] + pub name_plural: String, +} + +impl Currency { + /// Get symbol + pub fn symbol(&self) -> &String { + &self.symbol + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get symbol_native + pub fn symbol_native(&self) -> &String { + &self.symbol_native + } + + /// Get decimal_digits + pub fn decimal_digits(&self) -> &i64 { + &self.decimal_digits + } + + /// Get rounding + pub fn rounding(&self) -> &f64 { + &self.rounding + } + + /// Get code + pub fn code(&self) -> &String { + &self.code + } + + /// Get name_plural + pub fn name_plural(&self) -> &String { + &self.name_plural + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_currency_creation() { + let _model = ::default(); + let _ = _model.symbol(); + let _ = _model.name(); + let _ = _model.symbol_native(); + let _ = _model.decimal_digits(); + let _ = _model.rounding(); + let _ = _model.code(); + let _ = _model.name_plural(); + } + + #[test] + fn test_currency_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/currency_list.rs b/src/models/currency_list.rs new file mode 100644 index 0000000..5ba2a2f --- /dev/null +++ b/src/models/currency_list.rs @@ -0,0 +1,50 @@ +//! CurrencyList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Currencies List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct CurrencyList { + /// Total number of currencies that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of currencies. + #[serde(rename = "currencies")] + pub currencies: Vec, +} + +impl CurrencyList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get currencies + pub fn currencies(&self) -> &Vec { + &self.currencies + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_currency_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.currencies(); + } + + #[test] + fn test_currency_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/database.rs b/src/models/database.rs new file mode 100644 index 0000000..0f81ee1 --- /dev/null +++ b/src/models/database.rs @@ -0,0 +1,106 @@ +//! Database model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Database +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Database { + /// Database ID. + #[serde(rename = "$id")] + pub id: String, + /// Database name. + #[serde(rename = "name")] + pub name: String, + /// Database creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Database update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// If database is enabled. Can be 'enabled' or 'disabled'. When disabled, the + /// database is inaccessible to users, but remains accessible to Server SDKs + /// using API keys. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Database type. + #[serde(rename = "type")] + pub r#type: crate::enums::DatabaseType, + /// Database backup policies. + #[serde(rename = "policies")] + pub policies: Vec, + /// Database backup archives. + #[serde(rename = "archives")] + pub archives: Vec, +} + +impl Database { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get r#type + pub fn r#type(&self) -> &crate::enums::DatabaseType { + &self.r#type + } + + /// Get policies + pub fn policies(&self) -> &Vec { + &self.policies + } + + /// Get archives + pub fn archives(&self) -> &Vec { + &self.archives + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_database_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.name(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.enabled(); + let _ = _model.r#type(); + let _ = _model.policies(); + let _ = _model.archives(); + } + + #[test] + fn test_database_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/database_list.rs b/src/models/database_list.rs new file mode 100644 index 0000000..d7f6614 --- /dev/null +++ b/src/models/database_list.rs @@ -0,0 +1,50 @@ +//! DatabaseList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Databases List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct DatabaseList { + /// Total number of databases that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of databases. + #[serde(rename = "databases")] + pub databases: Vec, +} + +impl DatabaseList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get databases + pub fn databases(&self) -> &Vec { + &self.databases + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_database_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.databases(); + } + + #[test] + fn test_database_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/deployment.rs b/src/models/deployment.rs new file mode 100644 index 0000000..7d05805 --- /dev/null +++ b/src/models/deployment.rs @@ -0,0 +1,276 @@ +//! Deployment model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Deployment +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Deployment { + /// Deployment ID. + #[serde(rename = "$id")] + pub id: String, + /// Deployment creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Deployment update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Type of deployment. + #[serde(rename = "type")] + pub r#type: String, + /// Resource ID. + #[serde(rename = "resourceId")] + pub resource_id: String, + /// Resource type. + #[serde(rename = "resourceType")] + pub resource_type: String, + /// The entrypoint file to use to execute the deployment code. + #[serde(rename = "entrypoint")] + pub entrypoint: String, + /// The code size in bytes. + #[serde(rename = "sourceSize")] + pub source_size: i64, + /// The build output size in bytes. + #[serde(rename = "buildSize")] + pub build_size: i64, + /// The total size in bytes (source and build output). + #[serde(rename = "totalSize")] + pub total_size: i64, + /// The current build ID. + #[serde(rename = "buildId")] + pub build_id: String, + /// Whether the deployment should be automatically activated. + #[serde(rename = "activate")] + pub activate: bool, + /// Screenshot with light theme preference file ID. + #[serde(rename = "screenshotLight")] + pub screenshot_light: String, + /// Screenshot with dark theme preference file ID. + #[serde(rename = "screenshotDark")] + pub screenshot_dark: String, + /// The deployment status. Possible values are "waiting", "processing", + /// "building", "ready", "canceled" and "failed". + #[serde(rename = "status")] + pub status: crate::enums::DeploymentStatus, + /// The build logs. + #[serde(rename = "buildLogs")] + pub build_logs: String, + /// The current build time in seconds. + #[serde(rename = "buildDuration")] + pub build_duration: i64, + /// The name of the vcs provider repository + #[serde(rename = "providerRepositoryName")] + pub provider_repository_name: String, + /// The name of the vcs provider repository owner + #[serde(rename = "providerRepositoryOwner")] + pub provider_repository_owner: String, + /// The url of the vcs provider repository + #[serde(rename = "providerRepositoryUrl")] + pub provider_repository_url: String, + /// The commit hash of the vcs commit + #[serde(rename = "providerCommitHash")] + pub provider_commit_hash: String, + /// The url of vcs commit author + #[serde(rename = "providerCommitAuthorUrl")] + pub provider_commit_author_url: String, + /// The name of vcs commit author + #[serde(rename = "providerCommitAuthor")] + pub provider_commit_author: String, + /// The commit message + #[serde(rename = "providerCommitMessage")] + pub provider_commit_message: String, + /// The url of the vcs commit + #[serde(rename = "providerCommitUrl")] + pub provider_commit_url: String, + /// The branch of the vcs repository + #[serde(rename = "providerBranch")] + pub provider_branch: String, + /// The branch of the vcs repository + #[serde(rename = "providerBranchUrl")] + pub provider_branch_url: String, +} + +impl Deployment { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get resource_id + pub fn resource_id(&self) -> &String { + &self.resource_id + } + + /// Get resource_type + pub fn resource_type(&self) -> &String { + &self.resource_type + } + + /// Get entrypoint + pub fn entrypoint(&self) -> &String { + &self.entrypoint + } + + /// Get source_size + pub fn source_size(&self) -> &i64 { + &self.source_size + } + + /// Get build_size + pub fn build_size(&self) -> &i64 { + &self.build_size + } + + /// Get total_size + pub fn total_size(&self) -> &i64 { + &self.total_size + } + + /// Get build_id + pub fn build_id(&self) -> &String { + &self.build_id + } + + /// Get activate + pub fn activate(&self) -> &bool { + &self.activate + } + + /// Get screenshot_light + pub fn screenshot_light(&self) -> &String { + &self.screenshot_light + } + + /// Get screenshot_dark + pub fn screenshot_dark(&self) -> &String { + &self.screenshot_dark + } + + /// Get status + pub fn status(&self) -> &crate::enums::DeploymentStatus { + &self.status + } + + /// Get build_logs + pub fn build_logs(&self) -> &String { + &self.build_logs + } + + /// Get build_duration + pub fn build_duration(&self) -> &i64 { + &self.build_duration + } + + /// Get provider_repository_name + pub fn provider_repository_name(&self) -> &String { + &self.provider_repository_name + } + + /// Get provider_repository_owner + pub fn provider_repository_owner(&self) -> &String { + &self.provider_repository_owner + } + + /// Get provider_repository_url + pub fn provider_repository_url(&self) -> &String { + &self.provider_repository_url + } + + /// Get provider_commit_hash + pub fn provider_commit_hash(&self) -> &String { + &self.provider_commit_hash + } + + /// Get provider_commit_author_url + pub fn provider_commit_author_url(&self) -> &String { + &self.provider_commit_author_url + } + + /// Get provider_commit_author + pub fn provider_commit_author(&self) -> &String { + &self.provider_commit_author + } + + /// Get provider_commit_message + pub fn provider_commit_message(&self) -> &String { + &self.provider_commit_message + } + + /// Get provider_commit_url + pub fn provider_commit_url(&self) -> &String { + &self.provider_commit_url + } + + /// Get provider_branch + pub fn provider_branch(&self) -> &String { + &self.provider_branch + } + + /// Get provider_branch_url + pub fn provider_branch_url(&self) -> &String { + &self.provider_branch_url + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deployment_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.r#type(); + let _ = _model.resource_id(); + let _ = _model.resource_type(); + let _ = _model.entrypoint(); + let _ = _model.source_size(); + let _ = _model.build_size(); + let _ = _model.total_size(); + let _ = _model.build_id(); + let _ = _model.activate(); + let _ = _model.screenshot_light(); + let _ = _model.screenshot_dark(); + let _ = _model.status(); + let _ = _model.build_logs(); + let _ = _model.build_duration(); + let _ = _model.provider_repository_name(); + let _ = _model.provider_repository_owner(); + let _ = _model.provider_repository_url(); + let _ = _model.provider_commit_hash(); + let _ = _model.provider_commit_author_url(); + let _ = _model.provider_commit_author(); + let _ = _model.provider_commit_message(); + let _ = _model.provider_commit_url(); + let _ = _model.provider_branch(); + let _ = _model.provider_branch_url(); + } + + #[test] + fn test_deployment_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/deployment_list.rs b/src/models/deployment_list.rs new file mode 100644 index 0000000..e93a127 --- /dev/null +++ b/src/models/deployment_list.rs @@ -0,0 +1,50 @@ +//! DeploymentList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Deployments List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct DeploymentList { + /// Total number of deployments that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of deployments. + #[serde(rename = "deployments")] + pub deployments: Vec, +} + +impl DeploymentList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get deployments + pub fn deployments(&self) -> &Vec { + &self.deployments + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deployment_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.deployments(); + } + + #[test] + fn test_deployment_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/document.rs b/src/models/document.rs new file mode 100644 index 0000000..48be74c --- /dev/null +++ b/src/models/document.rs @@ -0,0 +1,109 @@ +//! Document model for Appwrite SDK + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Document +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Document { + /// Document ID. + #[serde(rename = "$id")] + pub id: String, + /// Document sequence ID. + #[serde(rename = "$sequence")] + pub sequence: String, + /// Collection ID. + #[serde(rename = "$collectionId")] + pub collection_id: String, + /// Database ID. + #[serde(rename = "$databaseId")] + pub database_id: String, + /// Document creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Document update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Document permissions. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "$permissions")] + pub permissions: Vec, + + #[serde(flatten)] + pub data: HashMap, +} + +impl Document { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get sequence + pub fn sequence(&self) -> &String { + &self.sequence + } + + /// Get collection_id + pub fn collection_id(&self) -> &String { + &self.collection_id + } + + /// Get database_id + pub fn database_id(&self) -> &String { + &self.database_id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + + pub fn get(&self, key: &str) -> Option { + self.data.get(key) + .and_then(|v| serde_json::from_value(v.clone()).ok()) + } + + pub fn data(&self) -> &HashMap { + &self.data + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_document_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.sequence(); + let _ = _model.collection_id(); + let _ = _model.database_id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + } + + #[test] + fn test_document_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/document_list.rs b/src/models/document_list.rs new file mode 100644 index 0000000..ca513ad --- /dev/null +++ b/src/models/document_list.rs @@ -0,0 +1,50 @@ +//! DocumentList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Documents List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct DocumentList { + /// Total number of documents that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of documents. + #[serde(rename = "documents")] + pub documents: Vec, +} + +impl DocumentList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get documents + pub fn documents(&self) -> &Vec { + &self.documents + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_document_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.documents(); + } + + #[test] + fn test_document_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/execution.rs b/src/models/execution.rs new file mode 100644 index 0000000..171b7a6 --- /dev/null +++ b/src/models/execution.rs @@ -0,0 +1,212 @@ +//! Execution model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Execution +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Execution { + /// Execution ID. + #[serde(rename = "$id")] + pub id: String, + /// Execution creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Execution update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Execution roles. + #[serde(rename = "$permissions")] + pub permissions: Vec, + /// Function ID. + #[serde(rename = "functionId")] + pub function_id: String, + /// Function's deployment ID used to create the execution. + #[serde(rename = "deploymentId")] + pub deployment_id: String, + /// The trigger that caused the function to execute. Possible values can be: + /// `http`, `schedule`, or `event`. + #[serde(rename = "trigger")] + pub trigger: crate::enums::ExecutionTrigger, + /// The status of the function execution. Possible values can be: `waiting`, + /// `processing`, `completed`, `failed`, or `scheduled`. + #[serde(rename = "status")] + pub status: crate::enums::ExecutionStatus, + /// HTTP request method type. + #[serde(rename = "requestMethod")] + pub request_method: String, + /// HTTP request path and query. + #[serde(rename = "requestPath")] + pub request_path: String, + /// HTTP request headers as a key-value object. This will return only + /// whitelisted headers. All headers are returned if execution is created as + /// synchronous. + #[serde(rename = "requestHeaders")] + pub request_headers: Vec, + /// HTTP response status code. + #[serde(rename = "responseStatusCode")] + pub response_status_code: i64, + /// HTTP response body. This will return empty unless execution is created as + /// synchronous. + #[serde(rename = "responseBody")] + pub response_body: String, + /// HTTP response headers as a key-value object. This will return only + /// whitelisted headers. All headers are returned if execution is created as + /// synchronous. + #[serde(rename = "responseHeaders")] + pub response_headers: Vec, + /// Function logs. Includes the last 4,000 characters. This will return an + /// empty string unless the response is returned using an API key or as part of + /// a webhook payload. + #[serde(rename = "logs")] + pub logs: String, + /// Function errors. Includes the last 4,000 characters. This will return an + /// empty string unless the response is returned using an API key or as part of + /// a webhook payload. + #[serde(rename = "errors")] + pub errors: String, + /// Resource(function/site) execution duration in seconds. + #[serde(rename = "duration")] + pub duration: f64, + /// The scheduled time for execution. If left empty, execution will be queued + /// immediately. + #[serde(rename = "scheduledAt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub scheduled_at: Option, +} + +impl Execution { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + /// Get function_id + pub fn function_id(&self) -> &String { + &self.function_id + } + + /// Get deployment_id + pub fn deployment_id(&self) -> &String { + &self.deployment_id + } + + /// Get trigger + pub fn trigger(&self) -> &crate::enums::ExecutionTrigger { + &self.trigger + } + + /// Get status + pub fn status(&self) -> &crate::enums::ExecutionStatus { + &self.status + } + + /// Get request_method + pub fn request_method(&self) -> &String { + &self.request_method + } + + /// Get request_path + pub fn request_path(&self) -> &String { + &self.request_path + } + + /// Get request_headers + pub fn request_headers(&self) -> &Vec { + &self.request_headers + } + + /// Get response_status_code + pub fn response_status_code(&self) -> &i64 { + &self.response_status_code + } + + /// Get response_body + pub fn response_body(&self) -> &String { + &self.response_body + } + + /// Get response_headers + pub fn response_headers(&self) -> &Vec { + &self.response_headers + } + + /// Get logs + pub fn logs(&self) -> &String { + &self.logs + } + + /// Get errors + pub fn errors(&self) -> &String { + &self.errors + } + + /// Get duration + pub fn duration(&self) -> &f64 { + &self.duration + } + + /// Set scheduled_at + pub fn set_scheduled_at(mut self, scheduled_at: String) -> Self { + self.scheduled_at = Some(scheduled_at); + self + } + + /// Get scheduled_at + pub fn scheduled_at(&self) -> Option<&String> { + self.scheduled_at.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_execution_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + let _ = _model.function_id(); + let _ = _model.deployment_id(); + let _ = _model.trigger(); + let _ = _model.status(); + let _ = _model.request_method(); + let _ = _model.request_path(); + let _ = _model.request_headers(); + let _ = _model.response_status_code(); + let _ = _model.response_body(); + let _ = _model.response_headers(); + let _ = _model.logs(); + let _ = _model.errors(); + let _ = _model.duration(); + } + + #[test] + fn test_execution_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/execution_list.rs b/src/models/execution_list.rs new file mode 100644 index 0000000..0066b37 --- /dev/null +++ b/src/models/execution_list.rs @@ -0,0 +1,50 @@ +//! ExecutionList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Executions List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ExecutionList { + /// Total number of executions that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of executions. + #[serde(rename = "executions")] + pub executions: Vec, +} + +impl ExecutionList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get executions + pub fn executions(&self) -> &Vec { + &self.executions + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_execution_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.executions(); + } + + #[test] + fn test_execution_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/file.rs b/src/models/file.rs new file mode 100644 index 0000000..c4d0c65 --- /dev/null +++ b/src/models/file.rs @@ -0,0 +1,152 @@ +//! File model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// File +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct File { + /// File ID. + #[serde(rename = "$id")] + pub id: String, + /// Bucket ID. + #[serde(rename = "bucketId")] + pub bucket_id: String, + /// File creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// File update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// File permissions. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "$permissions")] + pub permissions: Vec, + /// File name. + #[serde(rename = "name")] + pub name: String, + /// File MD5 signature. + #[serde(rename = "signature")] + pub signature: String, + /// File mime type. + #[serde(rename = "mimeType")] + pub mime_type: String, + /// File original size in bytes. + #[serde(rename = "sizeOriginal")] + pub size_original: i64, + /// Total number of chunks available + #[serde(rename = "chunksTotal")] + pub chunks_total: i64, + /// Total number of chunks uploaded + #[serde(rename = "chunksUploaded")] + pub chunks_uploaded: i64, + /// Whether file contents are encrypted at rest. + #[serde(rename = "encryption")] + pub encryption: bool, + /// Compression algorithm used for the file. Will be one of none, + /// [gzip](https://en.wikipedia.org/wiki/Gzip), or + /// [zstd](https://en.wikipedia.org/wiki/Zstd). + #[serde(rename = "compression")] + pub compression: String, +} + +impl File { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get bucket_id + pub fn bucket_id(&self) -> &String { + &self.bucket_id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get signature + pub fn signature(&self) -> &String { + &self.signature + } + + /// Get mime_type + pub fn mime_type(&self) -> &String { + &self.mime_type + } + + /// Get size_original + pub fn size_original(&self) -> &i64 { + &self.size_original + } + + /// Get chunks_total + pub fn chunks_total(&self) -> &i64 { + &self.chunks_total + } + + /// Get chunks_uploaded + pub fn chunks_uploaded(&self) -> &i64 { + &self.chunks_uploaded + } + + /// Get encryption + pub fn encryption(&self) -> &bool { + &self.encryption + } + + /// Get compression + pub fn compression(&self) -> &String { + &self.compression + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_file_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.bucket_id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + let _ = _model.name(); + let _ = _model.signature(); + let _ = _model.mime_type(); + let _ = _model.size_original(); + let _ = _model.chunks_total(); + let _ = _model.chunks_uploaded(); + let _ = _model.encryption(); + let _ = _model.compression(); + } + + #[test] + fn test_file_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/file_list.rs b/src/models/file_list.rs new file mode 100644 index 0000000..0a5ae54 --- /dev/null +++ b/src/models/file_list.rs @@ -0,0 +1,50 @@ +//! FileList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Files List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct FileList { + /// Total number of files that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of files. + #[serde(rename = "files")] + pub files: Vec, +} + +impl FileList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get files + pub fn files(&self) -> &Vec { + &self.files + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_file_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.files(); + } + + #[test] + fn test_file_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/framework.rs b/src/models/framework.rs new file mode 100644 index 0000000..b495410 --- /dev/null +++ b/src/models/framework.rs @@ -0,0 +1,77 @@ +//! Framework model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Framework +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Framework { + /// Framework key. + #[serde(rename = "key")] + pub key: String, + /// Framework Name. + #[serde(rename = "name")] + pub name: String, + /// Default runtime version. + #[serde(rename = "buildRuntime")] + pub build_runtime: String, + /// List of supported runtime versions. + #[serde(rename = "runtimes")] + pub runtimes: Vec, + /// List of supported adapters. + #[serde(rename = "adapters")] + pub adapters: Vec, +} + +impl Framework { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get build_runtime + pub fn build_runtime(&self) -> &String { + &self.build_runtime + } + + /// Get runtimes + pub fn runtimes(&self) -> &Vec { + &self.runtimes + } + + /// Get adapters + pub fn adapters(&self) -> &Vec { + &self.adapters + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_framework_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.name(); + let _ = _model.build_runtime(); + let _ = _model.runtimes(); + let _ = _model.adapters(); + } + + #[test] + fn test_framework_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/framework_adapter.rs b/src/models/framework_adapter.rs new file mode 100644 index 0000000..699a661 --- /dev/null +++ b/src/models/framework_adapter.rs @@ -0,0 +1,78 @@ +//! FrameworkAdapter model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Framework Adapter +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct FrameworkAdapter { + /// Adapter key. + #[serde(rename = "key")] + pub key: String, + /// Default command to download dependencies. + #[serde(rename = "installCommand")] + pub install_command: String, + /// Default command to build site into output directory. + #[serde(rename = "buildCommand")] + pub build_command: String, + /// Default output directory of build. + #[serde(rename = "outputDirectory")] + pub output_directory: String, + /// Name of fallback file to use instead of 404 page. If null, Appwrite 404 + /// page will be displayed. + #[serde(rename = "fallbackFile")] + pub fallback_file: String, +} + +impl FrameworkAdapter { + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get install_command + pub fn install_command(&self) -> &String { + &self.install_command + } + + /// Get build_command + pub fn build_command(&self) -> &String { + &self.build_command + } + + /// Get output_directory + pub fn output_directory(&self) -> &String { + &self.output_directory + } + + /// Get fallback_file + pub fn fallback_file(&self) -> &String { + &self.fallback_file + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_framework_adapter_creation() { + let _model = ::default(); + let _ = _model.key(); + let _ = _model.install_command(); + let _ = _model.build_command(); + let _ = _model.output_directory(); + let _ = _model.fallback_file(); + } + + #[test] + fn test_framework_adapter_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/framework_list.rs b/src/models/framework_list.rs new file mode 100644 index 0000000..386fa45 --- /dev/null +++ b/src/models/framework_list.rs @@ -0,0 +1,50 @@ +//! FrameworkList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Frameworks List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct FrameworkList { + /// Total number of frameworks that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of frameworks. + #[serde(rename = "frameworks")] + pub frameworks: Vec, +} + +impl FrameworkList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get frameworks + pub fn frameworks(&self) -> &Vec { + &self.frameworks + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_framework_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.frameworks(); + } + + #[test] + fn test_framework_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/function.rs b/src/models/function.rs new file mode 100644 index 0000000..5e609a1 --- /dev/null +++ b/src/models/function.rs @@ -0,0 +1,310 @@ +//! Function model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Function +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Function { + /// Function ID. + #[serde(rename = "$id")] + pub id: String, + /// Function creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Function update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Execution permissions. + #[serde(rename = "execute")] + pub execute: Vec, + /// Function name. + #[serde(rename = "name")] + pub name: String, + /// Function enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Is the function deployed with the latest configuration? This is set to + /// false if you've changed an environment variables, entrypoint, commands, or + /// other settings that needs redeploy to be applied. When the value is false, + /// redeploy the function to update it with the latest configuration. + #[serde(rename = "live")] + pub live: bool, + /// When disabled, executions will exclude logs and errors, and will be + /// slightly faster. + #[serde(rename = "logging")] + pub logging: bool, + /// Function execution and build runtime. + #[serde(rename = "runtime")] + pub runtime: String, + /// How many days to keep the non-active deployments before they will be + /// automatically deleted. + #[serde(rename = "deploymentRetention")] + pub deployment_retention: i64, + /// Function's active deployment ID. + #[serde(rename = "deploymentId")] + pub deployment_id: String, + /// Active deployment creation date in ISO 8601 format. + #[serde(rename = "deploymentCreatedAt")] + pub deployment_created_at: String, + /// Function's latest deployment ID. + #[serde(rename = "latestDeploymentId")] + pub latest_deployment_id: String, + /// Latest deployment creation date in ISO 8601 format. + #[serde(rename = "latestDeploymentCreatedAt")] + pub latest_deployment_created_at: String, + /// Status of latest deployment. Possible values are "waiting", "processing", + /// "building", "ready", and "failed". + #[serde(rename = "latestDeploymentStatus")] + pub latest_deployment_status: String, + /// Allowed permission scopes. + #[serde(rename = "scopes")] + pub scopes: Vec, + /// Function variables. + #[serde(rename = "vars")] + pub vars: Vec, + /// Function trigger events. + #[serde(rename = "events")] + pub events: Vec, + /// Function execution schedule in CRON format. + #[serde(rename = "schedule")] + pub schedule: String, + /// Function execution timeout in seconds. + #[serde(rename = "timeout")] + pub timeout: i64, + /// The entrypoint file used to execute the deployment. + #[serde(rename = "entrypoint")] + pub entrypoint: String, + /// The build command used to build the deployment. + #[serde(rename = "commands")] + pub commands: String, + /// Version of Open Runtimes used for the function. + #[serde(rename = "version")] + pub version: String, + /// Function VCS (Version Control System) installation id. + #[serde(rename = "installationId")] + pub installation_id: String, + /// VCS (Version Control System) Repository ID + #[serde(rename = "providerRepositoryId")] + pub provider_repository_id: String, + /// VCS (Version Control System) branch name + #[serde(rename = "providerBranch")] + pub provider_branch: String, + /// Path to function in VCS (Version Control System) repository + #[serde(rename = "providerRootDirectory")] + pub provider_root_directory: String, + /// Is VCS (Version Control System) connection is in silent mode? When in + /// silence mode, no comments will be posted on the repository pull or merge + /// requests + #[serde(rename = "providerSilentMode")] + pub provider_silent_mode: bool, + /// Machine specification for deployment builds. + #[serde(rename = "buildSpecification")] + pub build_specification: String, + /// Machine specification for executions. + #[serde(rename = "runtimeSpecification")] + pub runtime_specification: String, +} + +impl Function { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get execute + pub fn execute(&self) -> &Vec { + &self.execute + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get live + pub fn live(&self) -> &bool { + &self.live + } + + /// Get logging + pub fn logging(&self) -> &bool { + &self.logging + } + + /// Get runtime + pub fn runtime(&self) -> &String { + &self.runtime + } + + /// Get deployment_retention + pub fn deployment_retention(&self) -> &i64 { + &self.deployment_retention + } + + /// Get deployment_id + pub fn deployment_id(&self) -> &String { + &self.deployment_id + } + + /// Get deployment_created_at + pub fn deployment_created_at(&self) -> &String { + &self.deployment_created_at + } + + /// Get latest_deployment_id + pub fn latest_deployment_id(&self) -> &String { + &self.latest_deployment_id + } + + /// Get latest_deployment_created_at + pub fn latest_deployment_created_at(&self) -> &String { + &self.latest_deployment_created_at + } + + /// Get latest_deployment_status + pub fn latest_deployment_status(&self) -> &String { + &self.latest_deployment_status + } + + /// Get scopes + pub fn scopes(&self) -> &Vec { + &self.scopes + } + + /// Get vars + pub fn vars(&self) -> &Vec { + &self.vars + } + + /// Get events + pub fn events(&self) -> &Vec { + &self.events + } + + /// Get schedule + pub fn schedule(&self) -> &String { + &self.schedule + } + + /// Get timeout + pub fn timeout(&self) -> &i64 { + &self.timeout + } + + /// Get entrypoint + pub fn entrypoint(&self) -> &String { + &self.entrypoint + } + + /// Get commands + pub fn commands(&self) -> &String { + &self.commands + } + + /// Get version + pub fn version(&self) -> &String { + &self.version + } + + /// Get installation_id + pub fn installation_id(&self) -> &String { + &self.installation_id + } + + /// Get provider_repository_id + pub fn provider_repository_id(&self) -> &String { + &self.provider_repository_id + } + + /// Get provider_branch + pub fn provider_branch(&self) -> &String { + &self.provider_branch + } + + /// Get provider_root_directory + pub fn provider_root_directory(&self) -> &String { + &self.provider_root_directory + } + + /// Get provider_silent_mode + pub fn provider_silent_mode(&self) -> &bool { + &self.provider_silent_mode + } + + /// Get build_specification + pub fn build_specification(&self) -> &String { + &self.build_specification + } + + /// Get runtime_specification + pub fn runtime_specification(&self) -> &String { + &self.runtime_specification + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_function_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.execute(); + let _ = _model.name(); + let _ = _model.enabled(); + let _ = _model.live(); + let _ = _model.logging(); + let _ = _model.runtime(); + let _ = _model.deployment_retention(); + let _ = _model.deployment_id(); + let _ = _model.deployment_created_at(); + let _ = _model.latest_deployment_id(); + let _ = _model.latest_deployment_created_at(); + let _ = _model.latest_deployment_status(); + let _ = _model.scopes(); + let _ = _model.vars(); + let _ = _model.events(); + let _ = _model.schedule(); + let _ = _model.timeout(); + let _ = _model.entrypoint(); + let _ = _model.commands(); + let _ = _model.version(); + let _ = _model.installation_id(); + let _ = _model.provider_repository_id(); + let _ = _model.provider_branch(); + let _ = _model.provider_root_directory(); + let _ = _model.provider_silent_mode(); + let _ = _model.build_specification(); + let _ = _model.runtime_specification(); + } + + #[test] + fn test_function_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/function_list.rs b/src/models/function_list.rs new file mode 100644 index 0000000..4af367b --- /dev/null +++ b/src/models/function_list.rs @@ -0,0 +1,50 @@ +//! FunctionList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Functions List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct FunctionList { + /// Total number of functions that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of functions. + #[serde(rename = "functions")] + pub functions: Vec, +} + +impl FunctionList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get functions + pub fn functions(&self) -> &Vec { + &self.functions + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_function_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.functions(); + } + + #[test] + fn test_function_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/headers.rs b/src/models/headers.rs new file mode 100644 index 0000000..e357622 --- /dev/null +++ b/src/models/headers.rs @@ -0,0 +1,50 @@ +//! Headers model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Headers +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Headers { + /// Header name. + #[serde(rename = "name")] + pub name: String, + /// Header value. + #[serde(rename = "value")] + pub value: String, +} + +impl Headers { + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get value + pub fn value(&self) -> &String { + &self.value + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_headers_creation() { + let _model = ::default(); + let _ = _model.name(); + let _ = _model.value(); + } + + #[test] + fn test_headers_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/health_antivirus.rs b/src/models/health_antivirus.rs new file mode 100644 index 0000000..9571651 --- /dev/null +++ b/src/models/health_antivirus.rs @@ -0,0 +1,50 @@ +//! HealthAntivirus model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Health Antivirus +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct HealthAntivirus { + /// Antivirus version. + #[serde(rename = "version")] + pub version: String, + /// Antivirus status. Possible values are: `disabled`, `offline`, `online` + #[serde(rename = "status")] + pub status: crate::enums::HealthAntivirusStatus, +} + +impl HealthAntivirus { + /// Get version + pub fn version(&self) -> &String { + &self.version + } + + /// Get status + pub fn status(&self) -> &crate::enums::HealthAntivirusStatus { + &self.status + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_antivirus_creation() { + let _model = ::default(); + let _ = _model.version(); + let _ = _model.status(); + } + + #[test] + fn test_health_antivirus_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/health_certificate.rs b/src/models/health_certificate.rs new file mode 100644 index 0000000..c38e532 --- /dev/null +++ b/src/models/health_certificate.rs @@ -0,0 +1,86 @@ +//! HealthCertificate model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Health Certificate +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct HealthCertificate { + /// Certificate name + #[serde(rename = "name")] + pub name: String, + /// Subject SN + #[serde(rename = "subjectSN")] + pub subject_sn: String, + /// Issuer organisation + #[serde(rename = "issuerOrganisation")] + pub issuer_organisation: String, + /// Valid from + #[serde(rename = "validFrom")] + pub valid_from: String, + /// Valid to + #[serde(rename = "validTo")] + pub valid_to: String, + /// Signature type SN + #[serde(rename = "signatureTypeSN")] + pub signature_type_sn: String, +} + +impl HealthCertificate { + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get subject_sn + pub fn subject_sn(&self) -> &String { + &self.subject_sn + } + + /// Get issuer_organisation + pub fn issuer_organisation(&self) -> &String { + &self.issuer_organisation + } + + /// Get valid_from + pub fn valid_from(&self) -> &String { + &self.valid_from + } + + /// Get valid_to + pub fn valid_to(&self) -> &String { + &self.valid_to + } + + /// Get signature_type_sn + pub fn signature_type_sn(&self) -> &String { + &self.signature_type_sn + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_certificate_creation() { + let _model = ::default(); + let _ = _model.name(); + let _ = _model.subject_sn(); + let _ = _model.issuer_organisation(); + let _ = _model.valid_from(); + let _ = _model.valid_to(); + let _ = _model.signature_type_sn(); + } + + #[test] + fn test_health_certificate_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/health_queue.rs b/src/models/health_queue.rs new file mode 100644 index 0000000..92ea501 --- /dev/null +++ b/src/models/health_queue.rs @@ -0,0 +1,41 @@ +//! HealthQueue model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Health Queue +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct HealthQueue { + /// Amount of actions in the queue. + #[serde(rename = "size")] + pub size: i64, +} + +impl HealthQueue { + /// Get size + pub fn size(&self) -> &i64 { + &self.size + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_queue_creation() { + let _model = ::default(); + let _ = _model.size(); + } + + #[test] + fn test_health_queue_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/health_status.rs b/src/models/health_status.rs new file mode 100644 index 0000000..43b2d39 --- /dev/null +++ b/src/models/health_status.rs @@ -0,0 +1,59 @@ +//! HealthStatus model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Health Status +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct HealthStatus { + /// Name of the service. + #[serde(rename = "name")] + pub name: String, + /// Duration in milliseconds how long the health check took. + #[serde(rename = "ping")] + pub ping: i64, + /// Service status. Possible values are: `pass`, `fail` + #[serde(rename = "status")] + pub status: crate::enums::HealthCheckStatus, +} + +impl HealthStatus { + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get ping + pub fn ping(&self) -> &i64 { + &self.ping + } + + /// Get status + pub fn status(&self) -> &crate::enums::HealthCheckStatus { + &self.status + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_status_creation() { + let _model = ::default(); + let _ = _model.name(); + let _ = _model.ping(); + let _ = _model.status(); + } + + #[test] + fn test_health_status_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/health_status_list.rs b/src/models/health_status_list.rs new file mode 100644 index 0000000..c9613a9 --- /dev/null +++ b/src/models/health_status_list.rs @@ -0,0 +1,50 @@ +//! HealthStatusList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Status List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct HealthStatusList { + /// Total number of statuses that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of statuses. + #[serde(rename = "statuses")] + pub statuses: Vec, +} + +impl HealthStatusList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get statuses + pub fn statuses(&self) -> &Vec { + &self.statuses + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_status_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.statuses(); + } + + #[test] + fn test_health_status_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/health_time.rs b/src/models/health_time.rs new file mode 100644 index 0000000..a7aa916 --- /dev/null +++ b/src/models/health_time.rs @@ -0,0 +1,59 @@ +//! HealthTime model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Health Time +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct HealthTime { + /// Current unix timestamp on trustful remote server. + #[serde(rename = "remoteTime")] + pub remote_time: i64, + /// Current unix timestamp of local server where Appwrite runs. + #[serde(rename = "localTime")] + pub local_time: i64, + /// Difference of unix remote and local timestamps in milliseconds. + #[serde(rename = "diff")] + pub diff: i64, +} + +impl HealthTime { + /// Get remote_time + pub fn remote_time(&self) -> &i64 { + &self.remote_time + } + + /// Get local_time + pub fn local_time(&self) -> &i64 { + &self.local_time + } + + /// Get diff + pub fn diff(&self) -> &i64 { + &self.diff + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_time_creation() { + let _model = ::default(); + let _ = _model.remote_time(); + let _ = _model.local_time(); + let _ = _model.diff(); + } + + #[test] + fn test_health_time_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/identity.rs b/src/models/identity.rs new file mode 100644 index 0000000..ab32f8d --- /dev/null +++ b/src/models/identity.rs @@ -0,0 +1,122 @@ +//! Identity model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Identity +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Identity { + /// Identity ID. + #[serde(rename = "$id")] + pub id: String, + /// Identity creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Identity update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// Identity Provider. + #[serde(rename = "provider")] + pub provider: String, + /// ID of the User in the Identity Provider. + #[serde(rename = "providerUid")] + pub provider_uid: String, + /// Email of the User in the Identity Provider. + #[serde(rename = "providerEmail")] + pub provider_email: String, + /// Identity Provider Access Token. + #[serde(rename = "providerAccessToken")] + pub provider_access_token: String, + /// The date of when the access token expires in ISO 8601 format. + #[serde(rename = "providerAccessTokenExpiry")] + pub provider_access_token_expiry: String, + /// Identity Provider Refresh Token. + #[serde(rename = "providerRefreshToken")] + pub provider_refresh_token: String, +} + +impl Identity { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get provider + pub fn provider(&self) -> &String { + &self.provider + } + + /// Get provider_uid + pub fn provider_uid(&self) -> &String { + &self.provider_uid + } + + /// Get provider_email + pub fn provider_email(&self) -> &String { + &self.provider_email + } + + /// Get provider_access_token + pub fn provider_access_token(&self) -> &String { + &self.provider_access_token + } + + /// Get provider_access_token_expiry + pub fn provider_access_token_expiry(&self) -> &String { + &self.provider_access_token_expiry + } + + /// Get provider_refresh_token + pub fn provider_refresh_token(&self) -> &String { + &self.provider_refresh_token + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_identity_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.user_id(); + let _ = _model.provider(); + let _ = _model.provider_uid(); + let _ = _model.provider_email(); + let _ = _model.provider_access_token(); + let _ = _model.provider_access_token_expiry(); + let _ = _model.provider_refresh_token(); + } + + #[test] + fn test_identity_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/identity_list.rs b/src/models/identity_list.rs new file mode 100644 index 0000000..690fd7c --- /dev/null +++ b/src/models/identity_list.rs @@ -0,0 +1,50 @@ +//! IdentityList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Identities List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct IdentityList { + /// Total number of identities that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of identities. + #[serde(rename = "identities")] + pub identities: Vec, +} + +impl IdentityList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get identities + pub fn identities(&self) -> &Vec { + &self.identities + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_identity_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.identities(); + } + + #[test] + fn test_identity_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/index.rs b/src/models/index.rs new file mode 100644 index 0000000..819a1e6 --- /dev/null +++ b/src/models/index.rs @@ -0,0 +1,130 @@ +//! Index model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Index +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Index { + /// Index ID. + #[serde(rename = "$id")] + pub id: String, + /// Index creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Index update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Index key. + #[serde(rename = "key")] + pub key: String, + /// Index type. + #[serde(rename = "type")] + pub r#type: String, + /// Index status. Possible values: `available`, `processing`, `deleting`, + /// `stuck`, or `failed` + #[serde(rename = "status")] + pub status: crate::enums::IndexStatus, + /// Error message. Displays error generated on failure of creating or deleting + /// an index. + #[serde(rename = "error")] + pub error: String, + /// Index attributes. + #[serde(rename = "attributes")] + pub attributes: Vec, + /// Index attributes length. + #[serde(rename = "lengths")] + pub lengths: Vec, + /// Index orders. + #[serde(rename = "orders")] + #[serde(skip_serializing_if = "Option::is_none")] + pub orders: Option>, +} + +impl Index { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get status + pub fn status(&self) -> &crate::enums::IndexStatus { + &self.status + } + + /// Get error + pub fn error(&self) -> &String { + &self.error + } + + /// Get attributes + pub fn attributes(&self) -> &Vec { + &self.attributes + } + + /// Get lengths + pub fn lengths(&self) -> &Vec { + &self.lengths + } + + /// Set orders + pub fn set_orders(mut self, orders: Vec) -> Self { + self.orders = Some(orders); + self + } + + /// Get orders + pub fn orders(&self) -> Option<&Vec> { + self.orders.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_index_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.key(); + let _ = _model.r#type(); + let _ = _model.status(); + let _ = _model.error(); + let _ = _model.attributes(); + let _ = _model.lengths(); + } + + #[test] + fn test_index_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/index_list.rs b/src/models/index_list.rs new file mode 100644 index 0000000..b2d34b6 --- /dev/null +++ b/src/models/index_list.rs @@ -0,0 +1,50 @@ +//! IndexList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Indexes List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct IndexList { + /// Total number of indexes that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of indexes. + #[serde(rename = "indexes")] + pub indexes: Vec, +} + +impl IndexList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get indexes + pub fn indexes(&self) -> &Vec { + &self.indexes + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_index_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.indexes(); + } + + #[test] + fn test_index_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/jwt.rs b/src/models/jwt.rs new file mode 100644 index 0000000..02d850d --- /dev/null +++ b/src/models/jwt.rs @@ -0,0 +1,41 @@ +//! Jwt model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// JWT +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Jwt { + /// JWT encoded string. + #[serde(rename = "jwt")] + pub jwt: String, +} + +impl Jwt { + /// Get jwt + pub fn jwt(&self) -> &String { + &self.jwt + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_jwt_creation() { + let _model = ::default(); + let _ = _model.jwt(); + } + + #[test] + fn test_jwt_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/language.rs b/src/models/language.rs new file mode 100644 index 0000000..7f91530 --- /dev/null +++ b/src/models/language.rs @@ -0,0 +1,59 @@ +//! Language model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Language +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Language { + /// Language name. + #[serde(rename = "name")] + pub name: String, + /// Language two-character ISO 639-1 codes. + #[serde(rename = "code")] + pub code: String, + /// Language native name. + #[serde(rename = "nativeName")] + pub native_name: String, +} + +impl Language { + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get code + pub fn code(&self) -> &String { + &self.code + } + + /// Get native_name + pub fn native_name(&self) -> &String { + &self.native_name + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_language_creation() { + let _model = ::default(); + let _ = _model.name(); + let _ = _model.code(); + let _ = _model.native_name(); + } + + #[test] + fn test_language_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/language_list.rs b/src/models/language_list.rs new file mode 100644 index 0000000..6b87091 --- /dev/null +++ b/src/models/language_list.rs @@ -0,0 +1,50 @@ +//! LanguageList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Languages List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct LanguageList { + /// Total number of languages that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of languages. + #[serde(rename = "languages")] + pub languages: Vec, +} + +impl LanguageList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get languages + pub fn languages(&self) -> &Vec { + &self.languages + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_language_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.languages(); + } + + #[test] + fn test_language_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/locale.rs b/src/models/locale.rs new file mode 100644 index 0000000..79b763c --- /dev/null +++ b/src/models/locale.rs @@ -0,0 +1,99 @@ +//! Locale model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Locale +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Locale { + /// User IP address. + #[serde(rename = "ip")] + pub ip: String, + /// Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) + /// two-character format + #[serde(rename = "countryCode")] + pub country_code: String, + /// Country name. This field support localization. + #[serde(rename = "country")] + pub country: String, + /// Continent code. A two character continent code "AF" for Africa, "AN" for + /// Antarctica, "AS" for Asia, "EU" for Europe, "NA" for North America, "OC" + /// for Oceania, and "SA" for South America. + #[serde(rename = "continentCode")] + pub continent_code: String, + /// Continent name. This field support localization. + #[serde(rename = "continent")] + pub continent: String, + /// True if country is part of the European Union. + #[serde(rename = "eu")] + pub eu: bool, + /// Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) + /// three-character format + #[serde(rename = "currency")] + pub currency: String, +} + +impl Locale { + /// Get ip + pub fn ip(&self) -> &String { + &self.ip + } + + /// Get country_code + pub fn country_code(&self) -> &String { + &self.country_code + } + + /// Get country + pub fn country(&self) -> &String { + &self.country + } + + /// Get continent_code + pub fn continent_code(&self) -> &String { + &self.continent_code + } + + /// Get continent + pub fn continent(&self) -> &String { + &self.continent + } + + /// Get eu + pub fn eu(&self) -> &bool { + &self.eu + } + + /// Get currency + pub fn currency(&self) -> &String { + &self.currency + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_locale_creation() { + let _model = ::default(); + let _ = _model.ip(); + let _ = _model.country_code(); + let _ = _model.country(); + let _ = _model.continent_code(); + let _ = _model.continent(); + let _ = _model.eu(); + let _ = _model.currency(); + } + + #[test] + fn test_locale_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/locale_code.rs b/src/models/locale_code.rs new file mode 100644 index 0000000..92750c9 --- /dev/null +++ b/src/models/locale_code.rs @@ -0,0 +1,51 @@ +//! LocaleCode model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// LocaleCode +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct LocaleCode { + /// Locale codes in [ISO + /// 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) + #[serde(rename = "code")] + pub code: String, + /// Locale name + #[serde(rename = "name")] + pub name: String, +} + +impl LocaleCode { + /// Get code + pub fn code(&self) -> &String { + &self.code + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_locale_code_creation() { + let _model = ::default(); + let _ = _model.code(); + let _ = _model.name(); + } + + #[test] + fn test_locale_code_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/locale_code_list.rs b/src/models/locale_code_list.rs new file mode 100644 index 0000000..d503d0a --- /dev/null +++ b/src/models/locale_code_list.rs @@ -0,0 +1,50 @@ +//! LocaleCodeList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Locale codes list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct LocaleCodeList { + /// Total number of localeCodes that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of localeCodes. + #[serde(rename = "localeCodes")] + pub locale_codes: Vec, +} + +impl LocaleCodeList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get locale_codes + pub fn locale_codes(&self) -> &Vec { + &self.locale_codes + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_locale_code_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.locale_codes(); + } + + #[test] + fn test_locale_code_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/log.rs b/src/models/log.rs new file mode 100644 index 0000000..38ef796 --- /dev/null +++ b/src/models/log.rs @@ -0,0 +1,226 @@ +//! Log model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Log +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Log { + /// Event name. + #[serde(rename = "event")] + pub event: String, + /// User ID of the actor recorded for this log. During impersonation, this is + /// the original impersonator, not the impersonated target user. + #[serde(rename = "userId")] + pub user_id: String, + /// User email of the actor recorded for this log. During impersonation, this + /// is the original impersonator. + #[serde(rename = "userEmail")] + pub user_email: String, + /// User name of the actor recorded for this log. During impersonation, this is + /// the original impersonator. + #[serde(rename = "userName")] + pub user_name: String, + /// API mode when event triggered. + #[serde(rename = "mode")] + pub mode: String, + /// IP session in use when the session was created. + #[serde(rename = "ip")] + pub ip: String, + /// Log creation date in ISO 8601 format. + #[serde(rename = "time")] + pub time: String, + /// Operating system code name. View list of [available + /// options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). + #[serde(rename = "osCode")] + pub os_code: String, + /// Operating system name. + #[serde(rename = "osName")] + pub os_name: String, + /// Operating system version. + #[serde(rename = "osVersion")] + pub os_version: String, + /// Client type. + #[serde(rename = "clientType")] + pub client_type: String, + /// Client code name. View list of [available + /// options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). + #[serde(rename = "clientCode")] + pub client_code: String, + /// Client name. + #[serde(rename = "clientName")] + pub client_name: String, + /// Client version. + #[serde(rename = "clientVersion")] + pub client_version: String, + /// Client engine name. + #[serde(rename = "clientEngine")] + pub client_engine: String, + /// Client engine name. + #[serde(rename = "clientEngineVersion")] + pub client_engine_version: String, + /// Device name. + #[serde(rename = "deviceName")] + pub device_name: String, + /// Device brand name. + #[serde(rename = "deviceBrand")] + pub device_brand: String, + /// Device model name. + #[serde(rename = "deviceModel")] + pub device_model: String, + /// Country two-character ISO 3166-1 alpha code. + #[serde(rename = "countryCode")] + pub country_code: String, + /// Country name. + #[serde(rename = "countryName")] + pub country_name: String, +} + +impl Log { + /// Get event + pub fn event(&self) -> &String { + &self.event + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get user_email + pub fn user_email(&self) -> &String { + &self.user_email + } + + /// Get user_name + pub fn user_name(&self) -> &String { + &self.user_name + } + + /// Get mode + pub fn mode(&self) -> &String { + &self.mode + } + + /// Get ip + pub fn ip(&self) -> &String { + &self.ip + } + + /// Get time + pub fn time(&self) -> &String { + &self.time + } + + /// Get os_code + pub fn os_code(&self) -> &String { + &self.os_code + } + + /// Get os_name + pub fn os_name(&self) -> &String { + &self.os_name + } + + /// Get os_version + pub fn os_version(&self) -> &String { + &self.os_version + } + + /// Get client_type + pub fn client_type(&self) -> &String { + &self.client_type + } + + /// Get client_code + pub fn client_code(&self) -> &String { + &self.client_code + } + + /// Get client_name + pub fn client_name(&self) -> &String { + &self.client_name + } + + /// Get client_version + pub fn client_version(&self) -> &String { + &self.client_version + } + + /// Get client_engine + pub fn client_engine(&self) -> &String { + &self.client_engine + } + + /// Get client_engine_version + pub fn client_engine_version(&self) -> &String { + &self.client_engine_version + } + + /// Get device_name + pub fn device_name(&self) -> &String { + &self.device_name + } + + /// Get device_brand + pub fn device_brand(&self) -> &String { + &self.device_brand + } + + /// Get device_model + pub fn device_model(&self) -> &String { + &self.device_model + } + + /// Get country_code + pub fn country_code(&self) -> &String { + &self.country_code + } + + /// Get country_name + pub fn country_name(&self) -> &String { + &self.country_name + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_log_creation() { + let _model = ::default(); + let _ = _model.event(); + let _ = _model.user_id(); + let _ = _model.user_email(); + let _ = _model.user_name(); + let _ = _model.mode(); + let _ = _model.ip(); + let _ = _model.time(); + let _ = _model.os_code(); + let _ = _model.os_name(); + let _ = _model.os_version(); + let _ = _model.client_type(); + let _ = _model.client_code(); + let _ = _model.client_name(); + let _ = _model.client_version(); + let _ = _model.client_engine(); + let _ = _model.client_engine_version(); + let _ = _model.device_name(); + let _ = _model.device_brand(); + let _ = _model.device_model(); + let _ = _model.country_code(); + let _ = _model.country_name(); + } + + #[test] + fn test_log_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/log_list.rs b/src/models/log_list.rs new file mode 100644 index 0000000..696e194 --- /dev/null +++ b/src/models/log_list.rs @@ -0,0 +1,50 @@ +//! LogList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Logs List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct LogList { + /// Total number of logs that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of logs. + #[serde(rename = "logs")] + pub logs: Vec, +} + +impl LogList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get logs + pub fn logs(&self) -> &Vec { + &self.logs + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_log_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.logs(); + } + + #[test] + fn test_log_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/membership.rs b/src/models/membership.rs new file mode 100644 index 0000000..269abf9 --- /dev/null +++ b/src/models/membership.rs @@ -0,0 +1,155 @@ +//! Membership model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Membership +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Membership { + /// Membership ID. + #[serde(rename = "$id")] + pub id: String, + /// Membership creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Membership update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// User name. Hide this attribute by toggling membership privacy in the + /// Console. + #[serde(rename = "userName")] + pub user_name: String, + /// User email address. Hide this attribute by toggling membership privacy in + /// the Console. + #[serde(rename = "userEmail")] + pub user_email: String, + /// Team ID. + #[serde(rename = "teamId")] + pub team_id: String, + /// Team name. + #[serde(rename = "teamName")] + pub team_name: String, + /// Date, the user has been invited to join the team in ISO 8601 format. + #[serde(rename = "invited")] + pub invited: String, + /// Date, the user has accepted the invitation to join the team in ISO 8601 + /// format. + #[serde(rename = "joined")] + pub joined: String, + /// User confirmation status, true if the user has joined the team or false + /// otherwise. + #[serde(rename = "confirm")] + pub confirm: bool, + /// Multi factor authentication status, true if the user has MFA enabled or + /// false otherwise. Hide this attribute by toggling membership privacy in the + /// Console. + #[serde(rename = "mfa")] + pub mfa: bool, + /// User list of roles + #[serde(rename = "roles")] + pub roles: Vec, +} + +impl Membership { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get user_name + pub fn user_name(&self) -> &String { + &self.user_name + } + + /// Get user_email + pub fn user_email(&self) -> &String { + &self.user_email + } + + /// Get team_id + pub fn team_id(&self) -> &String { + &self.team_id + } + + /// Get team_name + pub fn team_name(&self) -> &String { + &self.team_name + } + + /// Get invited + pub fn invited(&self) -> &String { + &self.invited + } + + /// Get joined + pub fn joined(&self) -> &String { + &self.joined + } + + /// Get confirm + pub fn confirm(&self) -> &bool { + &self.confirm + } + + /// Get mfa + pub fn mfa(&self) -> &bool { + &self.mfa + } + + /// Get roles + pub fn roles(&self) -> &Vec { + &self.roles + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_membership_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.user_id(); + let _ = _model.user_name(); + let _ = _model.user_email(); + let _ = _model.team_id(); + let _ = _model.team_name(); + let _ = _model.invited(); + let _ = _model.joined(); + let _ = _model.confirm(); + let _ = _model.mfa(); + let _ = _model.roles(); + } + + #[test] + fn test_membership_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/membership_list.rs b/src/models/membership_list.rs new file mode 100644 index 0000000..27e020d --- /dev/null +++ b/src/models/membership_list.rs @@ -0,0 +1,50 @@ +//! MembershipList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Memberships List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct MembershipList { + /// Total number of memberships that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of memberships. + #[serde(rename = "memberships")] + pub memberships: Vec, +} + +impl MembershipList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get memberships + pub fn memberships(&self) -> &Vec { + &self.memberships + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_membership_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.memberships(); + } + + #[test] + fn test_membership_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/message.rs b/src/models/message.rs new file mode 100644 index 0000000..dcb4de3 --- /dev/null +++ b/src/models/message.rs @@ -0,0 +1,167 @@ +//! Message model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Message +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Message { + /// Message ID. + #[serde(rename = "$id")] + pub id: String, + /// Message creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Message update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Message provider type. + #[serde(rename = "providerType")] + pub provider_type: String, + /// Topic IDs set as recipients. + #[serde(rename = "topics")] + pub topics: Vec, + /// User IDs set as recipients. + #[serde(rename = "users")] + pub users: Vec, + /// Target IDs set as recipients. + #[serde(rename = "targets")] + pub targets: Vec, + /// The scheduled time for message. + #[serde(rename = "scheduledAt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub scheduled_at: Option, + /// The time when the message was delivered. + #[serde(rename = "deliveredAt")] + #[serde(skip_serializing_if = "Option::is_none")] + pub delivered_at: Option, + /// Delivery errors if any. + #[serde(rename = "deliveryErrors")] + #[serde(skip_serializing_if = "Option::is_none")] + pub delivery_errors: Option>, + /// Number of recipients the message was delivered to. + #[serde(rename = "deliveredTotal")] + pub delivered_total: i64, + /// Data of the message. + #[serde(rename = "data")] + pub data: serde_json::Value, + /// Status of delivery. + #[serde(rename = "status")] + pub status: crate::enums::MessageStatus, +} + +impl Message { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get provider_type + pub fn provider_type(&self) -> &String { + &self.provider_type + } + + /// Get topics + pub fn topics(&self) -> &Vec { + &self.topics + } + + /// Get users + pub fn users(&self) -> &Vec { + &self.users + } + + /// Get targets + pub fn targets(&self) -> &Vec { + &self.targets + } + + /// Set scheduled_at + pub fn set_scheduled_at(mut self, scheduled_at: String) -> Self { + self.scheduled_at = Some(scheduled_at); + self + } + + /// Get scheduled_at + pub fn scheduled_at(&self) -> Option<&String> { + self.scheduled_at.as_ref() + } + + /// Set delivered_at + pub fn set_delivered_at(mut self, delivered_at: String) -> Self { + self.delivered_at = Some(delivered_at); + self + } + + /// Get delivered_at + pub fn delivered_at(&self) -> Option<&String> { + self.delivered_at.as_ref() + } + + /// Set delivery_errors + pub fn set_delivery_errors(mut self, delivery_errors: Vec) -> Self { + self.delivery_errors = Some(delivery_errors); + self + } + + /// Get delivery_errors + pub fn delivery_errors(&self) -> Option<&Vec> { + self.delivery_errors.as_ref() + } + + /// Get delivered_total + pub fn delivered_total(&self) -> &i64 { + &self.delivered_total + } + + /// Get data + pub fn data(&self) -> &serde_json::Value { + &self.data + } + + /// Get status + pub fn status(&self) -> &crate::enums::MessageStatus { + &self.status + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_message_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.provider_type(); + let _ = _model.topics(); + let _ = _model.users(); + let _ = _model.targets(); + let _ = _model.delivered_total(); + let _ = _model.data(); + let _ = _model.status(); + } + + #[test] + fn test_message_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/message_list.rs b/src/models/message_list.rs new file mode 100644 index 0000000..6fc8614 --- /dev/null +++ b/src/models/message_list.rs @@ -0,0 +1,50 @@ +//! MessageList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Message list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct MessageList { + /// Total number of messages that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of messages. + #[serde(rename = "messages")] + pub messages: Vec, +} + +impl MessageList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get messages + pub fn messages(&self) -> &Vec { + &self.messages + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_message_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.messages(); + } + + #[test] + fn test_message_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/mfa_challenge.rs b/src/models/mfa_challenge.rs new file mode 100644 index 0000000..bb0b1bc --- /dev/null +++ b/src/models/mfa_challenge.rs @@ -0,0 +1,68 @@ +//! MfaChallenge model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// MFA Challenge +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct MfaChallenge { + /// Token ID. + #[serde(rename = "$id")] + pub id: String, + /// Token creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// Token expiration date in ISO 8601 format. + #[serde(rename = "expire")] + pub expire: String, +} + +impl MfaChallenge { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get expire + pub fn expire(&self) -> &String { + &self.expire + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mfa_challenge_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.user_id(); + let _ = _model.expire(); + } + + #[test] + fn test_mfa_challenge_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/mfa_factors.rs b/src/models/mfa_factors.rs new file mode 100644 index 0000000..6c68d93 --- /dev/null +++ b/src/models/mfa_factors.rs @@ -0,0 +1,68 @@ +//! MfaFactors model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// MFAFactors +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct MfaFactors { + /// Can TOTP be used for MFA challenge for this account. + #[serde(rename = "totp")] + pub totp: bool, + /// Can phone (SMS) be used for MFA challenge for this account. + #[serde(rename = "phone")] + pub phone: bool, + /// Can email be used for MFA challenge for this account. + #[serde(rename = "email")] + pub email: bool, + /// Can recovery code be used for MFA challenge for this account. + #[serde(rename = "recoveryCode")] + pub recovery_code: bool, +} + +impl MfaFactors { + /// Get totp + pub fn totp(&self) -> &bool { + &self.totp + } + + /// Get phone + pub fn phone(&self) -> &bool { + &self.phone + } + + /// Get email + pub fn email(&self) -> &bool { + &self.email + } + + /// Get recovery_code + pub fn recovery_code(&self) -> &bool { + &self.recovery_code + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mfa_factors_creation() { + let _model = ::default(); + let _ = _model.totp(); + let _ = _model.phone(); + let _ = _model.email(); + let _ = _model.recovery_code(); + } + + #[test] + fn test_mfa_factors_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/mfa_recovery_codes.rs b/src/models/mfa_recovery_codes.rs new file mode 100644 index 0000000..3d79a88 --- /dev/null +++ b/src/models/mfa_recovery_codes.rs @@ -0,0 +1,41 @@ +//! MfaRecoveryCodes model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// MFA Recovery Codes +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct MfaRecoveryCodes { + /// Recovery codes. + #[serde(rename = "recoveryCodes")] + pub recovery_codes: Vec, +} + +impl MfaRecoveryCodes { + /// Get recovery_codes + pub fn recovery_codes(&self) -> &Vec { + &self.recovery_codes + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mfa_recovery_codes_creation() { + let _model = ::default(); + let _ = _model.recovery_codes(); + } + + #[test] + fn test_mfa_recovery_codes_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/mfa_type.rs b/src/models/mfa_type.rs new file mode 100644 index 0000000..6d870c7 --- /dev/null +++ b/src/models/mfa_type.rs @@ -0,0 +1,50 @@ +//! MfaType model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// MFAType +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct MfaType { + /// Secret token used for TOTP factor. + #[serde(rename = "secret")] + pub secret: String, + /// URI for authenticator apps. + #[serde(rename = "uri")] + pub uri: String, +} + +impl MfaType { + /// Get secret + pub fn secret(&self) -> &String { + &self.secret + } + + /// Get uri + pub fn uri(&self) -> &String { + &self.uri + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mfa_type_creation() { + let _model = ::default(); + let _ = _model.secret(); + let _ = _model.uri(); + } + + #[test] + fn test_mfa_type_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/mod.rs b/src/models/mod.rs new file mode 100644 index 0000000..14cb773 --- /dev/null +++ b/src/models/mod.rs @@ -0,0 +1,433 @@ +//! Data models for Appwrite SDK + +pub mod row_list; +pub use row_list::RowList; +pub mod document_list; +pub use document_list::DocumentList; +pub mod table_list; +pub use table_list::TableList; +pub mod collection_list; +pub use collection_list::CollectionList; +pub mod database_list; +pub use database_list::DatabaseList; +pub mod index_list; +pub use index_list::IndexList; +pub mod column_index_list; +pub use column_index_list::ColumnIndexList; +pub mod user_list; +pub use user_list::UserList; +pub mod session_list; +pub use session_list::SessionList; +pub mod identity_list; +pub use identity_list::IdentityList; +pub mod log_list; +pub use log_list::LogList; +pub mod file_list; +pub use file_list::FileList; +pub mod bucket_list; +pub use bucket_list::BucketList; +pub mod resource_token_list; +pub use resource_token_list::ResourceTokenList; +pub mod team_list; +pub use team_list::TeamList; +pub mod membership_list; +pub use membership_list::MembershipList; +pub mod site_list; +pub use site_list::SiteList; +pub mod function_list; +pub use function_list::FunctionList; +pub mod framework_list; +pub use framework_list::FrameworkList; +pub mod runtime_list; +pub use runtime_list::RuntimeList; +pub mod deployment_list; +pub use deployment_list::DeploymentList; +pub mod execution_list; +pub use execution_list::ExecutionList; +pub mod webhook_list; +pub use webhook_list::WebhookList; +pub mod country_list; +pub use country_list::CountryList; +pub mod continent_list; +pub use continent_list::ContinentList; +pub mod language_list; +pub use language_list::LanguageList; +pub mod currency_list; +pub use currency_list::CurrencyList; +pub mod phone_list; +pub use phone_list::PhoneList; +pub mod variable_list; +pub use variable_list::VariableList; +pub mod health_status_list; +pub use health_status_list::HealthStatusList; +pub mod locale_code_list; +pub use locale_code_list::LocaleCodeList; +pub mod provider_list; +pub use provider_list::ProviderList; +pub mod message_list; +pub use message_list::MessageList; +pub mod topic_list; +pub use topic_list::TopicList; +pub mod subscriber_list; +pub use subscriber_list::SubscriberList; +pub mod target_list; +pub use target_list::TargetList; +pub mod transaction_list; +pub use transaction_list::TransactionList; +pub mod specification_list; +pub use specification_list::SpecificationList; +pub mod database; +pub use database::Database; +pub mod collection; +pub use collection::Collection; +pub mod attribute_list; +pub use attribute_list::AttributeList; +pub mod attribute_string; +pub use attribute_string::AttributeString; +pub mod attribute_integer; +pub use attribute_integer::AttributeInteger; +pub mod attribute_float; +pub use attribute_float::AttributeFloat; +pub mod attribute_boolean; +pub use attribute_boolean::AttributeBoolean; +pub mod attribute_email; +pub use attribute_email::AttributeEmail; +pub mod attribute_enum; +pub use attribute_enum::AttributeEnum; +pub mod attribute_ip; +pub use attribute_ip::AttributeIp; +pub mod attribute_url; +pub use attribute_url::AttributeUrl; +pub mod attribute_datetime; +pub use attribute_datetime::AttributeDatetime; +pub mod attribute_relationship; +pub use attribute_relationship::AttributeRelationship; +pub mod attribute_point; +pub use attribute_point::AttributePoint; +pub mod attribute_line; +pub use attribute_line::AttributeLine; +pub mod attribute_polygon; +pub use attribute_polygon::AttributePolygon; +pub mod attribute_varchar; +pub use attribute_varchar::AttributeVarchar; +pub mod attribute_text; +pub use attribute_text::AttributeText; +pub mod attribute_mediumtext; +pub use attribute_mediumtext::AttributeMediumtext; +pub mod attribute_longtext; +pub use attribute_longtext::AttributeLongtext; +pub mod table; +pub use table::Table; +pub mod column_list; +pub use column_list::ColumnList; +pub mod column_string; +pub use column_string::ColumnString; +pub mod column_integer; +pub use column_integer::ColumnInteger; +pub mod column_float; +pub use column_float::ColumnFloat; +pub mod column_boolean; +pub use column_boolean::ColumnBoolean; +pub mod column_email; +pub use column_email::ColumnEmail; +pub mod column_enum; +pub use column_enum::ColumnEnum; +pub mod column_ip; +pub use column_ip::ColumnIp; +pub mod column_url; +pub use column_url::ColumnUrl; +pub mod column_datetime; +pub use column_datetime::ColumnDatetime; +pub mod column_relationship; +pub use column_relationship::ColumnRelationship; +pub mod column_point; +pub use column_point::ColumnPoint; +pub mod column_line; +pub use column_line::ColumnLine; +pub mod column_polygon; +pub use column_polygon::ColumnPolygon; +pub mod column_varchar; +pub use column_varchar::ColumnVarchar; +pub mod column_text; +pub use column_text::ColumnText; +pub mod column_mediumtext; +pub use column_mediumtext::ColumnMediumtext; +pub mod column_longtext; +pub use column_longtext::ColumnLongtext; +pub mod index; +pub use index::Index; +pub mod column_index; +pub use column_index::ColumnIndex; +pub mod row; +pub use row::Row; +pub mod document; +pub use document::Document; +pub mod log; +pub use log::Log; +pub mod user; +pub use user::User; +pub mod algo_md5; +pub use algo_md5::AlgoMd5; +pub mod algo_sha; +pub use algo_sha::AlgoSha; +pub mod algo_phpass; +pub use algo_phpass::AlgoPhpass; +pub mod algo_bcrypt; +pub use algo_bcrypt::AlgoBcrypt; +pub mod algo_scrypt; +pub use algo_scrypt::AlgoScrypt; +pub mod algo_scrypt_modified; +pub use algo_scrypt_modified::AlgoScryptModified; +pub mod algo_argon2; +pub use algo_argon2::AlgoArgon2; +pub mod preferences; +pub use preferences::Preferences; +pub mod session; +pub use session::Session; +pub mod identity; +pub use identity::Identity; +pub mod token; +pub use token::Token; +pub mod jwt; +pub use jwt::Jwt; +pub mod locale; +pub use locale::Locale; +pub mod locale_code; +pub use locale_code::LocaleCode; +pub mod file; +pub use file::File; +pub mod bucket; +pub use bucket::Bucket; +pub mod resource_token; +pub use resource_token::ResourceToken; +pub mod team; +pub use team::Team; +pub mod membership; +pub use membership::Membership; +pub mod site; +pub use site::Site; +pub mod function; +pub use function::Function; +pub mod runtime; +pub use runtime::Runtime; +pub mod framework; +pub use framework::Framework; +pub mod framework_adapter; +pub use framework_adapter::FrameworkAdapter; +pub mod deployment; +pub use deployment::Deployment; +pub mod execution; +pub use execution::Execution; +pub mod webhook; +pub use webhook::Webhook; +pub mod variable; +pub use variable::Variable; +pub mod country; +pub use country::Country; +pub mod continent; +pub use continent::Continent; +pub mod language; +pub use language::Language; +pub mod currency; +pub use currency::Currency; +pub mod phone; +pub use phone::Phone; +pub mod health_antivirus; +pub use health_antivirus::HealthAntivirus; +pub mod health_queue; +pub use health_queue::HealthQueue; +pub mod health_status; +pub use health_status::HealthStatus; +pub mod health_certificate; +pub use health_certificate::HealthCertificate; +pub mod health_time; +pub use health_time::HealthTime; +pub mod headers; +pub use headers::Headers; +pub mod specification; +pub use specification::Specification; +pub mod mfa_challenge; +pub use mfa_challenge::MfaChallenge; +pub mod mfa_recovery_codes; +pub use mfa_recovery_codes::MfaRecoveryCodes; +pub mod mfa_type; +pub use mfa_type::MfaType; +pub mod mfa_factors; +pub use mfa_factors::MfaFactors; +pub mod provider; +pub use provider::Provider; +pub mod message; +pub use message::Message; +pub mod topic; +pub use topic::Topic; +pub mod transaction; +pub use transaction::Transaction; +pub mod subscriber; +pub use subscriber::Subscriber; +pub mod target; +pub use target::Target; +pub mod activity_event; +pub use activity_event::ActivityEvent; +pub mod backup_archive; +pub use backup_archive::BackupArchive; +pub mod backup_policy; +pub use backup_policy::BackupPolicy; +pub mod backup_restoration; +pub use backup_restoration::BackupRestoration; +pub mod activity_event_list; +pub use activity_event_list::ActivityEventList; +pub mod backup_archive_list; +pub use backup_archive_list::BackupArchiveList; +pub mod backup_policy_list; +pub use backup_policy_list::BackupPolicyList; +pub mod backup_restoration_list; +pub use backup_restoration_list::BackupRestorationList; + +// Re-export commonly used types +use serde::{Deserialize, Serialize}; + +/// Base trait for all Appwrite models +pub trait Model: Serialize + for<'de> Deserialize<'de> + Clone + std::fmt::Debug {} + +// Implement the trait for all generated models +impl Model for RowList {} +impl Model for DocumentList {} +impl Model for TableList {} +impl Model for CollectionList {} +impl Model for DatabaseList {} +impl Model for IndexList {} +impl Model for ColumnIndexList {} +impl Model for UserList {} +impl Model for SessionList {} +impl Model for IdentityList {} +impl Model for LogList {} +impl Model for FileList {} +impl Model for BucketList {} +impl Model for ResourceTokenList {} +impl Model for TeamList {} +impl Model for MembershipList {} +impl Model for SiteList {} +impl Model for FunctionList {} +impl Model for FrameworkList {} +impl Model for RuntimeList {} +impl Model for DeploymentList {} +impl Model for ExecutionList {} +impl Model for WebhookList {} +impl Model for CountryList {} +impl Model for ContinentList {} +impl Model for LanguageList {} +impl Model for CurrencyList {} +impl Model for PhoneList {} +impl Model for VariableList {} +impl Model for HealthStatusList {} +impl Model for LocaleCodeList {} +impl Model for ProviderList {} +impl Model for MessageList {} +impl Model for TopicList {} +impl Model for SubscriberList {} +impl Model for TargetList {} +impl Model for TransactionList {} +impl Model for SpecificationList {} +impl Model for Database {} +impl Model for Collection {} +impl Model for AttributeList {} +impl Model for AttributeString {} +impl Model for AttributeInteger {} +impl Model for AttributeFloat {} +impl Model for AttributeBoolean {} +impl Model for AttributeEmail {} +impl Model for AttributeEnum {} +impl Model for AttributeIp {} +impl Model for AttributeUrl {} +impl Model for AttributeDatetime {} +impl Model for AttributeRelationship {} +impl Model for AttributePoint {} +impl Model for AttributeLine {} +impl Model for AttributePolygon {} +impl Model for AttributeVarchar {} +impl Model for AttributeText {} +impl Model for AttributeMediumtext {} +impl Model for AttributeLongtext {} +impl Model for Table {} +impl Model for ColumnList {} +impl Model for ColumnString {} +impl Model for ColumnInteger {} +impl Model for ColumnFloat {} +impl Model for ColumnBoolean {} +impl Model for ColumnEmail {} +impl Model for ColumnEnum {} +impl Model for ColumnIp {} +impl Model for ColumnUrl {} +impl Model for ColumnDatetime {} +impl Model for ColumnRelationship {} +impl Model for ColumnPoint {} +impl Model for ColumnLine {} +impl Model for ColumnPolygon {} +impl Model for ColumnVarchar {} +impl Model for ColumnText {} +impl Model for ColumnMediumtext {} +impl Model for ColumnLongtext {} +impl Model for Index {} +impl Model for ColumnIndex {} +impl Model for Row {} +impl Model for Document {} +impl Model for Log {} +impl Model for User {} +impl Model for AlgoMd5 {} +impl Model for AlgoSha {} +impl Model for AlgoPhpass {} +impl Model for AlgoBcrypt {} +impl Model for AlgoScrypt {} +impl Model for AlgoScryptModified {} +impl Model for AlgoArgon2 {} +impl Model for Preferences {} +impl Model for Session {} +impl Model for Identity {} +impl Model for Token {} +impl Model for Jwt {} +impl Model for Locale {} +impl Model for LocaleCode {} +impl Model for File {} +impl Model for Bucket {} +impl Model for ResourceToken {} +impl Model for Team {} +impl Model for Membership {} +impl Model for Site {} +impl Model for Function {} +impl Model for Runtime {} +impl Model for Framework {} +impl Model for FrameworkAdapter {} +impl Model for Deployment {} +impl Model for Execution {} +impl Model for Webhook {} +impl Model for Variable {} +impl Model for Country {} +impl Model for Continent {} +impl Model for Language {} +impl Model for Currency {} +impl Model for Phone {} +impl Model for HealthAntivirus {} +impl Model for HealthQueue {} +impl Model for HealthStatus {} +impl Model for HealthCertificate {} +impl Model for HealthTime {} +impl Model for Headers {} +impl Model for Specification {} +impl Model for MfaChallenge {} +impl Model for MfaRecoveryCodes {} +impl Model for MfaType {} +impl Model for MfaFactors {} +impl Model for Provider {} +impl Model for Message {} +impl Model for Topic {} +impl Model for Transaction {} +impl Model for Subscriber {} +impl Model for Target {} +impl Model for ActivityEvent {} +impl Model for BackupArchive {} +impl Model for BackupPolicy {} +impl Model for BackupRestoration {} +impl Model for ActivityEventList {} +impl Model for BackupArchiveList {} +impl Model for BackupPolicyList {} +impl Model for BackupRestorationList {} diff --git a/src/models/phone.rs b/src/models/phone.rs new file mode 100644 index 0000000..6972713 --- /dev/null +++ b/src/models/phone.rs @@ -0,0 +1,59 @@ +//! Phone model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Phone +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Phone { + /// Phone code. + #[serde(rename = "code")] + pub code: String, + /// Country two-character ISO 3166-1 alpha code. + #[serde(rename = "countryCode")] + pub country_code: String, + /// Country name. + #[serde(rename = "countryName")] + pub country_name: String, +} + +impl Phone { + /// Get code + pub fn code(&self) -> &String { + &self.code + } + + /// Get country_code + pub fn country_code(&self) -> &String { + &self.country_code + } + + /// Get country_name + pub fn country_name(&self) -> &String { + &self.country_name + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_phone_creation() { + let _model = ::default(); + let _ = _model.code(); + let _ = _model.country_code(); + let _ = _model.country_name(); + } + + #[test] + fn test_phone_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/phone_list.rs b/src/models/phone_list.rs new file mode 100644 index 0000000..7ba3216 --- /dev/null +++ b/src/models/phone_list.rs @@ -0,0 +1,50 @@ +//! PhoneList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Phones List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct PhoneList { + /// Total number of phones that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of phones. + #[serde(rename = "phones")] + pub phones: Vec, +} + +impl PhoneList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get phones + pub fn phones(&self) -> &Vec { + &self.phones + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_phone_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.phones(); + } + + #[test] + fn test_phone_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/preferences.rs b/src/models/preferences.rs new file mode 100644 index 0000000..5444ff3 --- /dev/null +++ b/src/models/preferences.rs @@ -0,0 +1,45 @@ +//! Preferences model for Appwrite SDK + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Preferences +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Preferences { + + #[serde(flatten)] + pub data: HashMap, +} + +impl Preferences { + + pub fn get(&self, key: &str) -> Option { + self.data.get(key) + .and_then(|v| serde_json::from_value(v.clone()).ok()) + } + + pub fn data(&self) -> &HashMap { + &self.data + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_preferences_creation() { + let _model = ::default(); + } + + #[test] + fn test_preferences_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/provider.rs b/src/models/provider.rs new file mode 100644 index 0000000..077450f --- /dev/null +++ b/src/models/provider.rs @@ -0,0 +1,119 @@ +//! Provider model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Provider +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Provider { + /// Provider ID. + #[serde(rename = "$id")] + pub id: String, + /// Provider creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Provider update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// The name for the provider instance. + #[serde(rename = "name")] + pub name: String, + /// The name of the provider service. + #[serde(rename = "provider")] + pub provider: String, + /// Is provider enabled? + #[serde(rename = "enabled")] + pub enabled: bool, + /// Type of provider. + #[serde(rename = "type")] + pub r#type: String, + /// Provider credentials. + #[serde(rename = "credentials")] + pub credentials: serde_json::Value, + /// Provider options. + #[serde(rename = "options")] + #[serde(skip_serializing_if = "Option::is_none")] + pub options: Option, +} + +impl Provider { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get provider + pub fn provider(&self) -> &String { + &self.provider + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get r#type + pub fn r#type(&self) -> &String { + &self.r#type + } + + /// Get credentials + pub fn credentials(&self) -> &serde_json::Value { + &self.credentials + } + + /// Set options + pub fn set_options(mut self, options: serde_json::Value) -> Self { + self.options = Some(options); + self + } + + /// Get options + pub fn options(&self) -> Option<&serde_json::Value> { + self.options.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_provider_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.provider(); + let _ = _model.enabled(); + let _ = _model.r#type(); + let _ = _model.credentials(); + } + + #[test] + fn test_provider_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/provider_list.rs b/src/models/provider_list.rs new file mode 100644 index 0000000..cc36da7 --- /dev/null +++ b/src/models/provider_list.rs @@ -0,0 +1,50 @@ +//! ProviderList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Provider list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ProviderList { + /// Total number of providers that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of providers. + #[serde(rename = "providers")] + pub providers: Vec, +} + +impl ProviderList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get providers + pub fn providers(&self) -> &Vec { + &self.providers + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_provider_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.providers(); + } + + #[test] + fn test_provider_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/resource_token.rs b/src/models/resource_token.rs new file mode 100644 index 0000000..9d796e2 --- /dev/null +++ b/src/models/resource_token.rs @@ -0,0 +1,96 @@ +//! ResourceToken model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// ResourceToken +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ResourceToken { + /// Token ID. + #[serde(rename = "$id")] + pub id: String, + /// Token creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Resource ID. + #[serde(rename = "resourceId")] + pub resource_id: String, + /// Resource type. + #[serde(rename = "resourceType")] + pub resource_type: String, + /// Token expiration date in ISO 8601 format. + #[serde(rename = "expire")] + pub expire: String, + /// JWT encoded string. + #[serde(rename = "secret")] + pub secret: String, + /// Most recent access date in ISO 8601 format. This attribute is only updated + /// again after 24 hours. + #[serde(rename = "accessedAt")] + pub accessed_at: String, +} + +impl ResourceToken { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get resource_id + pub fn resource_id(&self) -> &String { + &self.resource_id + } + + /// Get resource_type + pub fn resource_type(&self) -> &String { + &self.resource_type + } + + /// Get expire + pub fn expire(&self) -> &String { + &self.expire + } + + /// Get secret + pub fn secret(&self) -> &String { + &self.secret + } + + /// Get accessed_at + pub fn accessed_at(&self) -> &String { + &self.accessed_at + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_resource_token_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.resource_id(); + let _ = _model.resource_type(); + let _ = _model.expire(); + let _ = _model.secret(); + let _ = _model.accessed_at(); + } + + #[test] + fn test_resource_token_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/resource_token_list.rs b/src/models/resource_token_list.rs new file mode 100644 index 0000000..818755e --- /dev/null +++ b/src/models/resource_token_list.rs @@ -0,0 +1,50 @@ +//! ResourceTokenList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Resource Tokens List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct ResourceTokenList { + /// Total number of tokens that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of tokens. + #[serde(rename = "tokens")] + pub tokens: Vec, +} + +impl ResourceTokenList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get tokens + pub fn tokens(&self) -> &Vec { + &self.tokens + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_resource_token_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.tokens(); + } + + #[test] + fn test_resource_token_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/row.rs b/src/models/row.rs new file mode 100644 index 0000000..d90bc78 --- /dev/null +++ b/src/models/row.rs @@ -0,0 +1,109 @@ +//! Row model for Appwrite SDK + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Row +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Row { + /// Row ID. + #[serde(rename = "$id")] + pub id: String, + /// Row sequence ID. + #[serde(rename = "$sequence")] + pub sequence: String, + /// Table ID. + #[serde(rename = "$tableId")] + pub table_id: String, + /// Database ID. + #[serde(rename = "$databaseId")] + pub database_id: String, + /// Row creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Row update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Row permissions. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "$permissions")] + pub permissions: Vec, + + #[serde(flatten)] + pub data: HashMap, +} + +impl Row { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get sequence + pub fn sequence(&self) -> &String { + &self.sequence + } + + /// Get table_id + pub fn table_id(&self) -> &String { + &self.table_id + } + + /// Get database_id + pub fn database_id(&self) -> &String { + &self.database_id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + + pub fn get(&self, key: &str) -> Option { + self.data.get(key) + .and_then(|v| serde_json::from_value(v.clone()).ok()) + } + + pub fn data(&self) -> &HashMap { + &self.data + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_row_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.sequence(); + let _ = _model.table_id(); + let _ = _model.database_id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + } + + #[test] + fn test_row_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/row_list.rs b/src/models/row_list.rs new file mode 100644 index 0000000..28e8091 --- /dev/null +++ b/src/models/row_list.rs @@ -0,0 +1,50 @@ +//! RowList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Rows List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct RowList { + /// Total number of rows that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of rows. + #[serde(rename = "rows")] + pub rows: Vec, +} + +impl RowList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get rows + pub fn rows(&self) -> &Vec { + &self.rows + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_row_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.rows(); + } + + #[test] + fn test_row_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/runtime.rs b/src/models/runtime.rs new file mode 100644 index 0000000..3c71b99 --- /dev/null +++ b/src/models/runtime.rs @@ -0,0 +1,104 @@ +//! Runtime model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Runtime +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Runtime { + /// Runtime ID. + #[serde(rename = "$id")] + pub id: String, + /// Parent runtime key. + #[serde(rename = "key")] + pub key: String, + /// Runtime Name. + #[serde(rename = "name")] + pub name: String, + /// Runtime version. + #[serde(rename = "version")] + pub version: String, + /// Base Docker image used to build the runtime. + #[serde(rename = "base")] + pub base: String, + /// Image name of Docker Hub. + #[serde(rename = "image")] + pub image: String, + /// Name of the logo image. + #[serde(rename = "logo")] + pub logo: String, + /// List of supported architectures. + #[serde(rename = "supports")] + pub supports: Vec, +} + +impl Runtime { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get version + pub fn version(&self) -> &String { + &self.version + } + + /// Get base + pub fn base(&self) -> &String { + &self.base + } + + /// Get image + pub fn image(&self) -> &String { + &self.image + } + + /// Get logo + pub fn logo(&self) -> &String { + &self.logo + } + + /// Get supports + pub fn supports(&self) -> &Vec { + &self.supports + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_runtime_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.key(); + let _ = _model.name(); + let _ = _model.version(); + let _ = _model.base(); + let _ = _model.image(); + let _ = _model.logo(); + let _ = _model.supports(); + } + + #[test] + fn test_runtime_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/runtime_list.rs b/src/models/runtime_list.rs new file mode 100644 index 0000000..aa35316 --- /dev/null +++ b/src/models/runtime_list.rs @@ -0,0 +1,50 @@ +//! RuntimeList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Runtimes List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct RuntimeList { + /// Total number of runtimes that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of runtimes. + #[serde(rename = "runtimes")] + pub runtimes: Vec, +} + +impl RuntimeList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get runtimes + pub fn runtimes(&self) -> &Vec { + &self.runtimes + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_runtime_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.runtimes(); + } + + #[test] + fn test_runtime_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/session.rs b/src/models/session.rs new file mode 100644 index 0000000..bcbe1e8 --- /dev/null +++ b/src/models/session.rs @@ -0,0 +1,297 @@ +//! Session model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Session +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Session { + /// Session ID. + #[serde(rename = "$id")] + pub id: String, + /// Session creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Session update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// Session expiration date in ISO 8601 format. + #[serde(rename = "expire")] + pub expire: String, + /// Session Provider. + #[serde(rename = "provider")] + pub provider: String, + /// Session Provider User ID. + #[serde(rename = "providerUid")] + pub provider_uid: String, + /// Session Provider Access Token. + #[serde(rename = "providerAccessToken")] + pub provider_access_token: String, + /// The date of when the access token expires in ISO 8601 format. + #[serde(rename = "providerAccessTokenExpiry")] + pub provider_access_token_expiry: String, + /// Session Provider Refresh Token. + #[serde(rename = "providerRefreshToken")] + pub provider_refresh_token: String, + /// IP in use when the session was created. + #[serde(rename = "ip")] + pub ip: String, + /// Operating system code name. View list of [available + /// options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). + #[serde(rename = "osCode")] + pub os_code: String, + /// Operating system name. + #[serde(rename = "osName")] + pub os_name: String, + /// Operating system version. + #[serde(rename = "osVersion")] + pub os_version: String, + /// Client type. + #[serde(rename = "clientType")] + pub client_type: String, + /// Client code name. View list of [available + /// options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). + #[serde(rename = "clientCode")] + pub client_code: String, + /// Client name. + #[serde(rename = "clientName")] + pub client_name: String, + /// Client version. + #[serde(rename = "clientVersion")] + pub client_version: String, + /// Client engine name. + #[serde(rename = "clientEngine")] + pub client_engine: String, + /// Client engine name. + #[serde(rename = "clientEngineVersion")] + pub client_engine_version: String, + /// Device name. + #[serde(rename = "deviceName")] + pub device_name: String, + /// Device brand name. + #[serde(rename = "deviceBrand")] + pub device_brand: String, + /// Device model name. + #[serde(rename = "deviceModel")] + pub device_model: String, + /// Country two-character ISO 3166-1 alpha code. + #[serde(rename = "countryCode")] + pub country_code: String, + /// Country name. + #[serde(rename = "countryName")] + pub country_name: String, + /// Returns true if this the current user session. + #[serde(rename = "current")] + pub current: bool, + /// Returns a list of active session factors. + #[serde(rename = "factors")] + pub factors: Vec, + /// Secret used to authenticate the user. Only included if the request was made + /// with an API key + #[serde(rename = "secret")] + pub secret: String, + /// Most recent date in ISO 8601 format when the session successfully passed + /// MFA challenge. + #[serde(rename = "mfaUpdatedAt")] + pub mfa_updated_at: String, +} + +impl Session { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get expire + pub fn expire(&self) -> &String { + &self.expire + } + + /// Get provider + pub fn provider(&self) -> &String { + &self.provider + } + + /// Get provider_uid + pub fn provider_uid(&self) -> &String { + &self.provider_uid + } + + /// Get provider_access_token + pub fn provider_access_token(&self) -> &String { + &self.provider_access_token + } + + /// Get provider_access_token_expiry + pub fn provider_access_token_expiry(&self) -> &String { + &self.provider_access_token_expiry + } + + /// Get provider_refresh_token + pub fn provider_refresh_token(&self) -> &String { + &self.provider_refresh_token + } + + /// Get ip + pub fn ip(&self) -> &String { + &self.ip + } + + /// Get os_code + pub fn os_code(&self) -> &String { + &self.os_code + } + + /// Get os_name + pub fn os_name(&self) -> &String { + &self.os_name + } + + /// Get os_version + pub fn os_version(&self) -> &String { + &self.os_version + } + + /// Get client_type + pub fn client_type(&self) -> &String { + &self.client_type + } + + /// Get client_code + pub fn client_code(&self) -> &String { + &self.client_code + } + + /// Get client_name + pub fn client_name(&self) -> &String { + &self.client_name + } + + /// Get client_version + pub fn client_version(&self) -> &String { + &self.client_version + } + + /// Get client_engine + pub fn client_engine(&self) -> &String { + &self.client_engine + } + + /// Get client_engine_version + pub fn client_engine_version(&self) -> &String { + &self.client_engine_version + } + + /// Get device_name + pub fn device_name(&self) -> &String { + &self.device_name + } + + /// Get device_brand + pub fn device_brand(&self) -> &String { + &self.device_brand + } + + /// Get device_model + pub fn device_model(&self) -> &String { + &self.device_model + } + + /// Get country_code + pub fn country_code(&self) -> &String { + &self.country_code + } + + /// Get country_name + pub fn country_name(&self) -> &String { + &self.country_name + } + + /// Get current + pub fn current(&self) -> &bool { + &self.current + } + + /// Get factors + pub fn factors(&self) -> &Vec { + &self.factors + } + + /// Get secret + pub fn secret(&self) -> &String { + &self.secret + } + + /// Get mfa_updated_at + pub fn mfa_updated_at(&self) -> &String { + &self.mfa_updated_at + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_session_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.user_id(); + let _ = _model.expire(); + let _ = _model.provider(); + let _ = _model.provider_uid(); + let _ = _model.provider_access_token(); + let _ = _model.provider_access_token_expiry(); + let _ = _model.provider_refresh_token(); + let _ = _model.ip(); + let _ = _model.os_code(); + let _ = _model.os_name(); + let _ = _model.os_version(); + let _ = _model.client_type(); + let _ = _model.client_code(); + let _ = _model.client_name(); + let _ = _model.client_version(); + let _ = _model.client_engine(); + let _ = _model.client_engine_version(); + let _ = _model.device_name(); + let _ = _model.device_brand(); + let _ = _model.device_model(); + let _ = _model.country_code(); + let _ = _model.country_name(); + let _ = _model.current(); + let _ = _model.factors(); + let _ = _model.secret(); + let _ = _model.mfa_updated_at(); + } + + #[test] + fn test_session_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/session_list.rs b/src/models/session_list.rs new file mode 100644 index 0000000..8ca8a5b --- /dev/null +++ b/src/models/session_list.rs @@ -0,0 +1,50 @@ +//! SessionList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Sessions List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct SessionList { + /// Total number of sessions that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of sessions. + #[serde(rename = "sessions")] + pub sessions: Vec, +} + +impl SessionList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get sessions + pub fn sessions(&self) -> &Vec { + &self.sessions + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_session_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.sessions(); + } + + #[test] + fn test_session_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/site.rs b/src/models/site.rs new file mode 100644 index 0000000..5004e82 --- /dev/null +++ b/src/models/site.rs @@ -0,0 +1,329 @@ +//! Site model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Site +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Site { + /// Site ID. + #[serde(rename = "$id")] + pub id: String, + /// Site creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Site update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Site name. + #[serde(rename = "name")] + pub name: String, + /// Site enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Is the site deployed with the latest configuration? This is set to false if + /// you've changed an environment variables, entrypoint, commands, or other + /// settings that needs redeploy to be applied. When the value is false, + /// redeploy the site to update it with the latest configuration. + #[serde(rename = "live")] + pub live: bool, + /// When disabled, request logs will exclude logs and errors, and site + /// responses will be slightly faster. + #[serde(rename = "logging")] + pub logging: bool, + /// Site framework. + #[serde(rename = "framework")] + pub framework: String, + /// How many days to keep the non-active deployments before they will be + /// automatically deleted. + #[serde(rename = "deploymentRetention")] + pub deployment_retention: i64, + /// Site's active deployment ID. + #[serde(rename = "deploymentId")] + pub deployment_id: String, + /// Active deployment creation date in ISO 8601 format. + #[serde(rename = "deploymentCreatedAt")] + pub deployment_created_at: String, + /// Screenshot of active deployment with light theme preference file ID. + #[serde(rename = "deploymentScreenshotLight")] + pub deployment_screenshot_light: String, + /// Screenshot of active deployment with dark theme preference file ID. + #[serde(rename = "deploymentScreenshotDark")] + pub deployment_screenshot_dark: String, + /// Site's latest deployment ID. + #[serde(rename = "latestDeploymentId")] + pub latest_deployment_id: String, + /// Latest deployment creation date in ISO 8601 format. + #[serde(rename = "latestDeploymentCreatedAt")] + pub latest_deployment_created_at: String, + /// Status of latest deployment. Possible values are "waiting", "processing", + /// "building", "ready", and "failed". + #[serde(rename = "latestDeploymentStatus")] + pub latest_deployment_status: String, + /// Site variables. + #[serde(rename = "vars")] + pub vars: Vec, + /// Site request timeout in seconds. + #[serde(rename = "timeout")] + pub timeout: i64, + /// The install command used to install the site dependencies. + #[serde(rename = "installCommand")] + pub install_command: String, + /// The build command used to build the site. + #[serde(rename = "buildCommand")] + pub build_command: String, + /// Custom command to use when starting site runtime. + #[serde(rename = "startCommand")] + pub start_command: String, + /// The directory where the site build output is located. + #[serde(rename = "outputDirectory")] + pub output_directory: String, + /// Site VCS (Version Control System) installation id. + #[serde(rename = "installationId")] + pub installation_id: String, + /// VCS (Version Control System) Repository ID + #[serde(rename = "providerRepositoryId")] + pub provider_repository_id: String, + /// VCS (Version Control System) branch name + #[serde(rename = "providerBranch")] + pub provider_branch: String, + /// Path to site in VCS (Version Control System) repository + #[serde(rename = "providerRootDirectory")] + pub provider_root_directory: String, + /// Is VCS (Version Control System) connection is in silent mode? When in + /// silence mode, no comments will be posted on the repository pull or merge + /// requests + #[serde(rename = "providerSilentMode")] + pub provider_silent_mode: bool, + /// Machine specification for deployment builds. + #[serde(rename = "buildSpecification")] + pub build_specification: String, + /// Machine specification for SSR executions. + #[serde(rename = "runtimeSpecification")] + pub runtime_specification: String, + /// Site build runtime. + #[serde(rename = "buildRuntime")] + pub build_runtime: String, + /// Site framework adapter. + #[serde(rename = "adapter")] + pub adapter: String, + /// Name of fallback file to use instead of 404 page. If null, Appwrite 404 + /// page will be displayed. + #[serde(rename = "fallbackFile")] + pub fallback_file: String, +} + +impl Site { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get live + pub fn live(&self) -> &bool { + &self.live + } + + /// Get logging + pub fn logging(&self) -> &bool { + &self.logging + } + + /// Get framework + pub fn framework(&self) -> &String { + &self.framework + } + + /// Get deployment_retention + pub fn deployment_retention(&self) -> &i64 { + &self.deployment_retention + } + + /// Get deployment_id + pub fn deployment_id(&self) -> &String { + &self.deployment_id + } + + /// Get deployment_created_at + pub fn deployment_created_at(&self) -> &String { + &self.deployment_created_at + } + + /// Get deployment_screenshot_light + pub fn deployment_screenshot_light(&self) -> &String { + &self.deployment_screenshot_light + } + + /// Get deployment_screenshot_dark + pub fn deployment_screenshot_dark(&self) -> &String { + &self.deployment_screenshot_dark + } + + /// Get latest_deployment_id + pub fn latest_deployment_id(&self) -> &String { + &self.latest_deployment_id + } + + /// Get latest_deployment_created_at + pub fn latest_deployment_created_at(&self) -> &String { + &self.latest_deployment_created_at + } + + /// Get latest_deployment_status + pub fn latest_deployment_status(&self) -> &String { + &self.latest_deployment_status + } + + /// Get vars + pub fn vars(&self) -> &Vec { + &self.vars + } + + /// Get timeout + pub fn timeout(&self) -> &i64 { + &self.timeout + } + + /// Get install_command + pub fn install_command(&self) -> &String { + &self.install_command + } + + /// Get build_command + pub fn build_command(&self) -> &String { + &self.build_command + } + + /// Get start_command + pub fn start_command(&self) -> &String { + &self.start_command + } + + /// Get output_directory + pub fn output_directory(&self) -> &String { + &self.output_directory + } + + /// Get installation_id + pub fn installation_id(&self) -> &String { + &self.installation_id + } + + /// Get provider_repository_id + pub fn provider_repository_id(&self) -> &String { + &self.provider_repository_id + } + + /// Get provider_branch + pub fn provider_branch(&self) -> &String { + &self.provider_branch + } + + /// Get provider_root_directory + pub fn provider_root_directory(&self) -> &String { + &self.provider_root_directory + } + + /// Get provider_silent_mode + pub fn provider_silent_mode(&self) -> &bool { + &self.provider_silent_mode + } + + /// Get build_specification + pub fn build_specification(&self) -> &String { + &self.build_specification + } + + /// Get runtime_specification + pub fn runtime_specification(&self) -> &String { + &self.runtime_specification + } + + /// Get build_runtime + pub fn build_runtime(&self) -> &String { + &self.build_runtime + } + + /// Get adapter + pub fn adapter(&self) -> &String { + &self.adapter + } + + /// Get fallback_file + pub fn fallback_file(&self) -> &String { + &self.fallback_file + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_site_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.enabled(); + let _ = _model.live(); + let _ = _model.logging(); + let _ = _model.framework(); + let _ = _model.deployment_retention(); + let _ = _model.deployment_id(); + let _ = _model.deployment_created_at(); + let _ = _model.deployment_screenshot_light(); + let _ = _model.deployment_screenshot_dark(); + let _ = _model.latest_deployment_id(); + let _ = _model.latest_deployment_created_at(); + let _ = _model.latest_deployment_status(); + let _ = _model.vars(); + let _ = _model.timeout(); + let _ = _model.install_command(); + let _ = _model.build_command(); + let _ = _model.start_command(); + let _ = _model.output_directory(); + let _ = _model.installation_id(); + let _ = _model.provider_repository_id(); + let _ = _model.provider_branch(); + let _ = _model.provider_root_directory(); + let _ = _model.provider_silent_mode(); + let _ = _model.build_specification(); + let _ = _model.runtime_specification(); + let _ = _model.build_runtime(); + let _ = _model.adapter(); + let _ = _model.fallback_file(); + } + + #[test] + fn test_site_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/site_list.rs b/src/models/site_list.rs new file mode 100644 index 0000000..231833e --- /dev/null +++ b/src/models/site_list.rs @@ -0,0 +1,50 @@ +//! SiteList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Sites List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct SiteList { + /// Total number of sites that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of sites. + #[serde(rename = "sites")] + pub sites: Vec, +} + +impl SiteList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get sites + pub fn sites(&self) -> &Vec { + &self.sites + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_site_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.sites(); + } + + #[test] + fn test_site_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/specification.rs b/src/models/specification.rs new file mode 100644 index 0000000..232e52e --- /dev/null +++ b/src/models/specification.rs @@ -0,0 +1,68 @@ +//! Specification model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Specification +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Specification { + /// Memory size in MB. + #[serde(rename = "memory")] + pub memory: i64, + /// Number of CPUs. + #[serde(rename = "cpus")] + pub cpus: f64, + /// Is size enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Size slug. + #[serde(rename = "slug")] + pub slug: String, +} + +impl Specification { + /// Get memory + pub fn memory(&self) -> &i64 { + &self.memory + } + + /// Get cpus + pub fn cpus(&self) -> &f64 { + &self.cpus + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get slug + pub fn slug(&self) -> &String { + &self.slug + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_specification_creation() { + let _model = ::default(); + let _ = _model.memory(); + let _ = _model.cpus(); + let _ = _model.enabled(); + let _ = _model.slug(); + } + + #[test] + fn test_specification_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/specification_list.rs b/src/models/specification_list.rs new file mode 100644 index 0000000..7028fd0 --- /dev/null +++ b/src/models/specification_list.rs @@ -0,0 +1,50 @@ +//! SpecificationList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Specifications List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct SpecificationList { + /// Total number of specifications that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of specifications. + #[serde(rename = "specifications")] + pub specifications: Vec, +} + +impl SpecificationList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get specifications + pub fn specifications(&self) -> &Vec { + &self.specifications + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_specification_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.specifications(); + } + + #[test] + fn test_specification_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/subscriber.rs b/src/models/subscriber.rs new file mode 100644 index 0000000..c4f0f36 --- /dev/null +++ b/src/models/subscriber.rs @@ -0,0 +1,114 @@ +//! Subscriber model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Subscriber +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Subscriber { + /// Subscriber ID. + #[serde(rename = "$id")] + pub id: String, + /// Subscriber creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Subscriber update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Target ID. + #[serde(rename = "targetId")] + pub target_id: String, + /// Target. + #[serde(rename = "target")] + pub target: crate::models::Target, + /// Topic ID. + #[serde(rename = "userId")] + pub user_id: String, + /// User Name. + #[serde(rename = "userName")] + pub user_name: String, + /// Topic ID. + #[serde(rename = "topicId")] + pub topic_id: String, + /// The target provider type. Can be one of the following: `email`, `sms` or + /// `push`. + #[serde(rename = "providerType")] + pub provider_type: String, +} + +impl Subscriber { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get target_id + pub fn target_id(&self) -> &String { + &self.target_id + } + + /// Get target + pub fn target(&self) -> &crate::models::Target { + &self.target + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get user_name + pub fn user_name(&self) -> &String { + &self.user_name + } + + /// Get topic_id + pub fn topic_id(&self) -> &String { + &self.topic_id + } + + /// Get provider_type + pub fn provider_type(&self) -> &String { + &self.provider_type + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_subscriber_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.target_id(); + let _ = _model.target(); + let _ = _model.user_id(); + let _ = _model.user_name(); + let _ = _model.topic_id(); + let _ = _model.provider_type(); + } + + #[test] + fn test_subscriber_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/subscriber_list.rs b/src/models/subscriber_list.rs new file mode 100644 index 0000000..083681d --- /dev/null +++ b/src/models/subscriber_list.rs @@ -0,0 +1,50 @@ +//! SubscriberList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Subscriber list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct SubscriberList { + /// Total number of subscribers that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of subscribers. + #[serde(rename = "subscribers")] + pub subscribers: Vec, +} + +impl SubscriberList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get subscribers + pub fn subscribers(&self) -> &Vec { + &self.subscribers + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_subscriber_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.subscribers(); + } + + #[test] + fn test_subscriber_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/table.rs b/src/models/table.rs new file mode 100644 index 0000000..e7af5b6 --- /dev/null +++ b/src/models/table.rs @@ -0,0 +1,144 @@ +//! Table model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Table +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Table { + /// Table ID. + #[serde(rename = "$id")] + pub id: String, + /// Table creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Table update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Table permissions. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "$permissions")] + pub permissions: Vec, + /// Database ID. + #[serde(rename = "databaseId")] + pub database_id: String, + /// Table name. + #[serde(rename = "name")] + pub name: String, + /// Table enabled. Can be 'enabled' or 'disabled'. When disabled, the table is + /// inaccessible to users, but remains accessible to Server SDKs using API + /// keys. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Whether row-level permissions are enabled. [Learn more about + /// permissions](https://appwrite.io/docs/permissions). + #[serde(rename = "rowSecurity")] + pub row_security: bool, + /// Table columns. + #[serde(rename = "columns")] + pub columns: Vec, + /// Table indexes. + #[serde(rename = "indexes")] + pub indexes: Vec, + /// Maximum row size in bytes. Returns 0 when no limit applies. + #[serde(rename = "bytesMax")] + pub bytes_max: i64, + /// Currently used row size in bytes based on defined columns. + #[serde(rename = "bytesUsed")] + pub bytes_used: i64, +} + +impl Table { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get permissions + pub fn permissions(&self) -> &Vec { + &self.permissions + } + + /// Get database_id + pub fn database_id(&self) -> &String { + &self.database_id + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get row_security + pub fn row_security(&self) -> &bool { + &self.row_security + } + + /// Get columns + pub fn columns(&self) -> &Vec { + &self.columns + } + + /// Get indexes + pub fn indexes(&self) -> &Vec { + &self.indexes + } + + /// Get bytes_max + pub fn bytes_max(&self) -> &i64 { + &self.bytes_max + } + + /// Get bytes_used + pub fn bytes_used(&self) -> &i64 { + &self.bytes_used + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_table_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.permissions(); + let _ = _model.database_id(); + let _ = _model.name(); + let _ = _model.enabled(); + let _ = _model.row_security(); + let _ = _model.columns(); + let _ = _model.indexes(); + let _ = _model.bytes_max(); + let _ = _model.bytes_used(); + } + + #[test] + fn test_table_serialization() { + let model =
::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/table_list.rs b/src/models/table_list.rs new file mode 100644 index 0000000..372ea24 --- /dev/null +++ b/src/models/table_list.rs @@ -0,0 +1,50 @@ +//! TableList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Tables List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct TableList { + /// Total number of tables that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of tables. + #[serde(rename = "tables")] + pub tables: Vec, +} + +impl TableList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get tables + pub fn tables(&self) -> &Vec { + &self.tables + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_table_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.tables(); + } + + #[test] + fn test_table_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/target.rs b/src/models/target.rs new file mode 100644 index 0000000..56edfb2 --- /dev/null +++ b/src/models/target.rs @@ -0,0 +1,120 @@ +//! Target model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Target +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Target { + /// Target ID. + #[serde(rename = "$id")] + pub id: String, + /// Target creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Target update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Target Name. + #[serde(rename = "name")] + pub name: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// Provider ID. + #[serde(rename = "providerId")] + #[serde(skip_serializing_if = "Option::is_none")] + pub provider_id: Option, + /// The target provider type. Can be one of the following: `email`, `sms` or + /// `push`. + #[serde(rename = "providerType")] + pub provider_type: String, + /// The target identifier. + #[serde(rename = "identifier")] + pub identifier: String, + /// Is the target expired. + #[serde(rename = "expired")] + pub expired: bool, +} + +impl Target { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Set provider_id + pub fn set_provider_id(mut self, provider_id: String) -> Self { + self.provider_id = Some(provider_id); + self + } + + /// Get provider_id + pub fn provider_id(&self) -> Option<&String> { + self.provider_id.as_ref() + } + + /// Get provider_type + pub fn provider_type(&self) -> &String { + &self.provider_type + } + + /// Get identifier + pub fn identifier(&self) -> &String { + &self.identifier + } + + /// Get expired + pub fn expired(&self) -> &bool { + &self.expired + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_target_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.user_id(); + let _ = _model.provider_type(); + let _ = _model.identifier(); + let _ = _model.expired(); + } + + #[test] + fn test_target_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/target_list.rs b/src/models/target_list.rs new file mode 100644 index 0000000..593ca5b --- /dev/null +++ b/src/models/target_list.rs @@ -0,0 +1,50 @@ +//! TargetList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Target list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct TargetList { + /// Total number of targets that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of targets. + #[serde(rename = "targets")] + pub targets: Vec, +} + +impl TargetList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get targets + pub fn targets(&self) -> &Vec { + &self.targets + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_target_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.targets(); + } + + #[test] + fn test_target_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/team.rs b/src/models/team.rs new file mode 100644 index 0000000..a5eb40f --- /dev/null +++ b/src/models/team.rs @@ -0,0 +1,86 @@ +//! Team model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Team +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Team { + /// Team ID. + #[serde(rename = "$id")] + pub id: String, + /// Team creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Team update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Team name. + #[serde(rename = "name")] + pub name: String, + /// Total number of team members. + #[serde(rename = "total")] + pub total: i64, + /// Team preferences as a key-value object + #[serde(rename = "prefs")] + pub prefs: crate::models::Preferences, +} + +impl Team { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get prefs + pub fn prefs(&self) -> &crate::models::Preferences { + &self.prefs + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_team_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.total(); + let _ = _model.prefs(); + } + + #[test] + fn test_team_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/team_list.rs b/src/models/team_list.rs new file mode 100644 index 0000000..fe267bb --- /dev/null +++ b/src/models/team_list.rs @@ -0,0 +1,50 @@ +//! TeamList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Teams List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct TeamList { + /// Total number of teams that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of teams. + #[serde(rename = "teams")] + pub teams: Vec, +} + +impl TeamList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get teams + pub fn teams(&self) -> &Vec { + &self.teams + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_team_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.teams(); + } + + #[test] + fn test_team_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/token.rs b/src/models/token.rs new file mode 100644 index 0000000..e2b1a4f --- /dev/null +++ b/src/models/token.rs @@ -0,0 +1,89 @@ +//! Token model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Token +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Token { + /// Token ID. + #[serde(rename = "$id")] + pub id: String, + /// Token creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// User ID. + #[serde(rename = "userId")] + pub user_id: String, + /// Token secret key. This will return an empty string unless the response is + /// returned using an API key or as part of a webhook payload. + #[serde(rename = "secret")] + pub secret: String, + /// Token expiration date in ISO 8601 format. + #[serde(rename = "expire")] + pub expire: String, + /// Security phrase of a token. Empty if security phrase was not requested when + /// creating a token. It includes randomly generated phrase which is also sent + /// in the external resource such as email. + #[serde(rename = "phrase")] + pub phrase: String, +} + +impl Token { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get user_id + pub fn user_id(&self) -> &String { + &self.user_id + } + + /// Get secret + pub fn secret(&self) -> &String { + &self.secret + } + + /// Get expire + pub fn expire(&self) -> &String { + &self.expire + } + + /// Get phrase + pub fn phrase(&self) -> &String { + &self.phrase + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_token_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.user_id(); + let _ = _model.secret(); + let _ = _model.expire(); + let _ = _model.phrase(); + } + + #[test] + fn test_token_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/topic.rs b/src/models/topic.rs new file mode 100644 index 0000000..3dbc2f7 --- /dev/null +++ b/src/models/topic.rs @@ -0,0 +1,104 @@ +//! Topic model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Topic +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Topic { + /// Topic ID. + #[serde(rename = "$id")] + pub id: String, + /// Topic creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Topic update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// The name of the topic. + #[serde(rename = "name")] + pub name: String, + /// Total count of email subscribers subscribed to the topic. + #[serde(rename = "emailTotal")] + pub email_total: i64, + /// Total count of SMS subscribers subscribed to the topic. + #[serde(rename = "smsTotal")] + pub sms_total: i64, + /// Total count of push subscribers subscribed to the topic. + #[serde(rename = "pushTotal")] + pub push_total: i64, + /// Subscribe permissions. + #[serde(rename = "subscribe")] + pub subscribe: Vec, +} + +impl Topic { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get email_total + pub fn email_total(&self) -> &i64 { + &self.email_total + } + + /// Get sms_total + pub fn sms_total(&self) -> &i64 { + &self.sms_total + } + + /// Get push_total + pub fn push_total(&self) -> &i64 { + &self.push_total + } + + /// Get subscribe + pub fn subscribe(&self) -> &Vec { + &self.subscribe + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_topic_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.email_total(); + let _ = _model.sms_total(); + let _ = _model.push_total(); + let _ = _model.subscribe(); + } + + #[test] + fn test_topic_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/topic_list.rs b/src/models/topic_list.rs new file mode 100644 index 0000000..a5dbbad --- /dev/null +++ b/src/models/topic_list.rs @@ -0,0 +1,50 @@ +//! TopicList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Topic list +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct TopicList { + /// Total number of topics that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of topics. + #[serde(rename = "topics")] + pub topics: Vec, +} + +impl TopicList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get topics + pub fn topics(&self) -> &Vec { + &self.topics + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_topic_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.topics(); + } + + #[test] + fn test_topic_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/transaction.rs b/src/models/transaction.rs new file mode 100644 index 0000000..758bc98 --- /dev/null +++ b/src/models/transaction.rs @@ -0,0 +1,87 @@ +//! Transaction model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Transaction +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Transaction { + /// Transaction ID. + #[serde(rename = "$id")] + pub id: String, + /// Transaction creation time in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Transaction update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Current status of the transaction. One of: pending, committing, committed, + /// rolled_back, failed. + #[serde(rename = "status")] + pub status: String, + /// Number of operations in the transaction. + #[serde(rename = "operations")] + pub operations: i64, + /// Expiration time in ISO 8601 format. + #[serde(rename = "expiresAt")] + pub expires_at: String, +} + +impl Transaction { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get status + pub fn status(&self) -> &String { + &self.status + } + + /// Get operations + pub fn operations(&self) -> &i64 { + &self.operations + } + + /// Get expires_at + pub fn expires_at(&self) -> &String { + &self.expires_at + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_transaction_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.status(); + let _ = _model.operations(); + let _ = _model.expires_at(); + } + + #[test] + fn test_transaction_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/transaction_list.rs b/src/models/transaction_list.rs new file mode 100644 index 0000000..12a01d2 --- /dev/null +++ b/src/models/transaction_list.rs @@ -0,0 +1,50 @@ +//! TransactionList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Transaction List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct TransactionList { + /// Total number of transactions that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of transactions. + #[serde(rename = "transactions")] + pub transactions: Vec, +} + +impl TransactionList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get transactions + pub fn transactions(&self) -> &Vec { + &self.transactions + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_transaction_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.transactions(); + } + + #[test] + fn test_transaction_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/user.rs b/src/models/user.rs new file mode 100644 index 0000000..06c0d62 --- /dev/null +++ b/src/models/user.rs @@ -0,0 +1,256 @@ +//! User model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// User +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct User { + /// User ID. + #[serde(rename = "$id")] + pub id: String, + /// User creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// User update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// User name. + #[serde(rename = "name")] + pub name: String, + /// Hashed user password. + #[serde(rename = "password")] + #[serde(skip_serializing_if = "Option::is_none")] + pub password: Option, + /// Password hashing algorithm. + #[serde(rename = "hash")] + #[serde(skip_serializing_if = "Option::is_none")] + pub hash: Option, + /// Password hashing algorithm configuration. + #[serde(rename = "hashOptions")] + #[serde(skip_serializing_if = "Option::is_none")] + pub hash_options: Option, + /// User registration date in ISO 8601 format. + #[serde(rename = "registration")] + pub registration: String, + /// User status. Pass `true` for enabled and `false` for disabled. + #[serde(rename = "status")] + pub status: bool, + /// Labels for the user. + #[serde(rename = "labels")] + pub labels: Vec, + /// Password update time in ISO 8601 format. + #[serde(rename = "passwordUpdate")] + pub password_update: String, + /// User email address. + #[serde(rename = "email")] + pub email: String, + /// User phone number in E.164 format. + #[serde(rename = "phone")] + pub phone: String, + /// Email verification status. + #[serde(rename = "emailVerification")] + pub email_verification: bool, + /// Phone verification status. + #[serde(rename = "phoneVerification")] + pub phone_verification: bool, + /// Multi factor authentication status. + #[serde(rename = "mfa")] + pub mfa: bool, + /// User preferences as a key-value object + #[serde(rename = "prefs")] + pub prefs: crate::models::Preferences, + /// A user-owned message receiver. A single user may have multiple e.g. emails, + /// phones, and a browser. Each target is registered with a single provider. + #[serde(rename = "targets")] + pub targets: Vec, + /// Most recent access date in ISO 8601 format. This attribute is only updated + /// again after 24 hours. + #[serde(rename = "accessedAt")] + pub accessed_at: String, + /// Whether the user can impersonate other users. + #[serde(rename = "impersonator")] + #[serde(skip_serializing_if = "Option::is_none")] + pub impersonator: Option, + /// ID of the original actor performing the impersonation. Present only when + /// the current request is impersonating another user. Internal audit logs + /// attribute the action to this user, while the impersonated target is + /// recorded only in internal audit payload data. + #[serde(rename = "impersonatorUserId")] + #[serde(skip_serializing_if = "Option::is_none")] + pub impersonator_user_id: Option, +} + +impl User { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Set password + pub fn set_password(mut self, password: String) -> Self { + self.password = Some(password); + self + } + + /// Get password + pub fn password(&self) -> Option<&String> { + self.password.as_ref() + } + + /// Set hash + pub fn set_hash(mut self, hash: String) -> Self { + self.hash = Some(hash); + self + } + + /// Get hash + pub fn hash(&self) -> Option<&String> { + self.hash.as_ref() + } + + /// Set hash_options + pub fn set_hash_options(mut self, hash_options: serde_json::Value) -> Self { + self.hash_options = Some(hash_options); + self + } + + /// Get hash_options + pub fn hash_options(&self) -> Option<&serde_json::Value> { + self.hash_options.as_ref() + } + + /// Get registration + pub fn registration(&self) -> &String { + &self.registration + } + + /// Get status + pub fn status(&self) -> &bool { + &self.status + } + + /// Get labels + pub fn labels(&self) -> &Vec { + &self.labels + } + + /// Get password_update + pub fn password_update(&self) -> &String { + &self.password_update + } + + /// Get email + pub fn email(&self) -> &String { + &self.email + } + + /// Get phone + pub fn phone(&self) -> &String { + &self.phone + } + + /// Get email_verification + pub fn email_verification(&self) -> &bool { + &self.email_verification + } + + /// Get phone_verification + pub fn phone_verification(&self) -> &bool { + &self.phone_verification + } + + /// Get mfa + pub fn mfa(&self) -> &bool { + &self.mfa + } + + /// Get prefs + pub fn prefs(&self) -> &crate::models::Preferences { + &self.prefs + } + + /// Get targets + pub fn targets(&self) -> &Vec { + &self.targets + } + + /// Get accessed_at + pub fn accessed_at(&self) -> &String { + &self.accessed_at + } + + /// Set impersonator + pub fn set_impersonator(mut self, impersonator: bool) -> Self { + self.impersonator = Some(impersonator); + self + } + + /// Get impersonator + pub fn impersonator(&self) -> Option<&bool> { + self.impersonator.as_ref() + } + + /// Set impersonator_user_id + pub fn set_impersonator_user_id(mut self, impersonator_user_id: String) -> Self { + self.impersonator_user_id = Some(impersonator_user_id); + self + } + + /// Get impersonator_user_id + pub fn impersonator_user_id(&self) -> Option<&String> { + self.impersonator_user_id.as_ref() + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_user_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.registration(); + let _ = _model.status(); + let _ = _model.labels(); + let _ = _model.password_update(); + let _ = _model.email(); + let _ = _model.phone(); + let _ = _model.email_verification(); + let _ = _model.phone_verification(); + let _ = _model.mfa(); + let _ = _model.prefs(); + let _ = _model.targets(); + let _ = _model.accessed_at(); + } + + #[test] + fn test_user_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/user_list.rs b/src/models/user_list.rs new file mode 100644 index 0000000..5a39f8f --- /dev/null +++ b/src/models/user_list.rs @@ -0,0 +1,50 @@ +//! UserList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Users List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct UserList { + /// Total number of users that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of users. + #[serde(rename = "users")] + pub users: Vec, +} + +impl UserList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get users + pub fn users(&self) -> &Vec { + &self.users + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_user_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.users(); + } + + #[test] + fn test_user_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/variable.rs b/src/models/variable.rs new file mode 100644 index 0000000..3bd1f7d --- /dev/null +++ b/src/models/variable.rs @@ -0,0 +1,107 @@ +//! Variable model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Variable +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Variable { + /// Variable ID. + #[serde(rename = "$id")] + pub id: String, + /// Variable creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Variable creation date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Variable key. + #[serde(rename = "key")] + pub key: String, + /// Variable value. + #[serde(rename = "value")] + pub value: String, + /// Variable secret flag. Secret variables can only be updated or deleted, but + /// never read. + #[serde(rename = "secret")] + pub secret: bool, + /// Service to which the variable belongs. Possible values are "project", + /// "function" + #[serde(rename = "resourceType")] + pub resource_type: String, + /// ID of resource to which the variable belongs. If resourceType is "project", + /// it is empty. If resourceType is "function", it is ID of the function. + #[serde(rename = "resourceId")] + pub resource_id: String, +} + +impl Variable { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get key + pub fn key(&self) -> &String { + &self.key + } + + /// Get value + pub fn value(&self) -> &String { + &self.value + } + + /// Get secret + pub fn secret(&self) -> &bool { + &self.secret + } + + /// Get resource_type + pub fn resource_type(&self) -> &String { + &self.resource_type + } + + /// Get resource_id + pub fn resource_id(&self) -> &String { + &self.resource_id + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_variable_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.key(); + let _ = _model.value(); + let _ = _model.secret(); + let _ = _model.resource_type(); + let _ = _model.resource_id(); + } + + #[test] + fn test_variable_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/variable_list.rs b/src/models/variable_list.rs new file mode 100644 index 0000000..e661976 --- /dev/null +++ b/src/models/variable_list.rs @@ -0,0 +1,50 @@ +//! VariableList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Variables List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct VariableList { + /// Total number of variables that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of variables. + #[serde(rename = "variables")] + pub variables: Vec, +} + +impl VariableList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get variables + pub fn variables(&self) -> &Vec { + &self.variables + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_variable_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.variables(); + } + + #[test] + fn test_variable_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/webhook.rs b/src/models/webhook.rs new file mode 100644 index 0000000..f78a7c4 --- /dev/null +++ b/src/models/webhook.rs @@ -0,0 +1,149 @@ +//! Webhook model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Webhook +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct Webhook { + /// Webhook ID. + #[serde(rename = "$id")] + pub id: String, + /// Webhook creation date in ISO 8601 format. + #[serde(rename = "$createdAt")] + pub created_at: String, + /// Webhook update date in ISO 8601 format. + #[serde(rename = "$updatedAt")] + pub updated_at: String, + /// Webhook name. + #[serde(rename = "name")] + pub name: String, + /// Webhook URL endpoint. + #[serde(rename = "url")] + pub url: String, + /// Webhook trigger events. + #[serde(rename = "events")] + pub events: Vec, + /// Indicated if SSL / TLS Certificate verification is enabled. + #[serde(rename = "security")] + pub security: bool, + /// HTTP basic authentication username. + #[serde(rename = "httpUser")] + pub http_user: String, + /// HTTP basic authentication password. + #[serde(rename = "httpPass")] + pub http_pass: String, + /// Signature key which can be used to validated incoming + #[serde(rename = "signatureKey")] + pub signature_key: String, + /// Indicates if this webhook is enabled. + #[serde(rename = "enabled")] + pub enabled: bool, + /// Webhook error logs from the most recent failure. + #[serde(rename = "logs")] + pub logs: String, + /// Number of consecutive failed webhook attempts. + #[serde(rename = "attempts")] + pub attempts: i64, +} + +impl Webhook { + /// Get id + pub fn id(&self) -> &String { + &self.id + } + + /// Get created_at + pub fn created_at(&self) -> &String { + &self.created_at + } + + /// Get updated_at + pub fn updated_at(&self) -> &String { + &self.updated_at + } + + /// Get name + pub fn name(&self) -> &String { + &self.name + } + + /// Get url + pub fn url(&self) -> &String { + &self.url + } + + /// Get events + pub fn events(&self) -> &Vec { + &self.events + } + + /// Get security + pub fn security(&self) -> &bool { + &self.security + } + + /// Get http_user + pub fn http_user(&self) -> &String { + &self.http_user + } + + /// Get http_pass + pub fn http_pass(&self) -> &String { + &self.http_pass + } + + /// Get signature_key + pub fn signature_key(&self) -> &String { + &self.signature_key + } + + /// Get enabled + pub fn enabled(&self) -> &bool { + &self.enabled + } + + /// Get logs + pub fn logs(&self) -> &String { + &self.logs + } + + /// Get attempts + pub fn attempts(&self) -> &i64 { + &self.attempts + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_webhook_creation() { + let _model = ::default(); + let _ = _model.id(); + let _ = _model.created_at(); + let _ = _model.updated_at(); + let _ = _model.name(); + let _ = _model.url(); + let _ = _model.events(); + let _ = _model.security(); + let _ = _model.http_user(); + let _ = _model.http_pass(); + let _ = _model.signature_key(); + let _ = _model.enabled(); + let _ = _model.logs(); + let _ = _model.attempts(); + } + + #[test] + fn test_webhook_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/models/webhook_list.rs b/src/models/webhook_list.rs new file mode 100644 index 0000000..7437c37 --- /dev/null +++ b/src/models/webhook_list.rs @@ -0,0 +1,50 @@ +//! WebhookList model for Appwrite SDK + +use serde::{Deserialize, Serialize}; + +/// Webhooks List +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(test, derive(Default))] +pub struct WebhookList { + /// Total number of webhooks that matched your query. + #[serde(rename = "total")] + pub total: i64, + /// List of webhooks. + #[serde(rename = "webhooks")] + pub webhooks: Vec, +} + +impl WebhookList { + /// Get total + pub fn total(&self) -> &i64 { + &self.total + } + + /// Get webhooks + pub fn webhooks(&self) -> &Vec { + &self.webhooks + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_webhook_list_creation() { + let _model = ::default(); + let _ = _model.total(); + let _ = _model.webhooks(); + } + + #[test] + fn test_webhook_list_serialization() { + let model = ::default(); + let json = serde_json::to_string(&model); + assert!(json.is_ok()); + + let deserialized: Result = serde_json::from_str(&json.unwrap()); + assert!(deserialized.is_ok()); + } +} diff --git a/src/operator.rs b/src/operator.rs new file mode 100644 index 0000000..263c3ba --- /dev/null +++ b/src/operator.rs @@ -0,0 +1,396 @@ +use serde::Serialize; +use serde_json::Value; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Condition { + Equal, + NotEqual, + GreaterThan, + GreaterThanEqual, + LessThan, + LessThanEqual, + Contains, + IsNull, + IsNotNull, +} + +impl Condition { + pub fn as_str(&self) -> &'static str { + match self { + Condition::Equal => "equal", + Condition::NotEqual => "notEqual", + Condition::GreaterThan => "greaterThan", + Condition::GreaterThanEqual => "greaterThanEqual", + Condition::LessThan => "lessThan", + Condition::LessThanEqual => "lessThanEqual", + Condition::Contains => "contains", + Condition::IsNull => "isNull", + Condition::IsNotNull => "isNotNull", + } + } +} + +#[derive(Debug, Serialize)] +struct OperatorData { + method: String, + values: Vec, +} + +fn parse_operator(method: &str, values: Vec) -> String { + let data = OperatorData { + method: method.to_string(), + values, + }; + serde_json::to_string(&data).expect("Failed to serialize operator data") +} + +fn validate_numeric(value: &Value, param_name: &str) { + if !value.is_number() { + panic!("{} must be a number", param_name); + } + if let Some(num) = value.as_f64() { + if num.is_nan() || num.is_infinite() { + panic!("{} cannot be NaN or Infinity", param_name); + } + } +} + +fn validate_nonzero_divisor(value: &Value, param_name: &str) { + validate_numeric(value, param_name); + + if let Some(num) = value.as_f64() { + if num == 0.0 { + panic!("{} cannot be zero", param_name); + } + } else if let Some(num) = value.as_i64() { + if num == 0 { + panic!("{} cannot be zero", param_name); + } + } +} + +pub fn increment() -> String { + parse_operator("increment", vec![Value::from(1)]) +} + +pub fn increment_by>(value: T) -> String { + let val = value.into(); + validate_numeric(&val, "value"); + parse_operator("increment", vec![val]) +} + +pub fn increment_with_max, M: Into>(value: T, max: M) -> String { + let val = value.into(); + let max_val = max.into(); + validate_numeric(&val, "value"); + validate_numeric(&max_val, "max"); + parse_operator("increment", vec![val, max_val]) +} + +pub fn decrement() -> String { + parse_operator("decrement", vec![Value::from(1)]) +} + +pub fn decrement_by>(value: T) -> String { + let val = value.into(); + validate_numeric(&val, "value"); + parse_operator("decrement", vec![val]) +} + +pub fn decrement_with_min, M: Into>(value: T, min: M) -> String { + let val = value.into(); + let min_val = min.into(); + validate_numeric(&val, "value"); + validate_numeric(&min_val, "min"); + parse_operator("decrement", vec![val, min_val]) +} + +pub fn multiply>(factor: T) -> String { + let val = factor.into(); + validate_numeric(&val, "factor"); + parse_operator("multiply", vec![val]) +} + +pub fn multiply_with_max, M: Into>(factor: T, max: M) -> String { + let val = factor.into(); + let max_val = max.into(); + validate_numeric(&val, "factor"); + validate_numeric(&max_val, "max"); + parse_operator("multiply", vec![val, max_val]) +} + +pub fn divide>(divisor: T) -> String { + let val = divisor.into(); + validate_nonzero_divisor(&val, "divisor"); + parse_operator("divide", vec![val]) +} + +pub fn divide_with_min, M: Into>(divisor: T, min: M) -> String { + let val = divisor.into(); + let min_val = min.into(); + validate_nonzero_divisor(&val, "divisor"); + validate_numeric(&min_val, "min"); + parse_operator("divide", vec![val, min_val]) +} + +pub fn modulo>(divisor: T) -> String { + let val = divisor.into(); + validate_nonzero_divisor(&val, "divisor"); + parse_operator("modulo", vec![val]) +} + +pub fn power>(exponent: T) -> String { + let val = exponent.into(); + validate_numeric(&val, "exponent"); + parse_operator("power", vec![val]) +} + +pub fn power_with_max, M: Into>(exponent: T, max: M) -> String { + let val = exponent.into(); + let max_val = max.into(); + validate_numeric(&val, "exponent"); + validate_numeric(&max_val, "max"); + parse_operator("power", vec![val, max_val]) +} + +pub fn array_append(values: &[T]) -> String { + let vals: Vec = values + .iter() + .map(|v| serde_json::to_value(v).expect("Failed to serialize value")) + .collect(); + parse_operator("arrayAppend", vals) +} + +pub fn array_prepend(values: &[T]) -> String { + let vals: Vec = values + .iter() + .map(|v| serde_json::to_value(v).expect("Failed to serialize value")) + .collect(); + parse_operator("arrayPrepend", vals) +} + +pub fn array_insert>(index: i64, value: T) -> String { + parse_operator("arrayInsert", vec![Value::from(index), value.into()]) +} + +pub fn array_remove>(value: T) -> String { + parse_operator("arrayRemove", vec![value.into()]) +} + +pub fn array_unique() -> String { + parse_operator("arrayUnique", vec![]) +} + +pub fn array_intersect(values: &[T]) -> String { + let vals: Vec = values + .iter() + .map(|v| serde_json::to_value(v).expect("Failed to serialize value")) + .collect(); + parse_operator("arrayIntersect", vals) +} + +pub fn array_diff(values: &[T]) -> String { + let vals: Vec = values + .iter() + .map(|v| serde_json::to_value(v).expect("Failed to serialize value")) + .collect(); + parse_operator("arrayDiff", vals) +} + +pub fn array_filter(condition: Condition) -> String { + parse_operator( + "arrayFilter", + vec![Value::from(condition.as_str()), Value::Null], + ) +} + +pub fn array_filter_with_value>(condition: Condition, value: T) -> String { + parse_operator( + "arrayFilter", + vec![Value::from(condition.as_str()), value.into()], + ) +} + +pub fn string_concat>(value: S) -> String { + parse_operator("stringConcat", vec![Value::from(value.into())]) +} + +pub fn string_replace>(search: S, replace: S) -> String { + parse_operator( + "stringReplace", + vec![Value::from(search.into()), Value::from(replace.into())], + ) +} + +pub fn toggle() -> String { + parse_operator("toggle", vec![]) +} + +pub fn date_add_days(days: i64) -> String { + parse_operator("dateAddDays", vec![Value::from(days)]) +} + +pub fn date_sub_days(days: i64) -> String { + parse_operator("dateSubDays", vec![Value::from(days)]) +} + +pub fn date_set_now() -> String { + parse_operator("dateSetNow", vec![]) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_increment() { + assert_eq!(increment(), r#"{"method":"increment","values":[1]}"#); + } + + #[test] + fn test_increment_by() { + assert_eq!(increment_by(5), r#"{"method":"increment","values":[5]}"#); + } + + #[test] + fn test_increment_with_max() { + assert_eq!(increment_with_max(5, 100), r#"{"method":"increment","values":[5,100]}"#); + } + + #[test] + fn test_decrement() { + assert_eq!(decrement(), r#"{"method":"decrement","values":[1]}"#); + } + + #[test] + fn test_decrement_by() { + assert_eq!(decrement_by(3), r#"{"method":"decrement","values":[3]}"#); + } + + #[test] + fn test_decrement_with_min() { + assert_eq!(decrement_with_min(3, 0), r#"{"method":"decrement","values":[3,0]}"#); + } + + #[test] + fn test_multiply() { + assert_eq!(multiply(2), r#"{"method":"multiply","values":[2]}"#); + } + + #[test] + fn test_multiply_with_max() { + assert_eq!(multiply_with_max(3, 1000), r#"{"method":"multiply","values":[3,1000]}"#); + } + + #[test] + fn test_divide() { + assert_eq!(divide(2), r#"{"method":"divide","values":[2]}"#); + } + + #[test] + fn test_divide_with_min() { + assert_eq!(divide_with_min(4, 1), r#"{"method":"divide","values":[4,1]}"#); + } + + #[test] + fn test_modulo() { + assert_eq!(modulo(5), r#"{"method":"modulo","values":[5]}"#); + } + + #[test] + fn test_power() { + assert_eq!(power(2), r#"{"method":"power","values":[2]}"#); + } + + #[test] + fn test_power_with_max() { + assert_eq!(power_with_max(3, 100), r#"{"method":"power","values":[3,100]}"#); + } + + #[test] + fn test_array_append() { + assert_eq!(array_append(&["item1", "item2"]), r#"{"method":"arrayAppend","values":["item1","item2"]}"#); + } + + #[test] + fn test_array_prepend() { + assert_eq!(array_prepend(&["first", "second"]), r#"{"method":"arrayPrepend","values":["first","second"]}"#); + } + + #[test] + fn test_array_insert() { + assert_eq!(array_insert(0, "newItem"), r#"{"method":"arrayInsert","values":[0,"newItem"]}"#); + } + + #[test] + fn test_array_remove() { + assert_eq!(array_remove("oldItem"), r#"{"method":"arrayRemove","values":["oldItem"]}"#); + } + + #[test] + fn test_array_unique() { + assert_eq!(array_unique(), r#"{"method":"arrayUnique","values":[]}"#); + } + + #[test] + fn test_array_intersect() { + assert_eq!(array_intersect(&["a", "b", "c"]), r#"{"method":"arrayIntersect","values":["a","b","c"]}"#); + } + + #[test] + fn test_array_diff() { + assert_eq!(array_diff(&["x", "y"]), r#"{"method":"arrayDiff","values":["x","y"]}"#); + } + + #[test] + fn test_array_filter() { + assert_eq!(array_filter(Condition::Equal), r#"{"method":"arrayFilter","values":["equal",null]}"#); + } + + #[test] + fn test_array_filter_with_value() { + assert_eq!(array_filter_with_value(Condition::Equal, "test"), r#"{"method":"arrayFilter","values":["equal","test"]}"#); + } + + #[test] + fn test_string_concat() { + assert_eq!(string_concat("suffix"), r#"{"method":"stringConcat","values":["suffix"]}"#); + } + + #[test] + fn test_string_replace() { + assert_eq!(string_replace("old", "new"), r#"{"method":"stringReplace","values":["old","new"]}"#); + } + + #[test] + fn test_toggle() { + assert_eq!(toggle(), r#"{"method":"toggle","values":[]}"#); + } + + #[test] + fn test_date_add_days() { + assert_eq!(date_add_days(7), r#"{"method":"dateAddDays","values":[7]}"#); + } + + #[test] + fn test_date_sub_days() { + assert_eq!(date_sub_days(3), r#"{"method":"dateSubDays","values":[3]}"#); + } + + #[test] + fn test_date_set_now() { + assert_eq!(date_set_now(), r#"{"method":"dateSetNow","values":[]}"#); + } + + #[test] + #[should_panic(expected = "divisor cannot be zero")] + fn test_divide_zero() { + divide(0); + } + + #[test] + #[should_panic(expected = "divisor cannot be zero")] + fn test_modulo_zero() { + modulo(0); + } +} diff --git a/src/permission.rs b/src/permission.rs new file mode 100644 index 0000000..0f42a89 --- /dev/null +++ b/src/permission.rs @@ -0,0 +1,91 @@ +//! Permission handling for Appwrite SDK + +/// Permission builder for Appwrite resources +#[derive(Debug, Clone)] +pub struct Permission { + permission: String, +} + +impl Permission { + /// Create a new permission + fn new(permission: String) -> Self { + Self { permission } + } + + /// Read permission for the specified role + pub fn read(role: impl std::fmt::Display) -> Self { + Self::new(format!("read(\"{}\")", role)) + } + + /// Write permission for the specified role + pub fn write(role: impl std::fmt::Display) -> Self { + Self::new(format!("write(\"{}\")", role)) + } + + /// Create permission for the specified role + pub fn create(role: impl std::fmt::Display) -> Self { + Self::new(format!("create(\"{}\")", role)) + } + + /// Update permission for the specified role + pub fn update(role: impl std::fmt::Display) -> Self { + Self::new(format!("update(\"{}\")", role)) + } + + /// Delete permission for the specified role + pub fn delete(role: impl std::fmt::Display) -> Self { + Self::new(format!("delete(\"{}\")", role)) + } + + /// Get the permission string + pub fn value(&self) -> &str { + &self.permission + } +} + +impl std::fmt::Display for Permission { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.permission) + } +} + +impl From for String { + fn from(permission: Permission) -> Self { + permission.permission + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_read_permission() { + let permission = Permission::read("any"); + assert_eq!(permission.to_string(), "read(\"any\")"); + } + + #[test] + fn test_write_permission() { + let permission = Permission::write("users"); + assert_eq!(permission.to_string(), "write(\"users\")"); + } + + #[test] + fn test_create_permission() { + let permission = Permission::create("team:developers"); + assert_eq!(permission.to_string(), "create(\"team:developers\")"); + } + + #[test] + fn test_update_permission() { + let permission = Permission::update("user:123"); + assert_eq!(permission.to_string(), "update(\"user:123\")"); + } + + #[test] + fn test_delete_permission() { + let permission = Permission::delete("admin"); + assert_eq!(permission.to_string(), "delete(\"admin\")"); + } +} diff --git a/src/query.rs b/src/query.rs new file mode 100644 index 0000000..d9d2a29 --- /dev/null +++ b/src/query.rs @@ -0,0 +1,846 @@ +//! Query builder for Appwrite SDK + +use serde::Serialize; +use serde_json::Value; + +/// Query builder for filtering and sorting database queries +#[derive(Debug, Clone, Serialize)] +pub struct Query { + method: String, + #[serde(skip_serializing_if = "Option::is_none")] + attribute: Option, + #[serde(skip_serializing_if = "Vec::is_empty")] + values: Vec, +} + +impl Query { + fn new(method: String, attribute: Option, values: Vec) -> Self { + Self { + method, + attribute, + values, + } + } + + fn to_array(value: Value) -> Vec { + match value { + Value::Array(arr) => arr, + _ => vec![value], + } + } + + pub fn equal, V: Into>(attribute: S, value: V) -> Self { + Self::new("equal".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn not_equal, V: Into>(attribute: S, value: V) -> Self { + Self::new("notEqual".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn less_than, V: Into>(attribute: S, value: V) -> Self { + Self::new("lessThan".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn less_than_equal, V: Into>(attribute: S, value: V) -> Self { + Self::new("lessThanEqual".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn greater_than, V: Into>(attribute: S, value: V) -> Self { + Self::new("greaterThan".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn greater_than_equal, V: Into>(attribute: S, value: V) -> Self { + Self::new("greaterThanEqual".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn is_null>(attribute: S) -> Self { + Self::new("isNull".to_string(), Some(attribute.into()), vec![]) + } + + pub fn is_not_null>(attribute: S) -> Self { + Self::new("isNotNull".to_string(), Some(attribute.into()), vec![]) + } + + pub fn between, V: Into>(attribute: S, start: V, end: V) -> Self { + Self::new("between".to_string(), Some(attribute.into()), vec![start.into(), end.into()]) + } + + pub fn starts_with, V: Into>(attribute: S, value: V) -> Self { + Self::new("startsWith".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn ends_with, V: Into>(attribute: S, value: V) -> Self { + Self::new("endsWith".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn select, S: Into>(attributes: I) -> Self { + let values: Vec = attributes.into_iter().map(|s| Value::String(s.into())).collect(); + Self::new("select".to_string(), None, values) + } + + pub fn search, V: Into>(attribute: S, value: V) -> Self { + Self::new("search".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn not_search, V: Into>(attribute: S, value: V) -> Self { + Self::new("notSearch".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn order_asc>(attribute: S) -> Self { + Self::new("orderAsc".to_string(), Some(attribute.into()), vec![]) + } + + pub fn order_desc>(attribute: S) -> Self { + Self::new("orderDesc".to_string(), Some(attribute.into()), vec![]) + } + + pub fn order_random() -> Self { + Self::new("orderRandom".to_string(), None, vec![]) + } + + pub fn cursor_after>(document_id: S) -> Self { + Self::new("cursorAfter".to_string(), None, vec![Value::String(document_id.into())]) + } + + pub fn cursor_before>(document_id: S) -> Self { + Self::new("cursorBefore".to_string(), None, vec![Value::String(document_id.into())]) + } + + pub fn limit(value: u32) -> Self { + Self::new("limit".to_string(), None, vec![Value::Number(value.into())]) + } + + pub fn offset(value: u32) -> Self { + Self::new("offset".to_string(), None, vec![Value::Number(value.into())]) + } + + pub fn contains, V: Into>(attribute: S, value: V) -> Self { + Self::new("contains".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn contains_any, V: Into>(attribute: S, values: Vec) -> Self { + Self::new("containsAny".to_string(), Some(attribute.into()), values.into_iter().map(|v| v.into()).collect()) + } + + pub fn contains_all, V: Into>(attribute: S, values: Vec) -> Self { + Self::new("containsAll".to_string(), Some(attribute.into()), values.into_iter().map(|v| v.into()).collect()) + } + + pub fn not_contains, V: Into>(attribute: S, value: V) -> Self { + Self::new("notContains".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn not_between, V: Into>(attribute: S, start: V, end: V) -> Self { + Self::new("notBetween".to_string(), Some(attribute.into()), vec![start.into(), end.into()]) + } + + pub fn not_starts_with, V: Into>(attribute: S, value: V) -> Self { + Self::new("notStartsWith".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn not_ends_with, V: Into>(attribute: S, value: V) -> Self { + Self::new("notEndsWith".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn created_before>(value: V) -> Self { + Self::less_than("$createdAt", value) + } + + pub fn created_after>(value: V) -> Self { + Self::greater_than("$createdAt", value) + } + + pub fn created_between>(start: V, end: V) -> Self { + Self::between("$createdAt", start, end) + } + + pub fn updated_before>(value: V) -> Self { + Self::less_than("$updatedAt", value) + } + + pub fn updated_after>(value: V) -> Self { + Self::greater_than("$updatedAt", value) + } + + pub fn updated_between>(start: V, end: V) -> Self { + Self::between("$updatedAt", start, end) + } + + pub fn distance_equal, V: Into>(attribute: S, values: V, distance: impl Into, meters: bool) -> Self { + let params = Value::Array(vec![values.into(), distance.into(), Value::Bool(meters)]); + Self::new("distanceEqual".to_string(), Some(attribute.into()), vec![params]) + } + + pub fn distance_not_equal, V: Into>(attribute: S, values: V, distance: impl Into, meters: bool) -> Self { + let params = Value::Array(vec![values.into(), distance.into(), Value::Bool(meters)]); + Self::new("distanceNotEqual".to_string(), Some(attribute.into()), vec![params]) + } + + pub fn distance_greater_than, V: Into>(attribute: S, values: V, distance: impl Into, meters: bool) -> Self { + let params = Value::Array(vec![values.into(), distance.into(), Value::Bool(meters)]); + Self::new("distanceGreaterThan".to_string(), Some(attribute.into()), vec![params]) + } + + pub fn distance_less_than, V: Into>(attribute: S, values: V, distance: impl Into, meters: bool) -> Self { + let params = Value::Array(vec![values.into(), distance.into(), Value::Bool(meters)]); + Self::new("distanceLessThan".to_string(), Some(attribute.into()), vec![params]) + } + + pub fn intersects, V: Into>(attribute: S, values: V) -> Self { + Self::new("intersects".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn not_intersects, V: Into>(attribute: S, values: V) -> Self { + Self::new("notIntersects".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn crosses, V: Into>(attribute: S, values: V) -> Self { + Self::new("crosses".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn not_crosses, V: Into>(attribute: S, values: V) -> Self { + Self::new("notCrosses".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn overlaps, V: Into>(attribute: S, values: V) -> Self { + Self::new("overlaps".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn not_overlaps, V: Into>(attribute: S, values: V) -> Self { + Self::new("notOverlaps".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn touches, V: Into>(attribute: S, values: V) -> Self { + Self::new("touches".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn not_touches, V: Into>(attribute: S, values: V) -> Self { + Self::new("notTouches".to_string(), Some(attribute.into()), vec![values.into()]) + } + + pub fn or(queries: I) -> Self + where + I: IntoIterator, + S: AsRef, + { + let values: Vec = queries + .into_iter() + .filter_map(|query| serde_json::from_str(query.as_ref()).ok()) + .collect(); + Self::new("or".to_string(), None, values) + } + + pub fn and(queries: I) -> Self + where + I: IntoIterator, + S: AsRef, + { + let values: Vec = queries + .into_iter() + .filter_map(|query| serde_json::from_str(query.as_ref()).ok()) + .collect(); + Self::new("and".to_string(), None, values) + } + + pub fn regex, V: Into>(attribute: S, value: V) -> Self { + Self::new("regex".to_string(), Some(attribute.into()), Self::to_array(value.into())) + } + + pub fn exists>(attributes: Vec) -> Self { + Self::new("exists".to_string(), None, attributes.into_iter().map(|v| v.into()).collect()) + } + + pub fn not_exists>(attributes: Vec) -> Self { + Self::new("notExists".to_string(), None, attributes.into_iter().map(|v| v.into()).collect()) + } + + pub fn elem_match(attribute: S, queries: I) -> Self + where + S: Into, + I: IntoIterator, + Q: AsRef, + { + let values: Vec = queries + .into_iter() + .filter_map(|query| serde_json::from_str(query.as_ref()).ok()) + .collect(); + Self::new("elemMatch".to_string(), Some(attribute.into()), values) + } + + /// Convert query to JSON value (matches Go/Python SDK format) + pub fn to_value(self) -> Value { + let mut obj = serde_json::Map::new(); + obj.insert("method".to_string(), Value::String(self.method)); + + if let Some(attr) = self.attribute { + obj.insert("attribute".to_string(), Value::String(attr)); + } + + if !self.values.is_empty() { + obj.insert("values".to_string(), Value::Array(self.values)); + } + + Value::Object(obj) + } +} + +impl std::fmt::Display for Query { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let json_str = serde_json::to_string(self) + .unwrap_or_else(|_| String::new()); + write!(f, "{}", json_str) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_equal_query() { + let query = Query::equal("name", "John"); + let value = query.to_value(); + assert_eq!(value["method"], "equal"); + assert_eq!(value["attribute"], "name"); + assert_eq!(value["values"][0], "John"); + } + + #[test] + fn test_greater_than_query() { + let query = Query::greater_than("age", 18); + let value = query.to_value(); + assert_eq!(value["method"], "greaterThan"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 18); + } + + #[test] + fn test_between_query() { + let query = Query::between("age", 18, 65); + let value = query.to_value(); + assert_eq!(value["method"], "between"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 18); + assert_eq!(value["values"][1], 65); + } + + #[test] + fn test_select_query() { + let query = Query::select(vec!["name", "age"]); + let value = query.to_value(); + assert_eq!(value["method"], "select"); + assert_eq!(value["values"][0], "name"); + assert_eq!(value["values"][1], "age"); + } + + #[test] + fn test_order_asc_query() { + let query = Query::order_asc("name"); + let value = query.to_value(); + assert_eq!(value["method"], "orderAsc"); + assert_eq!(value["attribute"], "name"); + } + + #[test] + fn test_limit_query() { + let query = Query::limit(10); + let value = query.to_value(); + assert_eq!(value["method"], "limit"); + assert_eq!(value["values"][0], 10); + } + + #[test] + fn test_or_query() { + let query_strings = vec![ + Query::equal("released", true).to_string(), + Query::less_than("releasedYear", 1990).to_string(), + ]; + let query = Query::or(query_strings); + let value = query.to_value(); + assert_eq!(value["method"], "or"); + assert!(value["values"].is_array()); + assert_eq!(value["values"].as_array().unwrap().len(), 2); + } + + #[test] + fn test_and_query() { + let query_strings = vec![ + Query::equal("released", false).to_string(), + Query::greater_than("releasedYear", 2015).to_string(), + ]; + let query = Query::and(query_strings); + let value = query.to_value(); + assert_eq!(value["method"], "and"); + assert!(value["values"].is_array()); + assert_eq!(value["values"].as_array().unwrap().len(), 2); + } + + #[test] + fn test_or_invalid_json_skipped() { + let mixed_queries = vec![ + Query::equal("released", true).to_string(), + "not valid json".to_string(), + Query::less_than("releasedYear", 1990).to_string(), + ]; + let query = Query::or(mixed_queries); + let value = query.to_value(); + assert_eq!(value["method"], "or"); + assert_eq!(value["values"].as_array().unwrap().len(), 2); + } + + #[test] + fn test_and_invalid_json_skipped() { + let mixed_queries = vec![ + "not valid json".to_string(), + Query::greater_than("releasedYear", 2015).to_string(), + ]; + let query = Query::and(mixed_queries); + let value = query.to_value(); + assert_eq!(value["method"], "and"); + assert_eq!(value["values"].as_array().unwrap().len(), 1); + } + + #[test] + fn test_json_serialization() { + let query = Query::equal("name", "John"); + let json_str = query.to_string(); + let parsed: Value = serde_json::from_str(&json_str).unwrap(); + assert_eq!(parsed["method"], "equal"); + assert_eq!(parsed["attribute"], "name"); + assert_eq!(parsed["values"][0], "John"); + } + + #[test] + fn test_equal_with_array() { + let arr = vec!["Movie1", "Movie2"]; + let query = Query::equal("title", Value::Array(arr.iter().map(|s| Value::String(s.to_string())).collect())); + let value = query.to_value(); + assert_eq!(value["method"], "equal"); + assert_eq!(value["attribute"], "title"); + assert_eq!(value["values"].as_array().unwrap().len(), 2); + assert_eq!(value["values"][0], "Movie1"); + assert_eq!(value["values"][1], "Movie2"); + } + + #[test] + fn test_not_equal() { + let query = Query::not_equal("status", "draft"); + let value = query.to_value(); + assert_eq!(value["method"], "notEqual"); + assert_eq!(value["attribute"], "status"); + assert_eq!(value["values"][0], "draft"); + } + + #[test] + fn test_less_than() { + let query = Query::less_than("age", 18); + let value = query.to_value(); + assert_eq!(value["method"], "lessThan"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 18); + } + + #[test] + fn test_less_than_equal() { + let query = Query::less_than_equal("score", 100); + let value = query.to_value(); + assert_eq!(value["method"], "lessThanEqual"); + assert_eq!(value["attribute"], "score"); + assert_eq!(value["values"][0], 100); + } + + #[test] + fn test_greater_than_equal() { + let query = Query::greater_than_equal("age", 21); + let value = query.to_value(); + assert_eq!(value["method"], "greaterThanEqual"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 21); + } + + #[test] + fn test_search() { + let query = Query::search("content", "keyword1 keyword2"); + let value = query.to_value(); + assert_eq!(value["method"], "search"); + assert_eq!(value["attribute"], "content"); + assert_eq!(value["values"][0], "keyword1 keyword2"); + } + + #[test] + fn test_search_with_number() { + let query = Query::search("age", 42); + let value = query.to_value(); + assert_eq!(value["method"], "search"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 42); + } + + #[test] + fn test_is_null() { + let query = Query::is_null("deletedAt"); + let value = query.to_value(); + assert_eq!(value["method"], "isNull"); + assert_eq!(value["attribute"], "deletedAt"); + } + + #[test] + fn test_is_not_null() { + let query = Query::is_not_null("publishedAt"); + let value = query.to_value(); + assert_eq!(value["method"], "isNotNull"); + assert_eq!(value["attribute"], "publishedAt"); + } + + #[test] + fn test_contains() { + let query = Query::contains("tags", "rust"); + let value = query.to_value(); + assert_eq!(value["method"], "contains"); + assert_eq!(value["attribute"], "tags"); + assert_eq!(value["values"][0], "rust"); + } + + #[test] + fn test_not_contains() { + let query = Query::not_contains("tags", "rust"); + let value = query.to_value(); + assert_eq!(value["method"], "notContains"); + assert_eq!(value["attribute"], "tags"); + assert_eq!(value["values"][0], "rust"); + } + + #[test] + fn test_not_search_with_number() { + let query = Query::not_search("age", 7); + let value = query.to_value(); + assert_eq!(value["method"], "notSearch"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 7); + } + + #[test] + fn test_not_search_with_array() { + let values = Value::Array(vec![Value::from("x"), Value::from("y")]); + let query = Query::not_search("tags", values); + let value = query.to_value(); + assert_eq!(value["method"], "notSearch"); + assert_eq!(value["attribute"], "tags"); + assert_eq!(value["values"][0], "x"); + assert_eq!(value["values"][1], "y"); + } + + #[test] + fn test_starts_with() { + let query = Query::starts_with("name", "John"); + let value = query.to_value(); + assert_eq!(value["method"], "startsWith"); + assert_eq!(value["attribute"], "name"); + assert_eq!(value["values"][0], "John"); + } + + #[test] + fn test_starts_with_with_bool() { + let query = Query::starts_with("active", true); + let value = query.to_value(); + assert_eq!(value["method"], "startsWith"); + assert_eq!(value["attribute"], "active"); + assert_eq!(value["values"][0], true); + } + + #[test] + fn test_not_starts_with_with_bool() { + let query = Query::not_starts_with("active", false); + let value = query.to_value(); + assert_eq!(value["method"], "notStartsWith"); + assert_eq!(value["attribute"], "active"); + assert_eq!(value["values"][0], false); + } + + #[test] + fn test_ends_with() { + let query = Query::ends_with("email", "@example.com"); + let value = query.to_value(); + assert_eq!(value["method"], "endsWith"); + assert_eq!(value["attribute"], "email"); + assert_eq!(value["values"][0], "@example.com"); + } + + #[test] + fn test_ends_with_with_array() { + let values = Value::Array(vec![Value::from("a"), Value::from("b")]); + let query = Query::ends_with("tags", values); + let value = query.to_value(); + assert_eq!(value["method"], "endsWith"); + assert_eq!(value["attribute"], "tags"); + assert_eq!(value["values"][0], "a"); + assert_eq!(value["values"][1], "b"); + } + + #[test] + fn test_not_ends_with_with_array() { + let values = Value::Array(vec![Value::from("x"), Value::from("y")]); + let query = Query::not_ends_with("tags", values); + let value = query.to_value(); + assert_eq!(value["method"], "notEndsWith"); + assert_eq!(value["attribute"], "tags"); + assert_eq!(value["values"][0], "x"); + assert_eq!(value["values"][1], "y"); + } + + #[test] + fn test_order_desc() { + let query = Query::order_desc("createdAt"); + let value = query.to_value(); + assert_eq!(value["method"], "orderDesc"); + assert_eq!(value["attribute"], "createdAt"); + } + + #[test] + fn test_order_random() { + let query = Query::order_random(); + let value = query.to_value(); + assert_eq!(value["method"], "orderRandom"); + } + + #[test] + fn test_cursor_before() { + let query = Query::cursor_before("doc123"); + let value = query.to_value(); + assert_eq!(value["method"], "cursorBefore"); + assert_eq!(value["values"][0], "doc123"); + } + + #[test] + fn test_cursor_after() { + let query = Query::cursor_after("doc456"); + let value = query.to_value(); + assert_eq!(value["method"], "cursorAfter"); + assert_eq!(value["values"][0], "doc456"); + } + + #[test] + fn test_offset() { + let query = Query::offset(50); + let value = query.to_value(); + assert_eq!(value["method"], "offset"); + assert_eq!(value["values"][0], 50); + } + + #[test] + fn test_distance_equal() { + let query = Query::distance_equal("location", Value::Array(vec![Value::from(40.7128), Value::from(-74.0060)]), 5000, true); + let value = query.to_value(); + assert_eq!(value["method"], "distanceEqual"); + assert_eq!(value["attribute"], "location"); + let params = value["values"][0].as_array().unwrap(); + assert_eq!(params[1], 5000); + assert_eq!(params[2], true); + } + + #[test] + fn test_distance_not_equal() { + let query = Query::distance_not_equal("location", Value::Array(vec![Value::from(40.7128), Value::from(-74.0060)]), 5000, false); + let value = query.to_value(); + assert_eq!(value["method"], "distanceNotEqual"); + assert_eq!(value["attribute"], "location"); + let params = value["values"][0].as_array().unwrap(); + assert_eq!(params[1], 5000); + assert_eq!(params[2], false); + } + + #[test] + fn test_distance_greater_than() { + let query = Query::distance_greater_than("location", Value::Array(vec![Value::from(1.0), Value::from(2.0)]), 123, true); + let value = query.to_value(); + assert_eq!(value["method"], "distanceGreaterThan"); + assert_eq!(value["attribute"], "location"); + let params = value["values"][0].as_array().unwrap(); + assert_eq!(params[1], 123); + assert_eq!(params[2], true); + } + + #[test] + fn test_distance_less_than() { + let query = Query::distance_less_than("location", Value::Array(vec![Value::from(1.0), Value::from(2.0)]), 321, false); + let value = query.to_value(); + assert_eq!(value["method"], "distanceLessThan"); + assert_eq!(value["attribute"], "location"); + let params = value["values"][0].as_array().unwrap(); + assert_eq!(params[1], 321); + assert_eq!(params[2], false); + } + + #[test] + fn test_intersects() { + let query = Query::intersects("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "intersects"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_not_intersects() { + let query = Query::not_intersects("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "notIntersects"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_crosses() { + let query = Query::crosses("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "crosses"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_not_crosses() { + let query = Query::not_crosses("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "notCrosses"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_overlaps() { + let query = Query::overlaps("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "overlaps"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_not_overlaps() { + let query = Query::not_overlaps("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "notOverlaps"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_touches() { + let query = Query::touches("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "touches"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_not_touches() { + let query = Query::not_touches("geo", Value::Array(vec![Value::from(1), Value::from(2)])); + let value = query.to_value(); + assert_eq!(value["method"], "notTouches"); + assert_eq!(value["attribute"], "geo"); + assert_eq!(value["values"][0][0], 1); + assert_eq!(value["values"][0][1], 2); + } + + #[test] + fn test_not_between() { + let query = Query::not_between("age", 18, 30); + let value = query.to_value(); + assert_eq!(value["method"], "notBetween"); + assert_eq!(value["attribute"], "age"); + assert_eq!(value["values"][0], 18); + assert_eq!(value["values"][1], 30); + } + + #[test] + fn test_not_starts_with() { + let query = Query::not_starts_with("name", "Ann"); + let value = query.to_value(); + assert_eq!(value["method"], "notStartsWith"); + assert_eq!(value["attribute"], "name"); + assert_eq!(value["values"][0], "Ann"); + } + + #[test] + fn test_not_ends_with() { + let query = Query::not_ends_with("name", "nne"); + let value = query.to_value(); + assert_eq!(value["method"], "notEndsWith"); + assert_eq!(value["attribute"], "name"); + assert_eq!(value["values"][0], "nne"); + } + + #[test] + fn test_created_before() { + let query = Query::created_before("2023-01-01"); + let value = query.to_value(); + assert_eq!(value["method"], "lessThan"); + assert_eq!(value["attribute"], "$createdAt"); + assert_eq!(value["values"][0], "2023-01-01"); + } + + #[test] + fn test_created_after() { + let query = Query::created_after("2023-01-01"); + let value = query.to_value(); + assert_eq!(value["method"], "greaterThan"); + assert_eq!(value["attribute"], "$createdAt"); + assert_eq!(value["values"][0], "2023-01-01"); + } + + #[test] + fn test_created_between() { + let query = Query::created_between("2023-01-01", "2023-12-31"); + let value = query.to_value(); + assert_eq!(value["method"], "between"); + assert_eq!(value["attribute"], "$createdAt"); + assert_eq!(value["values"][0], "2023-01-01"); + assert_eq!(value["values"][1], "2023-12-31"); + } + + #[test] + fn test_updated_before() { + let query = Query::updated_before("2023-01-01"); + let value = query.to_value(); + assert_eq!(value["method"], "lessThan"); + assert_eq!(value["attribute"], "$updatedAt"); + assert_eq!(value["values"][0], "2023-01-01"); + } + + #[test] + fn test_updated_after() { + let query = Query::updated_after("2023-01-01"); + let value = query.to_value(); + assert_eq!(value["method"], "greaterThan"); + assert_eq!(value["attribute"], "$updatedAt"); + assert_eq!(value["values"][0], "2023-01-01"); + } + + #[test] + fn test_updated_between() { + let query = Query::updated_between("2023-01-01", "2023-12-31"); + let value = query.to_value(); + assert_eq!(value["method"], "between"); + assert_eq!(value["attribute"], "$updatedAt"); + assert_eq!(value["values"][0], "2023-01-01"); + assert_eq!(value["values"][1], "2023-12-31"); + } + + #[test] + fn test_not_search() { + let query = Query::not_search("content", "spam keyword"); + let value = query.to_value(); + assert_eq!(value["method"], "notSearch"); + assert_eq!(value["attribute"], "content"); + assert_eq!(value["values"][0], "spam keyword"); + } +} diff --git a/src/role.rs b/src/role.rs new file mode 100644 index 0000000..b6495fe --- /dev/null +++ b/src/role.rs @@ -0,0 +1,155 @@ +//! Role handling for Appwrite SDK + +/// Role builder for Appwrite permissions +#[derive(Debug, Clone)] +pub struct Role { + role: String, +} + +impl Role { + /// Create a new role + fn new(role: String) -> Self { + Self { role } + } + + /// Any role + pub fn any() -> Self { + Self::new("any".to_string()) + } + + /// Users role (optionally filtered by status) + pub fn users(status: Option<&str>) -> Self { + if let Some(s) = status { + Self::new(format!("users/{}", s)) + } else { + Self::new("users".to_string()) + } + } + + /// Guests role + pub fn guests() -> Self { + Self::new("guests".to_string()) + } + + /// User role with specific user ID and optional status + pub fn user>(id: S, status: Option<&str>) -> Self { + if let Some(s) = status { + Self::new(format!("user:{}/{}", id.into(), s)) + } else { + Self::new(format!("user:{}", id.into())) + } + } + + /// Team role with specific team ID and optional role + pub fn team>(id: S, role: Option<&str>) -> Self { + if let Some(r) = role { + Self::new(format!("team:{}/{}", id.into(), r)) + } else { + Self::new(format!("team:{}", id.into())) + } + } + + /// Member role for a team + pub fn member>(id: S) -> Self { + Self::new(format!("member:{}", id.into())) + } + + /// Label role + pub fn label>(name: S) -> Self { + Self::new(format!("label:{}", name.into())) + } + + /// Get the role string + pub fn value(&self) -> &str { + &self.role + } +} + +impl std::fmt::Display for Role { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.role) + } +} + +impl From for String { + fn from(role: Role) -> Self { + role.role + } +} + +impl From<&str> for Role { + fn from(role: &str) -> Self { + Role::new(role.to_string()) + } +} + +impl From for Role { + fn from(role: String) -> Self { + Role::new(role) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_any_role() { + let role = Role::any(); + assert_eq!(role.to_string(), "any"); + } + + #[test] + fn test_users_role() { + let role = Role::users(None); + assert_eq!(role.to_string(), "users"); + } + + #[test] + fn test_users_role_with_status() { + let role = Role::users(Some("verified")); + assert_eq!(role.to_string(), "users/verified"); + } + + #[test] + fn test_user_role() { + let role = Role::user("123", None); + assert_eq!(role.to_string(), "user:123"); + } + + #[test] + fn test_user_role_with_status() { + let role = Role::user("123", Some("verified")); + assert_eq!(role.to_string(), "user:123/verified"); + } + + #[test] + fn test_team_role() { + let role = Role::team("developers", Some("admin")); + assert_eq!(role.to_string(), "team:developers/admin"); + } + + #[test] + fn test_team_role_without_specific_role() { + let role = Role::team("developers", None::<&str>); + assert_eq!(role.to_string(), "team:developers"); + } + + #[test] + fn test_member_role() { + let role = Role::member("123"); + assert_eq!(role.to_string(), "member:123"); + } + + #[test] + fn test_label_role() { + let role = Role::label("vip"); + assert_eq!(role.to_string(), "label:vip"); + } + + #[test] + fn test_from_string() { + let role = Role::from("custom:role"); + assert_eq!(role.to_string(), "custom:role"); + } +} diff --git a/src/services/account.rs b/src/services/account.rs new file mode 100644 index 0000000..b740c4e --- /dev/null +++ b/src/services/account.rs @@ -0,0 +1,931 @@ +//! Account service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Account service allows you to authenticate and manage a user account. +#[derive(Debug, Clone)] +pub struct Account { + client: Client, +} + +impl Account { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get the currently logged in user. + pub async fn get( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/account".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Use this endpoint to allow a new user to register a new account in your + /// project. After the user registration completes successfully, you can use + /// the + /// [/account/verfication](https://appwrite.io/docs/references/cloud/client-web/account#createVerification) + /// route to start verifying the user email address. To allow the new user to + /// login to their new account, you need to create a new [account + /// session](https://appwrite.io/docs/references/cloud/client-web/account#createEmailSession). + pub async fn create( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update currently logged in user account email address. After changing user + /// address, the user confirmation status will get reset. A new confirmation + /// email is not sent automatically however you can use the send confirmation + /// email endpoint again to send the confirmation email. For security measures, + /// user password is required to complete this request. + /// This endpoint can also be used to convert an anonymous account to a normal + /// one, by passing an email address and a new password. + pub async fn update_email( + &self, + email: impl Into, + password: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/email".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get the list of identities for the currently logged in user. + pub async fn list_identities( + &self, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/account/identities".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete an identity by its unique ID. + pub async fn delete_identity( + &self, + identity_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/identities/{identityId}".to_string().replace("{identityId}", &identity_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to create a JSON Web Token. You can use the resulting JWT + /// to authenticate on behalf of the current user when working with the + /// Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes + /// from its creation and will be invalid if the user will logout in that time + /// frame. + pub async fn create_jwt( + &self, + duration: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = duration { + params.insert("duration".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/jwts".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get the list of latest security activity logs for the currently logged in + /// user. Each log returns user IP address, location and date and time of log. + pub async fn list_logs( + &self, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/account/logs".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Enable or disable MFA on an account. + pub async fn update_mfa( + &self, + mfa: bool, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("mfa".to_string(), json!(mfa)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Add an authenticator app to be used as an MFA factor. Verify the + /// authenticator using the [verify + /// authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) + /// method. + pub async fn create_mfa_authenticator( + &self, + r#type: crate::enums::AuthenticatorType, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/authenticators/{type}".to_string().replace("{type}", &r#type.to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Verify an authenticator app after adding it using the [add + /// authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) + /// method. + pub async fn update_mfa_authenticator( + &self, + r#type: crate::enums::AuthenticatorType, + otp: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("otp".to_string(), json!(otp.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/authenticators/{type}".to_string().replace("{type}", &r#type.to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete an authenticator for a user by ID. + pub async fn delete_mfa_authenticator( + &self, + r#type: crate::enums::AuthenticatorType, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/authenticators/{type}".to_string().replace("{type}", &r#type.to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Begin the process of MFA verification after sign-in. Finish the flow with + /// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) + /// method. + pub async fn create_mfa_challenge( + &self, + factor: crate::enums::AuthenticationFactor, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("factor".to_string(), json!(factor)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/challenges".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Complete the MFA challenge by providing the one-time password. Finish the + /// process of MFA verification by providing the one-time password. To begin + /// the flow, use + /// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + /// method. + pub async fn update_mfa_challenge( + &self, + challenge_id: impl Into, + otp: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("challengeId".to_string(), json!(challenge_id.into())); + params.insert("otp".to_string(), json!(otp.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/challenges".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// List the factors available on the account to be used as a MFA challange. + pub async fn list_mfa_factors( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/account/mfa/factors".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get recovery codes that can be used as backup for MFA flow. Before getting + /// codes, they must be generated using + /// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + /// method. An OTP challenge is required to read recovery codes. + pub async fn get_mfa_recovery_codes( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/account/mfa/recovery-codes".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Generate recovery codes as backup for MFA flow. It's recommended to + /// generate and show then immediately after user successfully adds their + /// authehticator. Recovery codes can be used as a MFA verification type in + /// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + /// method. + pub async fn create_mfa_recovery_codes( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/recovery-codes".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Regenerate recovery codes that can be used as backup for MFA flow. Before + /// regenerating codes, they must be first generated using + /// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + /// method. An OTP challenge is required to regenreate recovery codes. + pub async fn update_mfa_recovery_codes( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/mfa/recovery-codes".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update currently logged in user account name. + pub async fn update_name( + &self, + name: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/name".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update currently logged in user password. For validation, user is required + /// to pass in the new password, and the old password. For users created with + /// OAuth, Team Invites and Magic URL, oldPassword is optional. + pub async fn update_password( + &self, + password: impl Into, + old_password: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = old_password { + params.insert("oldPassword".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/password".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update the currently logged in user's phone number. After updating the + /// phone number, the phone verification status will be reset. A confirmation + /// SMS is not sent automatically, however you can use the [POST + /// /account/verification/phone](https://appwrite.io/docs/references/cloud/client-web/account#createPhoneVerification) + /// endpoint to send a confirmation SMS. + pub async fn update_phone( + &self, + phone: impl Into, + password: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("phone".to_string(), json!(phone.into())); + params.insert("password".to_string(), json!(password.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/phone".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get the preferences as a key-value object for the currently logged in user. + pub async fn get_prefs( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/account/prefs".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update currently logged in user account preferences. The object you pass is + /// stored as is, and replaces any previous value. The maximum allowed prefs + /// size is 64kB and throws error if exceeded. + pub async fn update_prefs( + &self, + prefs: serde_json::Value, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("prefs".to_string(), json!(prefs)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/prefs".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Sends the user an email with a temporary secret key for password reset. + /// When the user clicks the confirmation link he is redirected back to your + /// app password reset URL with the secret key and email address values + /// attached to the URL query string. Use the query string params to submit a + /// request to the [PUT + /// /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#updateRecovery) + /// endpoint to complete the process. The verification link sent to the user's + /// email address is valid for 1 hour. + pub async fn create_recovery( + &self, + email: impl Into, + url: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("email".to_string(), json!(email.into())); + params.insert("url".to_string(), json!(url.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/recovery".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to complete the user account password reset. Both the + /// **userId** and **secret** arguments will be passed as query parameters to + /// the redirect URL you have provided when sending your request to the [POST + /// /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#createRecovery) + /// endpoint. + /// + /// Please note that in order to avoid a [Redirect + /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + /// the only valid redirect URLs are the ones from domains you have set when + /// adding your platforms in the console interface. + pub async fn update_recovery( + &self, + user_id: impl Into, + secret: impl Into, + password: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + params.insert("password".to_string(), json!(password.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/recovery".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Get the list of active sessions across different devices for the currently + /// logged in user. + pub async fn list_sessions( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/account/sessions".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete all sessions from the user account and remove any sessions cookies + /// from the end client. + pub async fn delete_sessions( + &self, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions".to_string(); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to allow a new user to register an anonymous account in + /// your project. This route will also create a new session for the user. To + /// allow the new user to convert an anonymous account to a normal account, you + /// need to update its [email and + /// password](https://appwrite.io/docs/references/cloud/client-web/account#updateEmail) + /// or create an [OAuth2 + /// session](https://appwrite.io/docs/references/cloud/client-web/account#CreateOAuth2Session). + pub async fn create_anonymous_session( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/anonymous".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Allow the user to login into their account by providing a valid email and + /// password combination. This route will create a new session for the user. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + pub async fn create_email_password_session( + &self, + email: impl Into, + password: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/email".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to create a session from token. Provide the **userId** + /// and **secret** parameters from the successful response of authentication + /// flows initiated by token creation. For example, magic URL and phone login. + pub async fn update_magic_url_session( + &self, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/magic-url".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to create a session from token. Provide the **userId** + /// and **secret** parameters from the successful response of authentication + /// flows initiated by token creation. For example, magic URL and phone login. + pub async fn update_phone_session( + &self, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/phone".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to create a session from token. Provide the **userId** + /// and **secret** parameters from the successful response of authentication + /// flows initiated by token creation. For example, magic URL and phone login. + pub async fn create_session( + &self, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/token".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to get a logged in user's session using a Session ID. + /// Inputting 'current' will return the current session being used. + pub async fn get_session( + &self, + session_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/account/sessions/{sessionId}".to_string().replace("{sessionId}", &session_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Use this endpoint to extend a session's length. Extending a session is + /// useful when session expiry is short. If the session was created using an + /// OAuth provider, this endpoint refreshes the access token from the provider. + pub async fn update_session( + &self, + session_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/{sessionId}".to_string().replace("{sessionId}", &session_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Logout the user. Use 'current' as the session ID to logout on this device, + /// use a session ID to logout on another device. If you're looking to logout + /// the user on all devices, use [Delete + /// Sessions](https://appwrite.io/docs/references/cloud/client-web/account#deleteSessions) + /// instead. + pub async fn delete_session( + &self, + session_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/sessions/{sessionId}".to_string().replace("{sessionId}", &session_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Block the currently logged in user account. Behind the scene, the user + /// record is not deleted but permanently blocked from any access. To + /// completely delete a user, use the Users API instead. + pub async fn update_status( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/status".to_string(); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Sends the user an email with a secret key for creating a session. If the + /// email address has never been used, a **new account is created** using the + /// provided `userId`. Otherwise, if the email address is already attached to + /// an account, the **user ID is ignored**. Then, the user will receive an + /// email with the one-time password. Use the returned user ID and secret and + /// submit a request to the [POST + /// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. The secret sent to the user's email + /// is valid for 15 minutes. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + pub async fn create_email_token( + &self, + user_id: impl Into, + email: impl Into, + phrase: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + if let Some(value) = phrase { + params.insert("phrase".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/tokens/email".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Sends the user an email with a secret key for creating a session. If the + /// provided user ID has not been registered, a new user will be created. When + /// the user clicks the link in the email, the user is redirected back to the + /// URL you provided with the secret key and userId values attached to the URL + /// query string. Use the query string parameters to submit a request to the + /// [POST + /// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. The link sent to the user's email + /// address is valid for 1 hour. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + pub async fn create_magic_url_token( + &self, + user_id: impl Into, + email: impl Into, + url: Option<&str>, + phrase: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + if let Some(value) = url { + params.insert("url".to_string(), json!(value)); + } + if let Some(value) = phrase { + params.insert("phrase".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/tokens/magic-url".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Allow the user to login to their account using the OAuth2 provider of their + /// choice. Each OAuth2 provider should be enabled from the Appwrite console + /// first. Use the success and failure arguments to provide a redirect URL's + /// back to your app when login is completed. + /// + /// If authentication succeeds, `userId` and `secret` of a token will be + /// appended to the success URL as query parameters. These can be used to + /// create a new session using the [Create + /// session](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + pub async fn create_o_auth2_token( + &self, + provider: crate::enums::OAuthProvider, + success: Option<&str>, + failure: Option<&str>, + scopes: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = success { + params.insert("success".to_string(), json!(value)); + } + if let Some(value) = failure { + params.insert("failure".to_string(), json!(value)); + } + if let Some(value) = scopes { + params.insert("scopes".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + + let path = "/account/tokens/oauth2/{provider}".to_string().replace("{provider}", &provider.to_string()); + + self.client.call_location(Method::GET, &path, None, Some(params)).await + } + + /// Sends the user an SMS with a secret key for creating a session. If the + /// provided user ID has not be registered, a new user will be created. Use the + /// returned user ID and secret and submit a request to the [POST + /// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. The secret sent to the user's phone + /// is valid for 15 minutes. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + pub async fn create_phone_token( + &self, + user_id: impl Into, + phone: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("phone".to_string(), json!(phone.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/tokens/phone".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to send a verification message to your user email address + /// to confirm they are the valid owners of that address. Both the **userId** + /// and **secret** arguments will be passed as query parameters to the URL you + /// have provided to be attached to the verification email. The provided URL + /// should redirect the user back to your app and allow you to complete the + /// verification process by verifying both the **userId** and **secret** + /// parameters. Learn more about how to [complete the verification + /// process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). + /// The verification link sent to the user's email address is valid for 7 days. + /// + /// Please note that in order to avoid a [Redirect + /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), + /// the only valid redirect URLs are the ones from domains you have set when + /// adding your platforms in the console interface. + pub async fn create_email_verification( + &self, + url: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("url".to_string(), json!(url.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/verifications/email".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to send a verification message to your user email address + /// to confirm they are the valid owners of that address. Both the **userId** + /// and **secret** arguments will be passed as query parameters to the URL you + /// have provided to be attached to the verification email. The provided URL + /// should redirect the user back to your app and allow you to complete the + /// verification process by verifying both the **userId** and **secret** + /// parameters. Learn more about how to [complete the verification + /// process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). + /// The verification link sent to the user's email address is valid for 7 days. + /// + /// Please note that in order to avoid a [Redirect + /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), + /// the only valid redirect URLs are the ones from domains you have set when + /// adding your platforms in the console interface. + pub async fn create_verification( + &self, + url: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("url".to_string(), json!(url.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/verifications/email".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to complete the user email verification process. Use both + /// the **userId** and **secret** parameters that were attached to your app URL + /// to verify the user email ownership. If confirmed this route will return a + /// 200 status code. + pub async fn update_email_verification( + &self, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/verifications/email".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to complete the user email verification process. Use both + /// the **userId** and **secret** parameters that were attached to your app URL + /// to verify the user email ownership. If confirmed this route will return a + /// 200 status code. + pub async fn update_verification( + &self, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/verifications/email".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to send a verification SMS to the currently logged in + /// user. This endpoint is meant for use after updating a user's phone number + /// using the + /// [accountUpdatePhone](https://appwrite.io/docs/references/cloud/client-web/account#updatePhone) + /// endpoint. Learn more about how to [complete the verification + /// process](https://appwrite.io/docs/references/cloud/client-web/account#updatePhoneVerification). + /// The verification code sent to the user's phone number is valid for 15 + /// minutes. + pub async fn create_phone_verification( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/verifications/phone".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to complete the user phone verification process. Use the + /// **userId** and **secret** that were sent to your user's phone number to + /// verify the user email ownership. If confirmed this route will return a 200 + /// status code. + pub async fn update_phone_verification( + &self, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/account/verifications/phone".to_string(); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Account { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_account_creation() { + let client = Client::new(); + let service = Account::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/activities.rs b/src/services/activities.rs new file mode 100644 index 0000000..83151b4 --- /dev/null +++ b/src/services/activities.rs @@ -0,0 +1,68 @@ +//! Activities service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub struct Activities { + client: Client, +} + +impl Activities { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// List all events for selected filters. + pub async fn list_events( + &self, + queries: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value)); + } + + let path = "/activities/events".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get event by ID. + pub async fn get_event( + &self, + event_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/activities/events/{eventId}".to_string().replace("{eventId}", &event_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + +} + +impl crate::services::Service for Activities { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_activities_creation() { + let client = Client::new(); + let service = Activities::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/avatars.rs b/src/services/avatars.rs new file mode 100644 index 0000000..c82e8bd --- /dev/null +++ b/src/services/avatars.rs @@ -0,0 +1,352 @@ +//! Avatars service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Avatars service aims to help you complete everyday tasks related to +/// your app image, icons, and avatars. +#[derive(Debug, Clone)] +pub struct Avatars { + client: Client, +} + +impl Avatars { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// You can use this endpoint to show different browser icons to your users. + /// The code argument receives the browser code as it appears in your user [GET + /// /account/sessions](https://appwrite.io/docs/references/cloud/client-web/account#getSessions) + /// endpoint. Use width, height and quality arguments to change the output + /// settings. + /// + /// When one dimension is specified and the other is 0, the image is scaled + /// with preserved aspect ratio. If both dimensions are 0, the API provides an + /// image at source quality. If dimensions are not specified, the default size + /// of image returned is 100x100px. + pub async fn get_browser( + &self, + code: crate::enums::Browser, + width: Option, + height: Option, + quality: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + if let Some(value) = quality { + params.insert("quality".to_string(), json!(value)); + } + + let path = "/avatars/browsers/{code}".to_string().replace("{code}", &code.to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// The credit card endpoint will return you the icon of the credit card + /// provider you need. Use width, height and quality arguments to change the + /// output settings. + /// + /// When one dimension is specified and the other is 0, the image is scaled + /// with preserved aspect ratio. If both dimensions are 0, the API provides an + /// image at source quality. If dimensions are not specified, the default size + /// of image returned is 100x100px. + pub async fn get_credit_card( + &self, + code: crate::enums::CreditCard, + width: Option, + height: Option, + quality: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + if let Some(value) = quality { + params.insert("quality".to_string(), json!(value)); + } + + let path = "/avatars/credit-cards/{code}".to_string().replace("{code}", &code.to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Use this endpoint to fetch the favorite icon (AKA favicon) of any remote + /// website URL. + /// + /// This endpoint does not follow HTTP redirects. + pub async fn get_favicon( + &self, + url: impl Into, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + params.insert("url".to_string(), json!(url.into())); + + let path = "/avatars/favicon".to_string(); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// You can use this endpoint to show different country flags icons to your + /// users. The code argument receives the 2 letter country code. Use width, + /// height and quality arguments to change the output settings. Country codes + /// follow the [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) standard. + /// + /// When one dimension is specified and the other is 0, the image is scaled + /// with preserved aspect ratio. If both dimensions are 0, the API provides an + /// image at source quality. If dimensions are not specified, the default size + /// of image returned is 100x100px. + pub async fn get_flag( + &self, + code: crate::enums::Flag, + width: Option, + height: Option, + quality: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + if let Some(value) = quality { + params.insert("quality".to_string(), json!(value)); + } + + let path = "/avatars/flags/{code}".to_string().replace("{code}", &code.to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Use this endpoint to fetch a remote image URL and crop it to any image size + /// you want. This endpoint is very useful if you need to crop and display + /// remote images in your app or in case you want to make sure a 3rd party + /// image is properly served using a TLS protocol. + /// + /// When one dimension is specified and the other is 0, the image is scaled + /// with preserved aspect ratio. If both dimensions are 0, the API provides an + /// image at source quality. If dimensions are not specified, the default size + /// of image returned is 400x400px. + /// + /// This endpoint does not follow HTTP redirects. + pub async fn get_image( + &self, + url: impl Into, + width: Option, + height: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + params.insert("url".to_string(), json!(url.into())); + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + + let path = "/avatars/image".to_string(); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Use this endpoint to show your user initials avatar icon on your website or + /// app. By default, this route will try to print your logged-in user name or + /// email initials. You can also overwrite the user name if you pass the 'name' + /// parameter. If no name is given and no user is logged, an empty avatar will + /// be returned. + /// + /// You can use the color and background params to change the avatar colors. By + /// default, a random theme will be selected. The random theme will persist for + /// the user's initials when reloading the same theme will always return for + /// the same initials. + /// + /// When one dimension is specified and the other is 0, the image is scaled + /// with preserved aspect ratio. If both dimensions are 0, the API provides an + /// image at source quality. If dimensions are not specified, the default size + /// of image returned is 100x100px. + pub async fn get_initials( + &self, + name: Option<&str>, + width: Option, + height: Option, + background: Option<&str>, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + if let Some(value) = background { + params.insert("background".to_string(), json!(value)); + } + + let path = "/avatars/initials".to_string(); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Converts a given plain text to a QR code image. You can use the query + /// parameters to change the size and style of the resulting image. + pub async fn get_qr( + &self, + text: impl Into, + size: Option, + margin: Option, + download: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + params.insert("text".to_string(), json!(text.into())); + if let Some(value) = size { + params.insert("size".to_string(), json!(value)); + } + if let Some(value) = margin { + params.insert("margin".to_string(), json!(value)); + } + if let Some(value) = download { + params.insert("download".to_string(), json!(value)); + } + + let path = "/avatars/qr".to_string(); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Use this endpoint to capture a screenshot of any website URL. This endpoint + /// uses a headless browser to render the webpage and capture it as an image. + /// + /// You can configure the browser viewport size, theme, user agent, + /// geolocation, permissions, and more. Capture either just the viewport or the + /// full page scroll. + /// + /// When width and height are specified, the image is resized accordingly. If + /// both dimensions are 0, the API provides an image at original size. If + /// dimensions are not specified, the default viewport size is 1280x720px. + #[allow(clippy::too_many_arguments)] + pub async fn get_screenshot( + &self, + url: impl Into, + headers: Option, + viewport_width: Option, + viewport_height: Option, + scale: Option, + theme: Option, + user_agent: Option<&str>, + fullpage: Option, + locale: Option<&str>, + timezone: Option, + latitude: Option, + longitude: Option, + accuracy: Option, + touch: Option, + permissions: Option, + sleep: Option, + width: Option, + height: Option, + quality: Option, + output: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + params.insert("url".to_string(), json!(url.into())); + if let Some(value) = headers { + params.insert("headers".to_string(), json!(value)); + } + if let Some(value) = viewport_width { + params.insert("viewportWidth".to_string(), json!(value)); + } + if let Some(value) = viewport_height { + params.insert("viewportHeight".to_string(), json!(value)); + } + if let Some(value) = scale { + params.insert("scale".to_string(), json!(value)); + } + if let Some(value) = theme { + params.insert("theme".to_string(), json!(value)); + } + if let Some(value) = user_agent { + params.insert("userAgent".to_string(), json!(value)); + } + if let Some(value) = fullpage { + params.insert("fullpage".to_string(), json!(value)); + } + if let Some(value) = locale { + params.insert("locale".to_string(), json!(value)); + } + if let Some(value) = timezone { + params.insert("timezone".to_string(), json!(value)); + } + if let Some(value) = latitude { + params.insert("latitude".to_string(), json!(value)); + } + if let Some(value) = longitude { + params.insert("longitude".to_string(), json!(value)); + } + if let Some(value) = accuracy { + params.insert("accuracy".to_string(), json!(value)); + } + if let Some(value) = touch { + params.insert("touch".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value)); + } + if let Some(value) = sleep { + params.insert("sleep".to_string(), json!(value)); + } + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + if let Some(value) = quality { + params.insert("quality".to_string(), json!(value)); + } + if let Some(value) = output { + params.insert("output".to_string(), json!(value)); + } + + let path = "/avatars/screenshots".to_string(); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + +} + +impl crate::services::Service for Avatars { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_avatars_creation() { + let client = Client::new(); + let service = Avatars::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/backups.rs b/src/services/backups.rs new file mode 100644 index 0000000..da96e2d --- /dev/null +++ b/src/services/backups.rs @@ -0,0 +1,258 @@ +//! Backups service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub struct Backups { + client: Client, +} + +impl Backups { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// List all archives for a project. + pub async fn list_archives( + &self, + queries: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + + let path = "/backups/archives".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new archive asynchronously for a project. + pub async fn create_archive( + &self, + services: crate::enums::BackupServices, + resource_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("services".to_string(), json!(services)); + if let Some(value) = resource_id { + params.insert("resourceId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/backups/archives".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a backup archive using it's ID. + pub async fn get_archive( + &self, + archive_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/backups/archives/{archiveId}".to_string().replace("{archiveId}", &archive_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete an existing archive for a project. + pub async fn delete_archive( + &self, + archive_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/backups/archives/{archiveId}".to_string().replace("{archiveId}", &archive_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// List all policies for a project. + pub async fn list_policies( + &self, + queries: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + + let path = "/backups/policies".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new backup policy. + #[allow(clippy::too_many_arguments)] + pub async fn create_policy( + &self, + policy_id: impl Into, + services: crate::enums::BackupServices, + retention: i64, + schedule: impl Into, + name: Option<&str>, + resource_id: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("policyId".to_string(), json!(policy_id.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + params.insert("services".to_string(), json!(services)); + if let Some(value) = resource_id { + params.insert("resourceId".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + params.insert("retention".to_string(), json!(retention)); + params.insert("schedule".to_string(), json!(schedule.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/backups/policies".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a backup policy using it's ID. + pub async fn get_policy( + &self, + policy_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/backups/policies/{policyId}".to_string().replace("{policyId}", &policy_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update an existing policy using it's ID. + pub async fn update_policy( + &self, + policy_id: impl Into, + name: Option<&str>, + retention: Option, + schedule: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = retention { + params.insert("retention".to_string(), json!(value)); + } + if let Some(value) = schedule { + params.insert("schedule".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/backups/policies/{policyId}".to_string().replace("{policyId}", &policy_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a policy using it's ID. + pub async fn delete_policy( + &self, + policy_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/backups/policies/{policyId}".to_string().replace("{policyId}", &policy_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Create and trigger a new restoration for a backup on a project. + pub async fn create_restoration( + &self, + archive_id: impl Into, + services: crate::enums::BackupServices, + new_resource_id: Option<&str>, + new_resource_name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("archiveId".to_string(), json!(archive_id.into())); + params.insert("services".to_string(), json!(services)); + if let Some(value) = new_resource_id { + params.insert("newResourceId".to_string(), json!(value)); + } + if let Some(value) = new_resource_name { + params.insert("newResourceName".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/backups/restoration".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// List all backup restorations for a project. + pub async fn list_restorations( + &self, + queries: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + + let path = "/backups/restorations".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the current status of a backup restoration. + pub async fn get_restoration( + &self, + restoration_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/backups/restorations/{restorationId}".to_string().replace("{restorationId}", &restoration_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + +} + +impl crate::services::Service for Backups { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_backups_creation() { + let client = Client::new(); + let service = Backups::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/databases.rs b/src/services/databases.rs new file mode 100644 index 0000000..56e5656 --- /dev/null +++ b/src/services/databases.rs @@ -0,0 +1,1820 @@ +//! Databases service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Databases service allows you to create structured collections of +/// documents, query and filter lists of documents +#[derive(Debug, Clone)] +pub struct Databases { + client: Client, +} + +impl Databases { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all databases from the current Appwrite project. You can use + /// the search parameter to filter your results. + pub async fn list( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/databases".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Database. + pub async fn create( + &self, + database_id: impl Into, + name: impl Into, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("databaseId".to_string(), json!(database_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// List transactions across all databases. + pub async fn list_transactions( + &self, + queries: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + + let path = "/databases/transactions".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new transaction. + pub async fn create_transaction( + &self, + ttl: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = ttl { + params.insert("ttl".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/transactions".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a transaction by its unique ID. + pub async fn get_transaction( + &self, + transaction_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/databases/transactions/{transactionId}".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a transaction, to either commit or roll back its operations. + pub async fn update_transaction( + &self, + transaction_id: impl Into, + commit: Option, + rollback: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = commit { + params.insert("commit".to_string(), json!(value)); + } + if let Some(value) = rollback { + params.insert("rollback".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/transactions/{transactionId}".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a transaction by its unique ID. + pub async fn delete_transaction( + &self, + transaction_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/transactions/{transactionId}".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Create multiple operations in a single transaction. + pub async fn create_operations( + &self, + transaction_id: impl Into, + operations: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = operations { + params.insert("operations".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/transactions/{transactionId}/operations".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a database by its unique ID. This endpoint response returns a JSON + /// object with the database metadata. + pub async fn get( + &self, + database_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/databases/{databaseId}".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a database by its unique ID. + pub async fn update( + &self, + database_id: impl Into, + name: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a database by its unique ID. Only API keys with with databases.write + /// scope can delete a database. + pub async fn delete( + &self, + database_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all collections that belong to the provided databaseId. You + /// can use the search parameter to filter your results. + pub async fn list_collections( + &self, + database_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/databases/{databaseId}/collections".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Collection. Before using this route, you should create a new + /// database resource using either a [server + /// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + /// API or directly from your database console. + #[allow(clippy::too_many_arguments)] + pub async fn create_collection( + &self, + database_id: impl Into, + collection_id: impl Into, + name: impl Into, + permissions: Option>, + document_security: Option, + enabled: Option, + attributes: Option>, + indexes: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("collectionId".to_string(), json!(collection_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = document_security { + params.insert("documentSecurity".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = attributes { + params.insert("attributes".to_string(), json!(value)); + } + if let Some(value) = indexes { + params.insert("indexes".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a collection by its unique ID. This endpoint response returns a JSON + /// object with the collection metadata. + pub async fn get_collection( + &self, + database_id: impl Into, + collection_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/databases/{databaseId}/collections/{collectionId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a collection by its unique ID. + pub async fn update_collection( + &self, + database_id: impl Into, + collection_id: impl Into, + name: Option<&str>, + permissions: Option>, + document_security: Option, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = document_security { + params.insert("documentSecurity".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a collection by its unique ID. Only users with write permissions + /// have access to delete this resource. + pub async fn delete_collection( + &self, + database_id: impl Into, + collection_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// List attributes in the collection. + pub async fn list_attributes( + &self, + database_id: impl Into, + collection_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a boolean attribute. + pub async fn create_boolean_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/boolean".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a boolean attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_boolean_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/boolean/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a date time attribute according to the ISO 8601 standard. + pub async fn create_datetime_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/datetime".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a date time attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_datetime_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/datetime/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create an email attribute. + pub async fn create_email_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/email".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an email attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_email_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/email/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create an enum attribute. The `elements` param acts as a white-list of + /// accepted values for this attribute. + #[allow(clippy::too_many_arguments)] + pub async fn create_enum_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + elements: impl IntoIterator>, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("elements".to_string(), json!(elements.into_iter().map(|s| s.into()).collect::>())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/enum".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an enum attribute. Changing the `default` value will not update + /// already existing documents. + #[allow(clippy::too_many_arguments)] + pub async fn update_enum_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + elements: impl IntoIterator>, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("elements".to_string(), json!(elements.into_iter().map(|s| s.into()).collect::>())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/enum/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a float attribute. Optionally, minimum and maximum values can be + /// provided. + #[allow(clippy::too_many_arguments)] + pub async fn create_float_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + min: Option, + max: Option, + default: Option, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/float".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a float attribute. Changing the `default` value will not update + /// already existing documents. + #[allow(clippy::too_many_arguments)] + pub async fn update_float_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option, + min: Option, + max: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/float/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create an integer attribute. Optionally, minimum and maximum values can be + /// provided. + #[allow(clippy::too_many_arguments)] + pub async fn create_integer_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + min: Option, + max: Option, + default: Option, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/integer".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an integer attribute. Changing the `default` value will not update + /// already existing documents. + #[allow(clippy::too_many_arguments)] + pub async fn update_integer_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option, + min: Option, + max: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/integer/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create IP address attribute. + pub async fn create_ip_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/ip".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an ip attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_ip_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/ip/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a geometric line attribute. + pub async fn create_line_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/line".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a line attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_line_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/line/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a longtext attribute. + #[allow(clippy::too_many_arguments)] + pub async fn create_longtext_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/longtext".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a longtext attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_longtext_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/longtext/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a mediumtext attribute. + #[allow(clippy::too_many_arguments)] + pub async fn create_mediumtext_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/mediumtext".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a mediumtext attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_mediumtext_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/mediumtext/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a geometric point attribute. + pub async fn create_point_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/point".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a point attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_point_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/point/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a geometric polygon attribute. + pub async fn create_polygon_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/polygon".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a polygon attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_polygon_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/polygon/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create relationship attribute. [Learn more about relationship + /// attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + #[allow(clippy::too_many_arguments)] + pub async fn create_relationship_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + related_collection_id: impl Into, + r#type: crate::enums::RelationshipType, + two_way: Option, + key: Option<&str>, + two_way_key: Option<&str>, + on_delete: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("relatedCollectionId".to_string(), json!(related_collection_id.into())); + params.insert("type".to_string(), json!(r#type)); + if let Some(value) = two_way { + params.insert("twoWay".to_string(), json!(value)); + } + if let Some(value) = key { + params.insert("key".to_string(), json!(value)); + } + if let Some(value) = two_way_key { + params.insert("twoWayKey".to_string(), json!(value)); + } + if let Some(value) = on_delete { + params.insert("onDelete".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/relationship".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update relationship attribute. [Learn more about relationship + /// attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + pub async fn update_relationship_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + on_delete: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = on_delete { + params.insert("onDelete".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/relationship/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a string attribute. + #[allow(clippy::too_many_arguments)] + pub async fn create_string_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + size: i64, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("size".to_string(), json!(size)); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/string".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a string attribute. Changing the `default` value will not update + /// already existing documents. + #[allow(clippy::too_many_arguments)] + pub async fn update_string_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + size: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = size { + params.insert("size".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/string/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a text attribute. + #[allow(clippy::too_many_arguments)] + pub async fn create_text_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/text".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a text attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_text_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/text/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a URL attribute. + pub async fn create_url_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/url".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an url attribute. Changing the `default` value will not update + /// already existing documents. + pub async fn update_url_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/url/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a varchar attribute. + #[allow(clippy::too_many_arguments)] + pub async fn create_varchar_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + size: i64, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("size".to_string(), json!(size)); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/varchar".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a varchar attribute. Changing the `default` value will not update + /// already existing documents. + #[allow(clippy::too_many_arguments)] + pub async fn update_varchar_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + size: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = size { + params.insert("size".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/varchar/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get attribute by ID. + pub async fn get_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Deletes an attribute. + pub async fn delete_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/attributes/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all the user's documents in a given collection. You can use + /// the query params to filter your results. + pub async fn list_documents( + &self, + database_id: impl Into, + collection_id: impl Into, + queries: Option>, + transaction_id: Option<&str>, + total: Option, + ttl: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + if let Some(value) = ttl { + params.insert("ttl".to_string(), json!(value)); + } + + let path = "/databases/{databaseId}/collections/{collectionId}/documents".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Document. Before using this route, you should create a new + /// collection resource using either a [server + /// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + /// API or directly from your database console. + pub async fn create_document( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + data: serde_json::Value, + permissions: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("documentId".to_string(), json!(document_id.into())); + params.insert("data".to_string(), json!(data)); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create new Documents. Before using this route, you should create a new + /// collection resource using either a [server + /// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + /// API or directly from your database console. + pub async fn create_documents( + &self, + database_id: impl Into, + collection_id: impl Into, + documents: Vec, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("documents".to_string(), json!(documents)); + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create or update Documents. Before using this route, you should create a + /// new collection resource using either a [server + /// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + /// API or directly from your database console. + pub async fn upsert_documents( + &self, + database_id: impl Into, + collection_id: impl Into, + documents: Vec, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("documents".to_string(), json!(documents)); + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Update all documents that match your queries, if no queries are submitted + /// then all documents are updated. You can pass only specific fields to be + /// updated. + pub async fn update_documents( + &self, + database_id: impl Into, + collection_id: impl Into, + data: Option, + queries: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Bulk delete documents using queries, if no queries are passed then all + /// documents are deleted. + pub async fn delete_documents( + &self, + database_id: impl Into, + collection_id: impl Into, + queries: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a document by its unique ID. This endpoint response returns a JSON + /// object with the document data. + pub async fn get_document( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + queries: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + + let path = "/databases/{databaseId}/collections/{collectionId}/documents/{documentId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{documentId}", &document_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create or update a Document. Before using this route, you should create a + /// new collection resource using either a [server + /// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + /// API or directly from your database console. + pub async fn upsert_document( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + data: Option, + permissions: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents/{documentId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{documentId}", &document_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Update a document by its unique ID. Using the patch method you can pass + /// only specific fields that will get updated. + pub async fn update_document( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + data: Option, + permissions: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents/{documentId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{documentId}", &document_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a document by its unique ID. + pub async fn delete_document( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + transaction_id: Option<&str>, + ) -> crate::error::Result<()> { + let mut params = HashMap::new(); + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents/{documentId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{documentId}", &document_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Decrement a specific attribute of a document by a given value. + #[allow(clippy::too_many_arguments)] + pub async fn decrement_document_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + attribute: impl Into, + value: Option, + min: Option, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = value { + params.insert("value".to_string(), json!(value)); + } + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/decrement".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{documentId}", &document_id.into().to_string()).replace("{attribute}", &attribute.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Increment a specific attribute of a document by a given value. + #[allow(clippy::too_many_arguments)] + pub async fn increment_document_attribute( + &self, + database_id: impl Into, + collection_id: impl Into, + document_id: impl Into, + attribute: impl Into, + value: Option, + max: Option, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = value { + params.insert("value".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/increment".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{documentId}", &document_id.into().to_string()).replace("{attribute}", &attribute.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// List indexes in the collection. + pub async fn list_indexes( + &self, + database_id: impl Into, + collection_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/databases/{databaseId}/collections/{collectionId}/indexes".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Creates an index on the attributes listed. Your index should include all + /// the attributes you will query in a single request. + /// Attributes can be `key`, `fulltext`, and `unique`. + #[allow(clippy::too_many_arguments)] + pub async fn create_index( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + r#type: crate::enums::IndexType, + attributes: impl IntoIterator>, + orders: Option, + lengths: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("type".to_string(), json!(r#type)); + params.insert("attributes".to_string(), json!(attributes.into_iter().map(|s| s.into()).collect::>())); + if let Some(value) = orders { + params.insert("orders".to_string(), json!(value)); + } + if let Some(value) = lengths { + params.insert("lengths".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/indexes".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get an index by its unique ID. + pub async fn get_index( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/databases/{databaseId}/collections/{collectionId}/indexes/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete an index. + pub async fn delete_index( + &self, + database_id: impl Into, + collection_id: impl Into, + key: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/databases/{databaseId}/collections/{collectionId}/indexes/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{collectionId}", &collection_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Databases { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_databases_creation() { + let client = Client::new(); + let service = Databases::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/functions.rs b/src/services/functions.rs new file mode 100644 index 0000000..e9a7981 --- /dev/null +++ b/src/services/functions.rs @@ -0,0 +1,697 @@ +//! Functions service for Appwrite SDK + +use crate::client::Client; +use crate::input_file::InputFile; +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Functions Service allows you view, create and manage your Cloud +/// Functions. +#[derive(Debug, Clone)] +pub struct Functions { + client: Client, +} + +impl Functions { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all the project's functions. You can use the query params to + /// filter your results. + pub async fn list( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/functions".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new function. You can pass a list of + /// [permissions](https://appwrite.io/docs/permissions) to allow different + /// project users or team with access to execute the function using the client + /// API. + #[allow(clippy::too_many_arguments)] + pub async fn create( + &self, + function_id: impl Into, + name: impl Into, + runtime: crate::enums::Runtime, + execute: Option>, + events: Option>, + schedule: Option<&str>, + timeout: Option, + enabled: Option, + logging: Option, + entrypoint: Option<&str>, + commands: Option<&str>, + scopes: Option, + installation_id: Option<&str>, + provider_repository_id: Option<&str>, + provider_branch: Option<&str>, + provider_silent_mode: Option, + provider_root_directory: Option<&str>, + build_specification: Option<&str>, + runtime_specification: Option<&str>, + deployment_retention: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("functionId".to_string(), json!(function_id.into())); + params.insert("name".to_string(), json!(name.into())); + params.insert("runtime".to_string(), json!(runtime)); + if let Some(value) = execute { + params.insert("execute".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = events { + params.insert("events".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = schedule { + params.insert("schedule".to_string(), json!(value)); + } + if let Some(value) = timeout { + params.insert("timeout".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = logging { + params.insert("logging".to_string(), json!(value)); + } + if let Some(value) = entrypoint { + params.insert("entrypoint".to_string(), json!(value)); + } + if let Some(value) = commands { + params.insert("commands".to_string(), json!(value)); + } + if let Some(value) = scopes { + params.insert("scopes".to_string(), json!(value)); + } + if let Some(value) = installation_id { + params.insert("installationId".to_string(), json!(value)); + } + if let Some(value) = provider_repository_id { + params.insert("providerRepositoryId".to_string(), json!(value)); + } + if let Some(value) = provider_branch { + params.insert("providerBranch".to_string(), json!(value)); + } + if let Some(value) = provider_silent_mode { + params.insert("providerSilentMode".to_string(), json!(value)); + } + if let Some(value) = provider_root_directory { + params.insert("providerRootDirectory".to_string(), json!(value)); + } + if let Some(value) = build_specification { + params.insert("buildSpecification".to_string(), json!(value)); + } + if let Some(value) = runtime_specification { + params.insert("runtimeSpecification".to_string(), json!(value)); + } + if let Some(value) = deployment_retention { + params.insert("deploymentRetention".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all runtimes that are currently active on your instance. + pub async fn list_runtimes( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/runtimes".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List allowed function specifications for this instance. + pub async fn list_specifications( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/specifications".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a function by its unique ID. + pub async fn get( + &self, + function_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/{functionId}".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update function by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update( + &self, + function_id: impl Into, + name: impl Into, + runtime: Option, + execute: Option>, + events: Option>, + schedule: Option<&str>, + timeout: Option, + enabled: Option, + logging: Option, + entrypoint: Option<&str>, + commands: Option<&str>, + scopes: Option, + installation_id: Option<&str>, + provider_repository_id: Option<&str>, + provider_branch: Option<&str>, + provider_silent_mode: Option, + provider_root_directory: Option<&str>, + build_specification: Option<&str>, + runtime_specification: Option<&str>, + deployment_retention: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = runtime { + params.insert("runtime".to_string(), json!(value)); + } + if let Some(value) = execute { + params.insert("execute".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = events { + params.insert("events".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = schedule { + params.insert("schedule".to_string(), json!(value)); + } + if let Some(value) = timeout { + params.insert("timeout".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = logging { + params.insert("logging".to_string(), json!(value)); + } + if let Some(value) = entrypoint { + params.insert("entrypoint".to_string(), json!(value)); + } + if let Some(value) = commands { + params.insert("commands".to_string(), json!(value)); + } + if let Some(value) = scopes { + params.insert("scopes".to_string(), json!(value)); + } + if let Some(value) = installation_id { + params.insert("installationId".to_string(), json!(value)); + } + if let Some(value) = provider_repository_id { + params.insert("providerRepositoryId".to_string(), json!(value)); + } + if let Some(value) = provider_branch { + params.insert("providerBranch".to_string(), json!(value)); + } + if let Some(value) = provider_silent_mode { + params.insert("providerSilentMode".to_string(), json!(value)); + } + if let Some(value) = provider_root_directory { + params.insert("providerRootDirectory".to_string(), json!(value)); + } + if let Some(value) = build_specification { + params.insert("buildSpecification".to_string(), json!(value)); + } + if let Some(value) = runtime_specification { + params.insert("runtimeSpecification".to_string(), json!(value)); + } + if let Some(value) = deployment_retention { + params.insert("deploymentRetention".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a function by its unique ID. + pub async fn delete( + &self, + function_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Update the function active deployment. Use this endpoint to switch the code + /// deployment that should be used when visitor opens your function. + pub async fn update_function_deployment( + &self, + function_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("deploymentId".to_string(), json!(deployment_id.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/deployment".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all the function's code deployments. You can use the query + /// params to filter your results. + pub async fn list_deployments( + &self, + function_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/functions/{functionId}/deployments".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new function code deployment. Use this endpoint to upload a new + /// version of your code function. To execute your newly uploaded code, you'll + /// need to update the function's deployment to use your new deployment UID. + /// + /// This endpoint accepts a tar.gz file compressed with your code. Make sure to + /// include any dependencies your code has within the compressed file. You can + /// learn more about code packaging in the [Appwrite Cloud Functions + /// tutorial](https://appwrite.io/docs/functions). + /// + /// Use the "command" param to set the entrypoint used to execute your code. + pub async fn create_deployment( + &self, + function_id: impl Into, + code: InputFile, + activate: bool, + entrypoint: Option<&str>, + commands: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = entrypoint { + params.insert("entrypoint".to_string(), json!(value)); + } + if let Some(value) = commands { + params.insert("commands".to_string(), json!(value)); + } + params.insert("activate".to_string(), json!(activate)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "multipart/form-data".to_string()); + + let path = "/functions/{functionId}/deployments".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.file_upload(&path, Some(api_headers), params, "code", code, None).await + } + + /// Create a new build for an existing function deployment. This endpoint + /// allows you to rebuild a deployment with the updated function configuration, + /// including its entrypoint and build commands if they have been modified. The + /// build process will be queued and executed asynchronously. The original + /// deployment's code will be preserved and used for the new build. + pub async fn create_duplicate_deployment( + &self, + function_id: impl Into, + deployment_id: impl Into, + build_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("deploymentId".to_string(), json!(deployment_id.into())); + if let Some(value) = build_id { + params.insert("buildId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/deployments/duplicate".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a deployment based on a template. + /// + /// Use this endpoint with combination of + /// [listTemplates](https://appwrite.io/docs/products/functions/templates) to + /// find the template details. + #[allow(clippy::too_many_arguments)] + pub async fn create_template_deployment( + &self, + function_id: impl Into, + repository: impl Into, + owner: impl Into, + root_directory: impl Into, + r#type: crate::enums::TemplateReferenceType, + reference: impl Into, + activate: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("repository".to_string(), json!(repository.into())); + params.insert("owner".to_string(), json!(owner.into())); + params.insert("rootDirectory".to_string(), json!(root_directory.into())); + params.insert("type".to_string(), json!(r#type)); + params.insert("reference".to_string(), json!(reference.into())); + if let Some(value) = activate { + params.insert("activate".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/deployments/template".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a deployment when a function is connected to VCS. + /// + /// This endpoint lets you create deployment from a branch, commit, or a tag. + pub async fn create_vcs_deployment( + &self, + function_id: impl Into, + r#type: crate::enums::VCSReferenceType, + reference: impl Into, + activate: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("type".to_string(), json!(r#type)); + params.insert("reference".to_string(), json!(reference.into())); + if let Some(value) = activate { + params.insert("activate".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/deployments/vcs".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a function deployment by its unique ID. + pub async fn get_deployment( + &self, + function_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/{functionId}/deployments/{deploymentId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a code deployment by its unique ID. + pub async fn delete_deployment( + &self, + function_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/deployments/{deploymentId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a function deployment content by its unique ID. The endpoint response + /// return with a 'Content-Disposition: attachment' header that tells the + /// browser to start downloading the file to user downloads directory. + pub async fn get_deployment_download( + &self, + function_id: impl Into, + deployment_id: impl Into, + r#type: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = r#type { + params.insert("type".to_string(), json!(value)); + } + + let path = "/functions/{functionId}/deployments/{deploymentId}/download".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Cancel an ongoing function deployment build. If the build is already in + /// progress, it will be stopped and marked as canceled. If the build hasn't + /// started yet, it will be marked as canceled without executing. You cannot + /// cancel builds that have already completed (status 'ready') or failed. The + /// response includes the final build status and details. + pub async fn update_deployment_status( + &self, + function_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/deployments/{deploymentId}/status".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all the current user function execution logs. You can use the + /// query params to filter your results. + pub async fn list_executions( + &self, + function_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/functions/{functionId}/executions".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Trigger a function execution. The returned object will return you the + /// current execution status. You can ping the `Get Execution` endpoint to get + /// updates on the current execution status. Once this endpoint is called, your + /// function execution process will start asynchronously. + #[allow(clippy::too_many_arguments)] + pub async fn create_execution( + &self, + function_id: impl Into, + body: Option<&str>, + r#async: Option, + path: Option<&str>, + method: Option, + headers: Option, + scheduled_at: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = body { + params.insert("body".to_string(), json!(value)); + } + if let Some(value) = r#async { + params.insert("async".to_string(), json!(value)); + } + if let Some(value) = path { + params.insert("path".to_string(), json!(value)); + } + if let Some(value) = method { + params.insert("method".to_string(), json!(value)); + } + if let Some(value) = headers { + params.insert("headers".to_string(), json!(value)); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/executions".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a function execution log by its unique ID. + pub async fn get_execution( + &self, + function_id: impl Into, + execution_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/{functionId}/executions/{executionId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{executionId}", &execution_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a function execution by its unique ID. + pub async fn delete_execution( + &self, + function_id: impl Into, + execution_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/executions/{executionId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{executionId}", &execution_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all variables of a specific function. + pub async fn list_variables( + &self, + function_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/{functionId}/variables".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new function environment variable. These variables can be accessed + /// in the function at runtime as environment variables. + pub async fn create_variable( + &self, + function_id: impl Into, + key: impl Into, + value: impl Into, + secret: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("value".to_string(), json!(value.into())); + if let Some(value) = secret { + params.insert("secret".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/variables".to_string().replace("{functionId}", &function_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a variable by its unique ID. + pub async fn get_variable( + &self, + function_id: impl Into, + variable_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/functions/{functionId}/variables/{variableId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{variableId}", &variable_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update variable by its unique ID. + pub async fn update_variable( + &self, + function_id: impl Into, + variable_id: impl Into, + key: impl Into, + value: Option<&str>, + secret: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + if let Some(value) = value { + params.insert("value".to_string(), json!(value)); + } + if let Some(value) = secret { + params.insert("secret".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/variables/{variableId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{variableId}", &variable_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a variable by its unique ID. + pub async fn delete_variable( + &self, + function_id: impl Into, + variable_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/functions/{functionId}/variables/{variableId}".to_string().replace("{functionId}", &function_id.into().to_string()).replace("{variableId}", &variable_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Functions { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_functions_creation() { + let client = Client::new(); + let service = Functions::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/graphql.rs b/src/services/graphql.rs new file mode 100644 index 0000000..5b87308 --- /dev/null +++ b/src/services/graphql.rs @@ -0,0 +1,75 @@ +//! Graphql service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The GraphQL API allows you to query and mutate your Appwrite server using +/// GraphQL. +#[derive(Debug, Clone)] +pub struct Graphql { + client: Client, +} + +impl Graphql { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Execute a GraphQL mutation. + pub async fn query( + &self, + query: serde_json::Value, + ) -> crate::error::Result<()> { + let mut params = HashMap::new(); + params.insert("query".to_string(), json!(query)); + let mut api_headers = HashMap::new(); + api_headers.insert("x-sdk-graphql".to_string(), "true".to_string()); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/graphql".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Execute a GraphQL mutation. + pub async fn mutation( + &self, + query: serde_json::Value, + ) -> crate::error::Result<()> { + let mut params = HashMap::new(); + params.insert("query".to_string(), json!(query)); + let mut api_headers = HashMap::new(); + api_headers.insert("x-sdk-graphql".to_string(), "true".to_string()); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/graphql/mutation".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Graphql { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_graphql_creation() { + let client = Client::new(); + let service = Graphql::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/health.rs b/src/services/health.rs new file mode 100644 index 0000000..35cfa99 --- /dev/null +++ b/src/services/health.rs @@ -0,0 +1,477 @@ +//! Health service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Health service allows you to both validate and monitor your Appwrite +/// server's health. +#[derive(Debug, Clone)] +pub struct Health { + client: Client, +} + +impl Health { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Check the Appwrite HTTP server is up and responsive. + pub async fn get( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite Antivirus server is up and connection is successful. + pub async fn get_antivirus( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/anti-virus".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite in-memory cache servers are up and connection is + /// successful. + pub async fn get_cache( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/cache".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the SSL certificate for a domain + pub async fn get_certificate( + &self, + domain: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = domain { + params.insert("domain".to_string(), json!(value)); + } + + let path = "/health/certificate".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get console pausing health status. Monitors projects approaching the pause + /// threshold to detect potential issues with console access tracking. + pub async fn get_console_pausing( + &self, + threshold: Option, + inactivity_days: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + if let Some(value) = inactivity_days { + params.insert("inactivityDays".to_string(), json!(value)); + } + + let path = "/health/console-pausing".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite database servers are up and connection is successful. + pub async fn get_db( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/db".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite pub-sub servers are up and connection is successful. + pub async fn get_pub_sub( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/pubsub".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of audit logs that are waiting to be processed in the + /// Appwrite internal queue server. + pub async fn get_queue_audits( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/audits".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get billing project aggregation queue. + pub async fn get_queue_billing_project_aggregation( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/billing-project-aggregation".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get billing team aggregation queue. + pub async fn get_queue_billing_team_aggregation( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/billing-team-aggregation".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of builds that are waiting to be processed in the Appwrite + /// internal queue server. + pub async fn get_queue_builds( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/builds".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the priority builds queue size. + pub async fn get_queue_priority_builds( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/builds-priority".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of certificates that are waiting to be issued against + /// [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue + /// server. + pub async fn get_queue_certificates( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/certificates".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of database changes that are waiting to be processed in the + /// Appwrite internal queue server. + pub async fn get_queue_databases( + &self, + name: Option<&str>, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/databases".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of background destructive changes that are waiting to be + /// processed in the Appwrite internal queue server. + pub async fn get_queue_deletes( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/deletes".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Returns the amount of failed jobs in a given queue. + pub async fn get_failed_jobs( + &self, + name: crate::enums::Name, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/failed/{name}".to_string().replace("{name}", &name.to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of function executions that are waiting to be processed in + /// the Appwrite internal queue server. + pub async fn get_queue_functions( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/functions".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of logs that are waiting to be processed in the Appwrite + /// internal queue server. + pub async fn get_queue_logs( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/logs".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of mails that are waiting to be processed in the Appwrite + /// internal queue server. + pub async fn get_queue_mails( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/mails".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of messages that are waiting to be processed in the Appwrite + /// internal queue server. + pub async fn get_queue_messaging( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/messaging".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of migrations that are waiting to be processed in the + /// Appwrite internal queue server. + pub async fn get_queue_migrations( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/migrations".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get region manager queue. + pub async fn get_queue_region_manager( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/region-manager".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of metrics that are waiting to be processed in the Appwrite + /// stats resources queue. + pub async fn get_queue_stats_resources( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/stats-resources".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of metrics that are waiting to be processed in the Appwrite + /// internal queue server. + pub async fn get_queue_usage( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/stats-usage".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get threats queue. + pub async fn get_queue_threats( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/threats".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the number of webhooks that are waiting to be processed in the Appwrite + /// internal queue server. + pub async fn get_queue_webhooks( + &self, + threshold: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = threshold { + params.insert("threshold".to_string(), json!(value)); + } + + let path = "/health/queue/webhooks".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite storage device is up and connection is successful. + pub async fn get_storage( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/storage".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite local storage device is up and connection is successful. + pub async fn get_storage_local( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/storage/local".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Check the Appwrite server time is synced with Google remote NTP server. We + /// use this technology to smoothly handle leap seconds with no disruptive + /// events. The [Network Time + /// Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is + /// used by hundreds of millions of computers and devices to synchronize their + /// clocks over the Internet. If your computer sets its own clock, it likely + /// uses NTP. + pub async fn get_time( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/health/time".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + +} + +impl crate::services::Service for Health { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_health_creation() { + let client = Client::new(); + let service = Health::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/locale.rs b/src/services/locale.rs new file mode 100644 index 0000000..2f50c07 --- /dev/null +++ b/src/services/locale.rs @@ -0,0 +1,144 @@ +//! Locale service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; + +use std::collections::HashMap; + +/// The Locale service allows you to customize your app based on your users' +/// location. +#[derive(Debug, Clone)] +pub struct Locale { + client: Client, +} + +impl Locale { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get the current user location based on IP. Returns an object with user + /// country code, country name, continent name, continent code, ip address and + /// suggested currency. You can use the locale header to get the data in a + /// supported language. + /// + /// ([IP Geolocation by DB-IP](https://db-ip.com)) + pub async fn get( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all locale codes in [ISO + /// 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). + pub async fn list_codes( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/codes".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all continents. You can use the locale header to get the data in a + /// supported language. + pub async fn list_continents( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/continents".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all countries. You can use the locale header to get the data in a + /// supported language. + pub async fn list_countries( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/countries".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all countries that are currently members of the EU. You can use the + /// locale header to get the data in a supported language. + pub async fn list_countries_eu( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/countries/eu".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all countries phone codes. You can use the locale header to get the + /// data in a supported language. + pub async fn list_countries_phones( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/countries/phones".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all currencies, including currency symbol, name, plural, and + /// decimal digits for all major and minor currencies. You can use the locale + /// header to get the data in a supported language. + pub async fn list_currencies( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/currencies".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List of all languages classified by ISO 639-1 including 2-letter code, name + /// in English, and name in the respective language. + pub async fn list_languages( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/locale/languages".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + +} + +impl crate::services::Service for Locale { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_locale_creation() { + let client = Client::new(); + let service = Locale::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/messaging.rs b/src/services/messaging.rs new file mode 100644 index 0000000..b59ad60 --- /dev/null +++ b/src/services/messaging.rs @@ -0,0 +1,1650 @@ +//! Messaging service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Messaging service allows you to send messages to any provider type +/// (SMTP, push notification, SMS, etc.). +#[derive(Debug, Clone)] +pub struct Messaging { + client: Client, +} + +impl Messaging { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all messages from the current Appwrite project. + pub async fn list_messages( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/messages".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new email message. + #[allow(clippy::too_many_arguments)] + pub async fn create_email( + &self, + message_id: impl Into, + subject: impl Into, + content: impl Into, + topics: Option>, + users: Option>, + targets: Option>, + cc: Option>, + bcc: Option>, + attachments: Option>, + draft: Option, + html: Option, + scheduled_at: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("messageId".to_string(), json!(message_id.into())); + params.insert("subject".to_string(), json!(subject.into())); + params.insert("content".to_string(), json!(content.into())); + if let Some(value) = topics { + params.insert("topics".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = users { + params.insert("users".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = targets { + params.insert("targets".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = cc { + params.insert("cc".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = bcc { + params.insert("bcc".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = attachments { + params.insert("attachments".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = draft { + params.insert("draft".to_string(), json!(value)); + } + if let Some(value) = html { + params.insert("html".to_string(), json!(value)); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/email".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an email message by its unique ID. This endpoint only works on + /// messages that are in draft status. Messages that are already processing, + /// sent, or failed cannot be updated. + #[allow(clippy::too_many_arguments)] + pub async fn update_email( + &self, + message_id: impl Into, + topics: Option>, + users: Option>, + targets: Option>, + subject: Option<&str>, + content: Option<&str>, + draft: Option, + html: Option, + cc: Option>, + bcc: Option>, + scheduled_at: Option<&str>, + attachments: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = topics { + params.insert("topics".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = users { + params.insert("users".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = targets { + params.insert("targets".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = subject { + params.insert("subject".to_string(), json!(value)); + } + if let Some(value) = content { + params.insert("content".to_string(), json!(value)); + } + if let Some(value) = draft { + params.insert("draft".to_string(), json!(value)); + } + if let Some(value) = html { + params.insert("html".to_string(), json!(value)); + } + if let Some(value) = cc { + params.insert("cc".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = bcc { + params.insert("bcc".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + if let Some(value) = attachments { + params.insert("attachments".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/email/{messageId}".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new push notification. + #[allow(clippy::too_many_arguments)] + pub async fn create_push( + &self, + message_id: impl Into, + title: Option<&str>, + body: Option<&str>, + topics: Option>, + users: Option>, + targets: Option>, + data: Option, + action: Option<&str>, + image: Option<&str>, + icon: Option<&str>, + sound: Option<&str>, + color: Option<&str>, + tag: Option<&str>, + badge: Option, + draft: Option, + scheduled_at: Option<&str>, + content_available: Option, + critical: Option, + priority: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("messageId".to_string(), json!(message_id.into())); + if let Some(value) = title { + params.insert("title".to_string(), json!(value)); + } + if let Some(value) = body { + params.insert("body".to_string(), json!(value)); + } + if let Some(value) = topics { + params.insert("topics".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = users { + params.insert("users".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = targets { + params.insert("targets".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = action { + params.insert("action".to_string(), json!(value)); + } + if let Some(value) = image { + params.insert("image".to_string(), json!(value)); + } + if let Some(value) = icon { + params.insert("icon".to_string(), json!(value)); + } + if let Some(value) = sound { + params.insert("sound".to_string(), json!(value)); + } + if let Some(value) = color { + params.insert("color".to_string(), json!(value)); + } + if let Some(value) = tag { + params.insert("tag".to_string(), json!(value)); + } + if let Some(value) = badge { + params.insert("badge".to_string(), json!(value)); + } + if let Some(value) = draft { + params.insert("draft".to_string(), json!(value)); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + if let Some(value) = content_available { + params.insert("contentAvailable".to_string(), json!(value)); + } + if let Some(value) = critical { + params.insert("critical".to_string(), json!(value)); + } + if let Some(value) = priority { + params.insert("priority".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/push".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a push notification by its unique ID. This endpoint only works on + /// messages that are in draft status. Messages that are already processing, + /// sent, or failed cannot be updated. + #[allow(clippy::too_many_arguments)] + pub async fn update_push( + &self, + message_id: impl Into, + topics: Option>, + users: Option>, + targets: Option>, + title: Option<&str>, + body: Option<&str>, + data: Option, + action: Option<&str>, + image: Option<&str>, + icon: Option<&str>, + sound: Option<&str>, + color: Option<&str>, + tag: Option<&str>, + badge: Option, + draft: Option, + scheduled_at: Option<&str>, + content_available: Option, + critical: Option, + priority: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = topics { + params.insert("topics".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = users { + params.insert("users".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = targets { + params.insert("targets".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = title { + params.insert("title".to_string(), json!(value)); + } + if let Some(value) = body { + params.insert("body".to_string(), json!(value)); + } + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = action { + params.insert("action".to_string(), json!(value)); + } + if let Some(value) = image { + params.insert("image".to_string(), json!(value)); + } + if let Some(value) = icon { + params.insert("icon".to_string(), json!(value)); + } + if let Some(value) = sound { + params.insert("sound".to_string(), json!(value)); + } + if let Some(value) = color { + params.insert("color".to_string(), json!(value)); + } + if let Some(value) = tag { + params.insert("tag".to_string(), json!(value)); + } + if let Some(value) = badge { + params.insert("badge".to_string(), json!(value)); + } + if let Some(value) = draft { + params.insert("draft".to_string(), json!(value)); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + if let Some(value) = content_available { + params.insert("contentAvailable".to_string(), json!(value)); + } + if let Some(value) = critical { + params.insert("critical".to_string(), json!(value)); + } + if let Some(value) = priority { + params.insert("priority".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/push/{messageId}".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new SMS message. + #[allow(clippy::too_many_arguments)] + pub async fn create_sms( + &self, + message_id: impl Into, + content: impl Into, + topics: Option>, + users: Option>, + targets: Option>, + draft: Option, + scheduled_at: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("messageId".to_string(), json!(message_id.into())); + params.insert("content".to_string(), json!(content.into())); + if let Some(value) = topics { + params.insert("topics".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = users { + params.insert("users".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = targets { + params.insert("targets".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = draft { + params.insert("draft".to_string(), json!(value)); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/sms".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an SMS message by its unique ID. This endpoint only works on + /// messages that are in draft status. Messages that are already processing, + /// sent, or failed cannot be updated. + #[allow(clippy::too_many_arguments)] + pub async fn update_sms( + &self, + message_id: impl Into, + topics: Option>, + users: Option>, + targets: Option>, + content: Option<&str>, + draft: Option, + scheduled_at: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = topics { + params.insert("topics".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = users { + params.insert("users".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = targets { + params.insert("targets".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = content { + params.insert("content".to_string(), json!(value)); + } + if let Some(value) = draft { + params.insert("draft".to_string(), json!(value)); + } + if let Some(value) = scheduled_at { + params.insert("scheduledAt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/sms/{messageId}".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get a message by its unique ID. + pub async fn get_message( + &self, + message_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/messaging/messages/{messageId}".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a message. If the message is not a draft or scheduled, but has been + /// sent, this will not recall the message. + pub async fn delete( + &self, + message_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/messages/{messageId}".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get the message activity logs listed by its unique ID. + pub async fn list_message_logs( + &self, + message_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/messages/{messageId}/logs".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a list of the targets associated with a message. + pub async fn list_targets( + &self, + message_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/messages/{messageId}/targets".to_string().replace("{messageId}", &message_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a list of all providers from the current Appwrite project. + pub async fn list_providers( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/providers".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Apple Push Notification service provider. + #[allow(clippy::too_many_arguments)] + pub async fn create_apns_provider( + &self, + provider_id: impl Into, + name: impl Into, + auth_key: Option<&str>, + auth_key_id: Option<&str>, + team_id: Option<&str>, + bundle_id: Option<&str>, + sandbox: Option, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = auth_key { + params.insert("authKey".to_string(), json!(value)); + } + if let Some(value) = auth_key_id { + params.insert("authKeyId".to_string(), json!(value)); + } + if let Some(value) = team_id { + params.insert("teamId".to_string(), json!(value)); + } + if let Some(value) = bundle_id { + params.insert("bundleId".to_string(), json!(value)); + } + if let Some(value) = sandbox { + params.insert("sandbox".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/apns".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Apple Push Notification service provider by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update_apns_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + auth_key: Option<&str>, + auth_key_id: Option<&str>, + team_id: Option<&str>, + bundle_id: Option<&str>, + sandbox: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = auth_key { + params.insert("authKey".to_string(), json!(value)); + } + if let Some(value) = auth_key_id { + params.insert("authKeyId".to_string(), json!(value)); + } + if let Some(value) = team_id { + params.insert("teamId".to_string(), json!(value)); + } + if let Some(value) = bundle_id { + params.insert("bundleId".to_string(), json!(value)); + } + if let Some(value) = sandbox { + params.insert("sandbox".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/apns/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Firebase Cloud Messaging provider. + pub async fn create_fcm_provider( + &self, + provider_id: impl Into, + name: impl Into, + service_account_json: Option, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = service_account_json { + params.insert("serviceAccountJSON".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/fcm".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Firebase Cloud Messaging provider by its unique ID. + pub async fn update_fcm_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + service_account_json: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = service_account_json { + params.insert("serviceAccountJSON".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/fcm/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Mailgun provider. + #[allow(clippy::too_many_arguments)] + pub async fn create_mailgun_provider( + &self, + provider_id: impl Into, + name: impl Into, + api_key: Option<&str>, + domain: Option<&str>, + is_eu_region: Option, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = domain { + params.insert("domain".to_string(), json!(value)); + } + if let Some(value) = is_eu_region { + params.insert("isEuRegion".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/mailgun".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Mailgun provider by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update_mailgun_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + api_key: Option<&str>, + domain: Option<&str>, + is_eu_region: Option, + enabled: Option, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = domain { + params.insert("domain".to_string(), json!(value)); + } + if let Some(value) = is_eu_region { + params.insert("isEuRegion".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/mailgun/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new MSG91 provider. + pub async fn create_msg91_provider( + &self, + provider_id: impl Into, + name: impl Into, + template_id: Option<&str>, + sender_id: Option<&str>, + auth_key: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = template_id { + params.insert("templateId".to_string(), json!(value)); + } + if let Some(value) = sender_id { + params.insert("senderId".to_string(), json!(value)); + } + if let Some(value) = auth_key { + params.insert("authKey".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/msg91".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a MSG91 provider by its unique ID. + pub async fn update_msg91_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + template_id: Option<&str>, + sender_id: Option<&str>, + auth_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = template_id { + params.insert("templateId".to_string(), json!(value)); + } + if let Some(value) = sender_id { + params.insert("senderId".to_string(), json!(value)); + } + if let Some(value) = auth_key { + params.insert("authKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/msg91/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Resend provider. + #[allow(clippy::too_many_arguments)] + pub async fn create_resend_provider( + &self, + provider_id: impl Into, + name: impl Into, + api_key: Option<&str>, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/resend".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Resend provider by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update_resend_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + api_key: Option<&str>, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/resend/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Sendgrid provider. + #[allow(clippy::too_many_arguments)] + pub async fn create_sendgrid_provider( + &self, + provider_id: impl Into, + name: impl Into, + api_key: Option<&str>, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/sendgrid".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Sendgrid provider by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update_sendgrid_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + api_key: Option<&str>, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/sendgrid/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new SMTP provider. + #[allow(clippy::too_many_arguments)] + pub async fn create_smtp_provider( + &self, + provider_id: impl Into, + name: impl Into, + host: impl Into, + port: Option, + username: Option<&str>, + password: Option<&str>, + encryption: Option, + auto_tls: Option, + mailer: Option<&str>, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + params.insert("host".to_string(), json!(host.into())); + if let Some(value) = port { + params.insert("port".to_string(), json!(value)); + } + if let Some(value) = username { + params.insert("username".to_string(), json!(value)); + } + if let Some(value) = password { + params.insert("password".to_string(), json!(value)); + } + if let Some(value) = encryption { + params.insert("encryption".to_string(), json!(value)); + } + if let Some(value) = auto_tls { + params.insert("autoTLS".to_string(), json!(value)); + } + if let Some(value) = mailer { + params.insert("mailer".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/smtp".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a SMTP provider by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update_smtp_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + host: Option<&str>, + port: Option, + username: Option<&str>, + password: Option<&str>, + encryption: Option, + auto_tls: Option, + mailer: Option<&str>, + from_name: Option<&str>, + from_email: Option<&str>, + reply_to_name: Option<&str>, + reply_to_email: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = host { + params.insert("host".to_string(), json!(value)); + } + if let Some(value) = port { + params.insert("port".to_string(), json!(value)); + } + if let Some(value) = username { + params.insert("username".to_string(), json!(value)); + } + if let Some(value) = password { + params.insert("password".to_string(), json!(value)); + } + if let Some(value) = encryption { + params.insert("encryption".to_string(), json!(value)); + } + if let Some(value) = auto_tls { + params.insert("autoTLS".to_string(), json!(value)); + } + if let Some(value) = mailer { + params.insert("mailer".to_string(), json!(value)); + } + if let Some(value) = from_name { + params.insert("fromName".to_string(), json!(value)); + } + if let Some(value) = from_email { + params.insert("fromEmail".to_string(), json!(value)); + } + if let Some(value) = reply_to_name { + params.insert("replyToName".to_string(), json!(value)); + } + if let Some(value) = reply_to_email { + params.insert("replyToEmail".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/smtp/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Telesign provider. + pub async fn create_telesign_provider( + &self, + provider_id: impl Into, + name: impl Into, + from: Option<&str>, + customer_id: Option<&str>, + api_key: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + if let Some(value) = customer_id { + params.insert("customerId".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/telesign".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Telesign provider by its unique ID. + pub async fn update_telesign_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + customer_id: Option<&str>, + api_key: Option<&str>, + from: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = customer_id { + params.insert("customerId".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/telesign/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Textmagic provider. + pub async fn create_textmagic_provider( + &self, + provider_id: impl Into, + name: impl Into, + from: Option<&str>, + username: Option<&str>, + api_key: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + if let Some(value) = username { + params.insert("username".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/textmagic".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Textmagic provider by its unique ID. + pub async fn update_textmagic_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + username: Option<&str>, + api_key: Option<&str>, + from: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = username { + params.insert("username".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/textmagic/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Twilio provider. + pub async fn create_twilio_provider( + &self, + provider_id: impl Into, + name: impl Into, + from: Option<&str>, + account_sid: Option<&str>, + auth_token: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + if let Some(value) = account_sid { + params.insert("accountSid".to_string(), json!(value)); + } + if let Some(value) = auth_token { + params.insert("authToken".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/twilio".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Twilio provider by its unique ID. + pub async fn update_twilio_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + account_sid: Option<&str>, + auth_token: Option<&str>, + from: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = account_sid { + params.insert("accountSid".to_string(), json!(value)); + } + if let Some(value) = auth_token { + params.insert("authToken".to_string(), json!(value)); + } + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/twilio/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a new Vonage provider. + pub async fn create_vonage_provider( + &self, + provider_id: impl Into, + name: impl Into, + from: Option<&str>, + api_key: Option<&str>, + api_secret: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("providerId".to_string(), json!(provider_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = api_secret { + params.insert("apiSecret".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/vonage".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a Vonage provider by its unique ID. + pub async fn update_vonage_provider( + &self, + provider_id: impl Into, + name: Option<&str>, + enabled: Option, + api_key: Option<&str>, + api_secret: Option<&str>, + from: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = api_key { + params.insert("apiKey".to_string(), json!(value)); + } + if let Some(value) = api_secret { + params.insert("apiSecret".to_string(), json!(value)); + } + if let Some(value) = from { + params.insert("from".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/vonage/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get a provider by its unique ID. + pub async fn get_provider( + &self, + provider_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/messaging/providers/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a provider by its unique ID. + pub async fn delete_provider( + &self, + provider_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/providers/{providerId}".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get the provider activity logs listed by its unique ID. + pub async fn list_provider_logs( + &self, + provider_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/providers/{providerId}/logs".to_string().replace("{providerId}", &provider_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the subscriber activity logs listed by its unique ID. + pub async fn list_subscriber_logs( + &self, + subscriber_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/subscribers/{subscriberId}/logs".to_string().replace("{subscriberId}", &subscriber_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a list of all topics from the current Appwrite project. + pub async fn list_topics( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/topics".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new topic. + pub async fn create_topic( + &self, + topic_id: impl Into, + name: impl Into, + subscribe: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("topicId".to_string(), json!(topic_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = subscribe { + params.insert("subscribe".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/topics".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a topic by its unique ID. + pub async fn get_topic( + &self, + topic_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/messaging/topics/{topicId}".to_string().replace("{topicId}", &topic_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a topic by its unique ID. + pub async fn update_topic( + &self, + topic_id: impl Into, + name: Option<&str>, + subscribe: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = subscribe { + params.insert("subscribe".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/topics/{topicId}".to_string().replace("{topicId}", &topic_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a topic by its unique ID. + pub async fn delete_topic( + &self, + topic_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/topics/{topicId}".to_string().replace("{topicId}", &topic_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get the topic activity logs listed by its unique ID. + pub async fn list_topic_logs( + &self, + topic_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/topics/{topicId}/logs".to_string().replace("{topicId}", &topic_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a list of all subscribers from the current Appwrite project. + pub async fn list_subscribers( + &self, + topic_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/messaging/topics/{topicId}/subscribers".to_string().replace("{topicId}", &topic_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new subscriber. + pub async fn create_subscriber( + &self, + topic_id: impl Into, + subscriber_id: impl Into, + target_id: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("subscriberId".to_string(), json!(subscriber_id.into())); + params.insert("targetId".to_string(), json!(target_id.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/topics/{topicId}/subscribers".to_string().replace("{topicId}", &topic_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a subscriber by its unique ID. + pub async fn get_subscriber( + &self, + topic_id: impl Into, + subscriber_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/messaging/topics/{topicId}/subscribers/{subscriberId}".to_string().replace("{topicId}", &topic_id.into().to_string()).replace("{subscriberId}", &subscriber_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a subscriber by its unique ID. + pub async fn delete_subscriber( + &self, + topic_id: impl Into, + subscriber_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/messaging/topics/{topicId}/subscribers/{subscriberId}".to_string().replace("{topicId}", &topic_id.into().to_string()).replace("{subscriberId}", &subscriber_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Messaging { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_messaging_creation() { + let client = Client::new(); + let service = Messaging::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/mod.rs b/src/services/mod.rs new file mode 100644 index 0000000..5ed69ab --- /dev/null +++ b/src/services/mod.rs @@ -0,0 +1,166 @@ +//! Service modules for Appwrite SDK + +pub mod account; +pub use account::Account; +pub mod activities; +pub use activities::Activities; +pub mod avatars; +pub use avatars::Avatars; +pub mod backups; +pub use backups::Backups; +pub mod databases; +pub use databases::Databases; +pub mod functions; +pub use functions::Functions; +pub mod graphql; +pub use graphql::Graphql; +pub mod health; +pub use health::Health; +pub mod locale; +pub use locale::Locale; +pub mod messaging; +pub use messaging::Messaging; +pub mod sites; +pub use sites::Sites; +pub mod storage; +pub use storage::Storage; +pub mod tables_db; +pub use tables_db::TablesDB; +pub mod teams; +pub use teams::Teams; +pub mod tokens; +pub use tokens::Tokens; +pub mod users; +pub use users::Users; +pub mod webhooks; +pub use webhooks::Webhooks; + +use crate::client::Client; + +/// Base trait for all Appwrite services +pub trait Service { + /// Get a reference to the client + fn client(&self) -> &Client; +} + +// Re-export all services for convenience +pub struct Services { + client: Client, + account: Account, + activities: Activities, + avatars: Avatars, + backups: Backups, + databases: Databases, + functions: Functions, + graphql: Graphql, + health: Health, + locale: Locale, + messaging: Messaging, + sites: Sites, + storage: Storage, + tables_db: TablesDB, + teams: Teams, + tokens: Tokens, + users: Users, + webhooks: Webhooks, +} + +impl Services { + /// Create new services instance + pub fn new(client: Client) -> Self { + Self { + account: Account::new(&client), + activities: Activities::new(&client), + avatars: Avatars::new(&client), + backups: Backups::new(&client), + databases: Databases::new(&client), + functions: Functions::new(&client), + graphql: Graphql::new(&client), + health: Health::new(&client), + locale: Locale::new(&client), + messaging: Messaging::new(&client), + sites: Sites::new(&client), + storage: Storage::new(&client), + tables_db: TablesDB::new(&client), + teams: Teams::new(&client), + tokens: Tokens::new(&client), + users: Users::new(&client), + webhooks: Webhooks::new(&client), + client, + } + } + + /// Get client reference + pub fn client(&self) -> &Client { + &self.client + } + + /// Get Account service + pub fn account(&self) -> &Account { + &self.account + } + /// Get Activities service + pub fn activities(&self) -> &Activities { + &self.activities + } + /// Get Avatars service + pub fn avatars(&self) -> &Avatars { + &self.avatars + } + /// Get Backups service + pub fn backups(&self) -> &Backups { + &self.backups + } + /// Get Databases service + pub fn databases(&self) -> &Databases { + &self.databases + } + /// Get Functions service + pub fn functions(&self) -> &Functions { + &self.functions + } + /// Get Graphql service + pub fn graphql(&self) -> &Graphql { + &self.graphql + } + /// Get Health service + pub fn health(&self) -> &Health { + &self.health + } + /// Get Locale service + pub fn locale(&self) -> &Locale { + &self.locale + } + /// Get Messaging service + pub fn messaging(&self) -> &Messaging { + &self.messaging + } + /// Get Sites service + pub fn sites(&self) -> &Sites { + &self.sites + } + /// Get Storage service + pub fn storage(&self) -> &Storage { + &self.storage + } + /// Get TablesDB service + pub fn tables_db(&self) -> &TablesDB { + &self.tables_db + } + /// Get Teams service + pub fn teams(&self) -> &Teams { + &self.teams + } + /// Get Tokens service + pub fn tokens(&self) -> &Tokens { + &self.tokens + } + /// Get Users service + pub fn users(&self) -> &Users { + &self.users + } + /// Get Webhooks service + pub fn webhooks(&self) -> &Webhooks { + &self.webhooks + } +} diff --git a/src/services/sites.rs b/src/services/sites.rs new file mode 100644 index 0000000..12b8422 --- /dev/null +++ b/src/services/sites.rs @@ -0,0 +1,651 @@ +//! Sites service for Appwrite SDK + +use crate::client::Client; +use crate::input_file::InputFile; +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Sites Service allows you view, create and manage your web applications. +#[derive(Debug, Clone)] +pub struct Sites { + client: Client, +} + +impl Sites { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all the project's sites. You can use the query params to + /// filter your results. + pub async fn list( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/sites".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new site. + #[allow(clippy::too_many_arguments)] + pub async fn create( + &self, + site_id: impl Into, + name: impl Into, + framework: crate::enums::Framework, + build_runtime: crate::enums::BuildRuntime, + enabled: Option, + logging: Option, + timeout: Option, + install_command: Option<&str>, + build_command: Option<&str>, + start_command: Option<&str>, + output_directory: Option<&str>, + adapter: Option, + installation_id: Option<&str>, + fallback_file: Option<&str>, + provider_repository_id: Option<&str>, + provider_branch: Option<&str>, + provider_silent_mode: Option, + provider_root_directory: Option<&str>, + build_specification: Option<&str>, + runtime_specification: Option<&str>, + deployment_retention: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("siteId".to_string(), json!(site_id.into())); + params.insert("name".to_string(), json!(name.into())); + params.insert("framework".to_string(), json!(framework)); + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = logging { + params.insert("logging".to_string(), json!(value)); + } + if let Some(value) = timeout { + params.insert("timeout".to_string(), json!(value)); + } + if let Some(value) = install_command { + params.insert("installCommand".to_string(), json!(value)); + } + if let Some(value) = build_command { + params.insert("buildCommand".to_string(), json!(value)); + } + if let Some(value) = start_command { + params.insert("startCommand".to_string(), json!(value)); + } + if let Some(value) = output_directory { + params.insert("outputDirectory".to_string(), json!(value)); + } + params.insert("buildRuntime".to_string(), json!(build_runtime)); + if let Some(value) = adapter { + params.insert("adapter".to_string(), json!(value)); + } + if let Some(value) = installation_id { + params.insert("installationId".to_string(), json!(value)); + } + if let Some(value) = fallback_file { + params.insert("fallbackFile".to_string(), json!(value)); + } + if let Some(value) = provider_repository_id { + params.insert("providerRepositoryId".to_string(), json!(value)); + } + if let Some(value) = provider_branch { + params.insert("providerBranch".to_string(), json!(value)); + } + if let Some(value) = provider_silent_mode { + params.insert("providerSilentMode".to_string(), json!(value)); + } + if let Some(value) = provider_root_directory { + params.insert("providerRootDirectory".to_string(), json!(value)); + } + if let Some(value) = build_specification { + params.insert("buildSpecification".to_string(), json!(value)); + } + if let Some(value) = runtime_specification { + params.insert("runtimeSpecification".to_string(), json!(value)); + } + if let Some(value) = deployment_retention { + params.insert("deploymentRetention".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all frameworks that are currently available on the server + /// instance. + pub async fn list_frameworks( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/frameworks".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// List allowed site specifications for this instance. + pub async fn list_specifications( + &self, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/specifications".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a site by its unique ID. + pub async fn get( + &self, + site_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/{siteId}".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update site by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update( + &self, + site_id: impl Into, + name: impl Into, + framework: crate::enums::Framework, + enabled: Option, + logging: Option, + timeout: Option, + install_command: Option<&str>, + build_command: Option<&str>, + start_command: Option<&str>, + output_directory: Option<&str>, + build_runtime: Option, + adapter: Option, + fallback_file: Option<&str>, + installation_id: Option<&str>, + provider_repository_id: Option<&str>, + provider_branch: Option<&str>, + provider_silent_mode: Option, + provider_root_directory: Option<&str>, + build_specification: Option<&str>, + runtime_specification: Option<&str>, + deployment_retention: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + params.insert("framework".to_string(), json!(framework)); + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = logging { + params.insert("logging".to_string(), json!(value)); + } + if let Some(value) = timeout { + params.insert("timeout".to_string(), json!(value)); + } + if let Some(value) = install_command { + params.insert("installCommand".to_string(), json!(value)); + } + if let Some(value) = build_command { + params.insert("buildCommand".to_string(), json!(value)); + } + if let Some(value) = start_command { + params.insert("startCommand".to_string(), json!(value)); + } + if let Some(value) = output_directory { + params.insert("outputDirectory".to_string(), json!(value)); + } + if let Some(value) = build_runtime { + params.insert("buildRuntime".to_string(), json!(value)); + } + if let Some(value) = adapter { + params.insert("adapter".to_string(), json!(value)); + } + if let Some(value) = fallback_file { + params.insert("fallbackFile".to_string(), json!(value)); + } + if let Some(value) = installation_id { + params.insert("installationId".to_string(), json!(value)); + } + if let Some(value) = provider_repository_id { + params.insert("providerRepositoryId".to_string(), json!(value)); + } + if let Some(value) = provider_branch { + params.insert("providerBranch".to_string(), json!(value)); + } + if let Some(value) = provider_silent_mode { + params.insert("providerSilentMode".to_string(), json!(value)); + } + if let Some(value) = provider_root_directory { + params.insert("providerRootDirectory".to_string(), json!(value)); + } + if let Some(value) = build_specification { + params.insert("buildSpecification".to_string(), json!(value)); + } + if let Some(value) = runtime_specification { + params.insert("runtimeSpecification".to_string(), json!(value)); + } + if let Some(value) = deployment_retention { + params.insert("deploymentRetention".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a site by its unique ID. + pub async fn delete( + &self, + site_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Update the site active deployment. Use this endpoint to switch the code + /// deployment that should be used when visitor opens your site. + pub async fn update_site_deployment( + &self, + site_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("deploymentId".to_string(), json!(deployment_id.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/deployment".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all the site's code deployments. You can use the query params + /// to filter your results. + pub async fn list_deployments( + &self, + site_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/sites/{siteId}/deployments".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new site code deployment. Use this endpoint to upload a new + /// version of your site code. To activate your newly uploaded code, you'll + /// need to update the site's deployment to use your new deployment ID. + pub async fn create_deployment( + &self, + site_id: impl Into, + code: InputFile, + install_command: Option<&str>, + build_command: Option<&str>, + output_directory: Option<&str>, + activate: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = install_command { + params.insert("installCommand".to_string(), json!(value)); + } + if let Some(value) = build_command { + params.insert("buildCommand".to_string(), json!(value)); + } + if let Some(value) = output_directory { + params.insert("outputDirectory".to_string(), json!(value)); + } + if let Some(value) = activate { + params.insert("activate".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "multipart/form-data".to_string()); + + let path = "/sites/{siteId}/deployments".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.file_upload(&path, Some(api_headers), params, "code", code, None).await + } + + /// Create a new build for an existing site deployment. This endpoint allows + /// you to rebuild a deployment with the updated site configuration, including + /// its commands and output directory if they have been modified. The build + /// process will be queued and executed asynchronously. The original + /// deployment's code will be preserved and used for the new build. + pub async fn create_duplicate_deployment( + &self, + site_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("deploymentId".to_string(), json!(deployment_id.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/deployments/duplicate".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a deployment based on a template. + /// + /// Use this endpoint with combination of + /// [listTemplates](https://appwrite.io/docs/products/sites/templates) to find + /// the template details. + #[allow(clippy::too_many_arguments)] + pub async fn create_template_deployment( + &self, + site_id: impl Into, + repository: impl Into, + owner: impl Into, + root_directory: impl Into, + r#type: crate::enums::TemplateReferenceType, + reference: impl Into, + activate: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("repository".to_string(), json!(repository.into())); + params.insert("owner".to_string(), json!(owner.into())); + params.insert("rootDirectory".to_string(), json!(root_directory.into())); + params.insert("type".to_string(), json!(r#type)); + params.insert("reference".to_string(), json!(reference.into())); + if let Some(value) = activate { + params.insert("activate".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/deployments/template".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a deployment when a site is connected to VCS. + /// + /// This endpoint lets you create deployment from a branch, commit, or a tag. + pub async fn create_vcs_deployment( + &self, + site_id: impl Into, + r#type: crate::enums::VCSReferenceType, + reference: impl Into, + activate: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("type".to_string(), json!(r#type)); + params.insert("reference".to_string(), json!(reference.into())); + if let Some(value) = activate { + params.insert("activate".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/deployments/vcs".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a site deployment by its unique ID. + pub async fn get_deployment( + &self, + site_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/{siteId}/deployments/{deploymentId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a site deployment by its unique ID. + pub async fn delete_deployment( + &self, + site_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/deployments/{deploymentId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a site deployment content by its unique ID. The endpoint response + /// return with a 'Content-Disposition: attachment' header that tells the + /// browser to start downloading the file to user downloads directory. + pub async fn get_deployment_download( + &self, + site_id: impl Into, + deployment_id: impl Into, + r#type: Option, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = r#type { + params.insert("type".to_string(), json!(value)); + } + + let path = "/sites/{siteId}/deployments/{deploymentId}/download".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Cancel an ongoing site deployment build. If the build is already in + /// progress, it will be stopped and marked as canceled. If the build hasn't + /// started yet, it will be marked as canceled without executing. You cannot + /// cancel builds that have already completed (status 'ready') or failed. The + /// response includes the final build status and details. + pub async fn update_deployment_status( + &self, + site_id: impl Into, + deployment_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/deployments/{deploymentId}/status".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{deploymentId}", &deployment_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all site logs. You can use the query params to filter your + /// results. + pub async fn list_logs( + &self, + site_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/sites/{siteId}/logs".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get a site request log by its unique ID. + pub async fn get_log( + &self, + site_id: impl Into, + log_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/{siteId}/logs/{logId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{logId}", &log_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a site log by its unique ID. + pub async fn delete_log( + &self, + site_id: impl Into, + log_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/logs/{logId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{logId}", &log_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all variables of a specific site. + pub async fn list_variables( + &self, + site_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/{siteId}/variables".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new site variable. These variables can be accessed during build + /// and runtime (server-side rendering) as environment variables. + pub async fn create_variable( + &self, + site_id: impl Into, + key: impl Into, + value: impl Into, + secret: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("value".to_string(), json!(value.into())); + if let Some(value) = secret { + params.insert("secret".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/variables".to_string().replace("{siteId}", &site_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a variable by its unique ID. + pub async fn get_variable( + &self, + site_id: impl Into, + variable_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/sites/{siteId}/variables/{variableId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{variableId}", &variable_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update variable by its unique ID. + pub async fn update_variable( + &self, + site_id: impl Into, + variable_id: impl Into, + key: impl Into, + value: Option<&str>, + secret: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + if let Some(value) = value { + params.insert("value".to_string(), json!(value)); + } + if let Some(value) = secret { + params.insert("secret".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/variables/{variableId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{variableId}", &variable_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a variable by its unique ID. + pub async fn delete_variable( + &self, + site_id: impl Into, + variable_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/sites/{siteId}/variables/{variableId}".to_string().replace("{siteId}", &site_id.into().to_string()).replace("{variableId}", &variable_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Sites { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sites_creation() { + let client = Client::new(); + let service = Sites::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/storage.rs b/src/services/storage.rs new file mode 100644 index 0000000..77be17f --- /dev/null +++ b/src/services/storage.rs @@ -0,0 +1,421 @@ +//! Storage service for Appwrite SDK + +use crate::client::Client; +use crate::input_file::InputFile; +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Storage service allows you to manage your project files. +#[derive(Debug, Clone)] +pub struct Storage { + client: Client, +} + +impl Storage { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all the storage buckets. You can use the query params to + /// filter your results. + pub async fn list_buckets( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/storage/buckets".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new storage bucket. + #[allow(clippy::too_many_arguments)] + pub async fn create_bucket( + &self, + bucket_id: impl Into, + name: impl Into, + permissions: Option>, + file_security: Option, + enabled: Option, + maximum_file_size: Option, + allowed_file_extensions: Option>, + compression: Option, + encryption: Option, + antivirus: Option, + transformations: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("bucketId".to_string(), json!(bucket_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = file_security { + params.insert("fileSecurity".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = maximum_file_size { + params.insert("maximumFileSize".to_string(), json!(value)); + } + if let Some(value) = allowed_file_extensions { + params.insert("allowedFileExtensions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = compression { + params.insert("compression".to_string(), json!(value)); + } + if let Some(value) = encryption { + params.insert("encryption".to_string(), json!(value)); + } + if let Some(value) = antivirus { + params.insert("antivirus".to_string(), json!(value)); + } + if let Some(value) = transformations { + params.insert("transformations".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/storage/buckets".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a storage bucket by its unique ID. This endpoint response returns a + /// JSON object with the storage bucket metadata. + pub async fn get_bucket( + &self, + bucket_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/storage/buckets/{bucketId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a storage bucket by its unique ID. + #[allow(clippy::too_many_arguments)] + pub async fn update_bucket( + &self, + bucket_id: impl Into, + name: impl Into, + permissions: Option>, + file_security: Option, + enabled: Option, + maximum_file_size: Option, + allowed_file_extensions: Option>, + compression: Option, + encryption: Option, + antivirus: Option, + transformations: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = file_security { + params.insert("fileSecurity".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = maximum_file_size { + params.insert("maximumFileSize".to_string(), json!(value)); + } + if let Some(value) = allowed_file_extensions { + params.insert("allowedFileExtensions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = compression { + params.insert("compression".to_string(), json!(value)); + } + if let Some(value) = encryption { + params.insert("encryption".to_string(), json!(value)); + } + if let Some(value) = antivirus { + params.insert("antivirus".to_string(), json!(value)); + } + if let Some(value) = transformations { + params.insert("transformations".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/storage/buckets/{bucketId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a storage bucket by its unique ID. + pub async fn delete_bucket( + &self, + bucket_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/storage/buckets/{bucketId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all the user files. You can use the query params to filter + /// your results. + pub async fn list_files( + &self, + bucket_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/storage/buckets/{bucketId}/files".to_string().replace("{bucketId}", &bucket_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new file. Before using this route, you should create a new bucket + /// resource using either a [server + /// integration](https://appwrite.io/docs/server/storage#storageCreateBucket) + /// API or directly from your Appwrite console. + /// + /// Larger files should be uploaded using multiple requests with the + /// [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) + /// header to send a partial request with a maximum supported chunk of `5MB`. + /// The `content-range` header values should always be in bytes. + /// + /// When the first request is sent, the server will return the **File** object, + /// and the subsequent part request must include the file's **id** in + /// `x-appwrite-id` header to allow the server to know that the partial upload + /// is for the existing file and not for a new one. + /// + /// If you're creating a new file using one of the Appwrite SDKs, all the + /// chunking logic will be managed by the SDK internally. + pub async fn create_file( + &self, + bucket_id: impl Into, + file_id: impl Into, + file: InputFile, + permissions: Option>, + ) -> crate::error::Result { + let file_id_str = file_id.into(); + let mut params = HashMap::new(); + params.insert("fileId".to_string(), json!(file_id_str)); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "multipart/form-data".to_string()); + + let path = "/storage/buckets/{bucketId}/files".to_string().replace("{bucketId}", &bucket_id.into().to_string()); + + self.client.file_upload(&path, Some(api_headers), params, "file", file, Some(file_id_str)).await + } + + /// Get a file by its unique ID. This endpoint response returns a JSON object + /// with the file metadata. + pub async fn get_file( + &self, + bucket_id: impl Into, + file_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/storage/buckets/{bucketId}/files/{fileId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a file by its unique ID. Only users with write permissions have + /// access to update this resource. + pub async fn update_file( + &self, + bucket_id: impl Into, + file_id: impl Into, + name: Option<&str>, + permissions: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/storage/buckets/{bucketId}/files/{fileId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a file by its unique ID. Only users with write permissions have + /// access to delete this resource. + pub async fn delete_file( + &self, + bucket_id: impl Into, + file_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/storage/buckets/{bucketId}/files/{fileId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a file content by its unique ID. The endpoint response return with a + /// 'Content-Disposition: attachment' header that tells the browser to start + /// downloading the file to user downloads directory. + pub async fn get_file_download( + &self, + bucket_id: impl Into, + file_id: impl Into, + token: Option<&str>, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = token { + params.insert("token".to_string(), json!(value)); + } + + let path = "/storage/buckets/{bucketId}/files/{fileId}/download".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Get a file preview image. Currently, this method supports preview for image + /// files (jpg, png, and gif), other supported formats, like pdf, docs, slides, + /// and spreadsheets, will return the file icon image. You can also pass query + /// string arguments for cutting and resizing your preview image. Preview is + /// supported only for image files smaller than 10MB. + #[allow(clippy::too_many_arguments)] + pub async fn get_file_preview( + &self, + bucket_id: impl Into, + file_id: impl Into, + width: Option, + height: Option, + gravity: Option, + quality: Option, + border_width: Option, + border_color: Option<&str>, + border_radius: Option, + opacity: Option, + rotation: Option, + background: Option<&str>, + output: Option, + token: Option<&str>, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = width { + params.insert("width".to_string(), json!(value)); + } + if let Some(value) = height { + params.insert("height".to_string(), json!(value)); + } + if let Some(value) = gravity { + params.insert("gravity".to_string(), json!(value)); + } + if let Some(value) = quality { + params.insert("quality".to_string(), json!(value)); + } + if let Some(value) = border_width { + params.insert("borderWidth".to_string(), json!(value)); + } + if let Some(value) = border_color { + params.insert("borderColor".to_string(), json!(value)); + } + if let Some(value) = border_radius { + params.insert("borderRadius".to_string(), json!(value)); + } + if let Some(value) = opacity { + params.insert("opacity".to_string(), json!(value)); + } + if let Some(value) = rotation { + params.insert("rotation".to_string(), json!(value)); + } + if let Some(value) = background { + params.insert("background".to_string(), json!(value)); + } + if let Some(value) = output { + params.insert("output".to_string(), json!(value)); + } + if let Some(value) = token { + params.insert("token".to_string(), json!(value)); + } + + let path = "/storage/buckets/{bucketId}/files/{fileId}/preview".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + + /// Get a file content by its unique ID. This endpoint is similar to the + /// download method but returns with no 'Content-Disposition: attachment' + /// header. + pub async fn get_file_view( + &self, + bucket_id: impl Into, + file_id: impl Into, + token: Option<&str>, + ) -> crate::error::Result> { + let mut params = HashMap::new(); + if let Some(value) = token { + params.insert("token".to_string(), json!(value)); + } + + let path = "/storage/buckets/{bucketId}/files/{fileId}/view".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call_bytes(Method::GET, &path, None, Some(params)).await + } + +} + +impl crate::services::Service for Storage { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_storage_creation() { + let client = Client::new(); + let service = Storage::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/tables_db.rs b/src/services/tables_db.rs new file mode 100644 index 0000000..9a014dc --- /dev/null +++ b/src/services/tables_db.rs @@ -0,0 +1,1817 @@ +//! TablesDB service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub struct TablesDB { + client: Client, +} + +impl TablesDB { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all databases from the current Appwrite project. You can use + /// the search parameter to filter your results. + pub async fn list( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/tablesdb".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Database. + pub async fn create( + &self, + database_id: impl Into, + name: impl Into, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("databaseId".to_string(), json!(database_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// List transactions across all databases. + pub async fn list_transactions( + &self, + queries: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + + let path = "/tablesdb/transactions".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new transaction. + pub async fn create_transaction( + &self, + ttl: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = ttl { + params.insert("ttl".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/transactions".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a transaction by its unique ID. + pub async fn get_transaction( + &self, + transaction_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/tablesdb/transactions/{transactionId}".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a transaction, to either commit or roll back its operations. + pub async fn update_transaction( + &self, + transaction_id: impl Into, + commit: Option, + rollback: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = commit { + params.insert("commit".to_string(), json!(value)); + } + if let Some(value) = rollback { + params.insert("rollback".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/transactions/{transactionId}".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a transaction by its unique ID. + pub async fn delete_transaction( + &self, + transaction_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/transactions/{transactionId}".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Create multiple operations in a single transaction. + pub async fn create_operations( + &self, + transaction_id: impl Into, + operations: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = operations { + params.insert("operations".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/transactions/{transactionId}/operations".to_string().replace("{transactionId}", &transaction_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a database by its unique ID. This endpoint response returns a JSON + /// object with the database metadata. + pub async fn get( + &self, + database_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/tablesdb/{databaseId}".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a database by its unique ID. + pub async fn update( + &self, + database_id: impl Into, + name: Option<&str>, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a database by its unique ID. Only API keys with with databases.write + /// scope can delete a database. + pub async fn delete( + &self, + database_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all tables that belong to the provided databaseId. You can + /// use the search parameter to filter your results. + pub async fn list_tables( + &self, + database_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/tablesdb/{databaseId}/tables".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Table. Before using this route, you should create a new + /// database resource using either a [server + /// integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + /// API or directly from your database console. + #[allow(clippy::too_many_arguments)] + pub async fn create_table( + &self, + database_id: impl Into, + table_id: impl Into, + name: impl Into, + permissions: Option>, + row_security: Option, + enabled: Option, + columns: Option>, + indexes: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("tableId".to_string(), json!(table_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = row_security { + params.insert("rowSecurity".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = columns { + params.insert("columns".to_string(), json!(value)); + } + if let Some(value) = indexes { + params.insert("indexes".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables".to_string().replace("{databaseId}", &database_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a table by its unique ID. This endpoint response returns a JSON object + /// with the table metadata. + pub async fn get_table( + &self, + database_id: impl Into, + table_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/tablesdb/{databaseId}/tables/{tableId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a table by its unique ID. + pub async fn update_table( + &self, + database_id: impl Into, + table_id: impl Into, + name: Option<&str>, + permissions: Option>, + row_security: Option, + enabled: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = row_security { + params.insert("rowSecurity".to_string(), json!(value)); + } + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a table by its unique ID. Only users with write permissions have + /// access to delete this resource. + pub async fn delete_table( + &self, + database_id: impl Into, + table_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// List columns in the table. + pub async fn list_columns( + &self, + database_id: impl Into, + table_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a boolean column. + pub async fn create_boolean_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/boolean".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a boolean column. Changing the `default` value will not update + /// already existing rows. + pub async fn update_boolean_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/boolean/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a date time column according to the ISO 8601 standard. + pub async fn create_datetime_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/datetime".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a date time column. Changing the `default` value will not update + /// already existing rows. + pub async fn update_datetime_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/datetime/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create an email column. + pub async fn create_email_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/email".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an email column. Changing the `default` value will not update + /// already existing rows. + pub async fn update_email_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/email/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create an enumeration column. The `elements` param acts as a white-list of + /// accepted values for this column. + #[allow(clippy::too_many_arguments)] + pub async fn create_enum_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + elements: impl IntoIterator>, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("elements".to_string(), json!(elements.into_iter().map(|s| s.into()).collect::>())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/enum".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an enum column. Changing the `default` value will not update already + /// existing rows. + #[allow(clippy::too_many_arguments)] + pub async fn update_enum_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + elements: impl IntoIterator>, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("elements".to_string(), json!(elements.into_iter().map(|s| s.into()).collect::>())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/enum/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a float column. Optionally, minimum and maximum values can be + /// provided. + #[allow(clippy::too_many_arguments)] + pub async fn create_float_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + min: Option, + max: Option, + default: Option, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/float".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a float column. Changing the `default` value will not update already + /// existing rows. + #[allow(clippy::too_many_arguments)] + pub async fn update_float_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option, + min: Option, + max: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/float/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create an integer column. Optionally, minimum and maximum values can be + /// provided. + #[allow(clippy::too_many_arguments)] + pub async fn create_integer_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + min: Option, + max: Option, + default: Option, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/integer".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an integer column. Changing the `default` value will not update + /// already existing rows. + #[allow(clippy::too_many_arguments)] + pub async fn update_integer_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option, + min: Option, + max: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/integer/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create IP address column. + pub async fn create_ip_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/ip".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an ip column. Changing the `default` value will not update already + /// existing rows. + pub async fn update_ip_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/ip/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a geometric line column. + pub async fn create_line_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/line".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a line column. Changing the `default` value will not update already + /// existing rows. + pub async fn update_line_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/line/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a longtext column. + #[allow(clippy::too_many_arguments)] + pub async fn create_longtext_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/longtext".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a longtext column. Changing the `default` value will not update + /// already existing rows. + pub async fn update_longtext_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/longtext/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a mediumtext column. + #[allow(clippy::too_many_arguments)] + pub async fn create_mediumtext_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/mediumtext".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a mediumtext column. Changing the `default` value will not update + /// already existing rows. + pub async fn update_mediumtext_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/mediumtext/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a geometric point column. + pub async fn create_point_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/point".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a point column. Changing the `default` value will not update already + /// existing rows. + pub async fn update_point_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/point/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a geometric polygon column. + pub async fn create_polygon_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/polygon".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a polygon column. Changing the `default` value will not update + /// already existing rows. + pub async fn update_polygon_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/polygon/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create relationship column. [Learn more about relationship + /// columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + #[allow(clippy::too_many_arguments)] + pub async fn create_relationship_column( + &self, + database_id: impl Into, + table_id: impl Into, + related_table_id: impl Into, + r#type: crate::enums::RelationshipType, + two_way: Option, + key: Option<&str>, + two_way_key: Option<&str>, + on_delete: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("relatedTableId".to_string(), json!(related_table_id.into())); + params.insert("type".to_string(), json!(r#type)); + if let Some(value) = two_way { + params.insert("twoWay".to_string(), json!(value)); + } + if let Some(value) = key { + params.insert("key".to_string(), json!(value)); + } + if let Some(value) = two_way_key { + params.insert("twoWayKey".to_string(), json!(value)); + } + if let Some(value) = on_delete { + params.insert("onDelete".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/relationship".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a string column. + #[allow(clippy::too_many_arguments)] + pub async fn create_string_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + size: i64, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("size".to_string(), json!(size)); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/string".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a string column. Changing the `default` value will not update + /// already existing rows. + #[allow(clippy::too_many_arguments)] + pub async fn update_string_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + size: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = size { + params.insert("size".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/string/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a text column. + #[allow(clippy::too_many_arguments)] + pub async fn create_text_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/text".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a text column. Changing the `default` value will not update already + /// existing rows. + pub async fn update_text_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/text/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a URL column. + pub async fn create_url_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + array: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/url".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update an url column. Changing the `default` value will not update already + /// existing rows. + pub async fn update_url_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/url/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Create a varchar column. + #[allow(clippy::too_many_arguments)] + pub async fn create_varchar_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + size: i64, + required: bool, + default: Option<&str>, + array: Option, + encrypt: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("size".to_string(), json!(size)); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = array { + params.insert("array".to_string(), json!(value)); + } + if let Some(value) = encrypt { + params.insert("encrypt".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/varchar".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update a varchar column. Changing the `default` value will not update + /// already existing rows. + #[allow(clippy::too_many_arguments)] + pub async fn update_varchar_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + required: bool, + default: Option<&str>, + size: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("required".to_string(), json!(required)); + if let Some(value) = default { + params.insert("default".to_string(), json!(value)); + } + if let Some(value) = size { + params.insert("size".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/varchar/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get column by ID. + pub async fn get_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Deletes a column. + pub async fn delete_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Update relationship column. [Learn more about relationship + /// columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + pub async fn update_relationship_column( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + on_delete: Option, + new_key: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = on_delete { + params.insert("onDelete".to_string(), json!(value)); + } + if let Some(value) = new_key { + params.insert("newKey".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/columns/{key}/relationship".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// List indexes on the table. + pub async fn list_indexes( + &self, + database_id: impl Into, + table_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/tablesdb/{databaseId}/tables/{tableId}/indexes".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Creates an index on the columns listed. Your index should include all the + /// columns you will query in a single request. + /// Type can be `key`, `fulltext`, or `unique`. + #[allow(clippy::too_many_arguments)] + pub async fn create_index( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + r#type: crate::enums::IndexType, + columns: impl IntoIterator>, + orders: Option, + lengths: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("key".to_string(), json!(key.into())); + params.insert("type".to_string(), json!(r#type)); + params.insert("columns".to_string(), json!(columns.into_iter().map(|s| s.into()).collect::>())); + if let Some(value) = orders { + params.insert("orders".to_string(), json!(value)); + } + if let Some(value) = lengths { + params.insert("lengths".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/indexes".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get index by ID. + pub async fn get_index( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/indexes/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete an index. + pub async fn delete_index( + &self, + database_id: impl Into, + table_id: impl Into, + key: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/indexes/{key}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{key}", &key.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a list of all the user's rows in a given table. You can use the query + /// params to filter your results. + pub async fn list_rows( + &self, + database_id: impl Into, + table_id: impl Into, + queries: Option>, + transaction_id: Option<&str>, + total: Option, + ttl: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + if let Some(value) = ttl { + params.insert("ttl".to_string(), json!(value)); + } + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new Row. Before using this route, you should create a new table + /// resource using either a [server + /// integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + /// API or directly from your database console. + pub async fn create_row( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + data: serde_json::Value, + permissions: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("rowId".to_string(), json!(row_id.into())); + params.insert("data".to_string(), json!(data)); + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create new Rows. Before using this route, you should create a new table + /// resource using either a [server + /// integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + /// API or directly from your database console. + pub async fn create_rows( + &self, + database_id: impl Into, + table_id: impl Into, + rows: Vec, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("rows".to_string(), json!(rows)); + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create or update Rows. Before using this route, you should create a new + /// table resource using either a [server + /// integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + /// API or directly from your database console. + pub async fn upsert_rows( + &self, + database_id: impl Into, + table_id: impl Into, + rows: Vec, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("rows".to_string(), json!(rows)); + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Update all rows that match your queries, if no queries are submitted then + /// all rows are updated. You can pass only specific fields to be updated. + pub async fn update_rows( + &self, + database_id: impl Into, + table_id: impl Into, + data: Option, + queries: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Bulk delete rows using queries, if no queries are passed then all rows are + /// deleted. + pub async fn delete_rows( + &self, + database_id: impl Into, + table_id: impl Into, + queries: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Get a row by its unique ID. This endpoint response returns a JSON object + /// with the row data. + pub async fn get_row( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + queries: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{rowId}", &row_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create or update a Row. Before using this route, you should create a new + /// table resource using either a [server + /// integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + /// API or directly from your database console. + pub async fn upsert_row( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + data: Option, + permissions: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{rowId}", &row_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Update a row by its unique ID. Using the patch method you can pass only + /// specific fields that will get updated. + pub async fn update_row( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + data: Option, + permissions: Option>, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = data { + params.insert("data".to_string(), json!(value)); + } + if let Some(value) = permissions { + params.insert("permissions".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{rowId}", &row_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a row by its unique ID. + pub async fn delete_row( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + transaction_id: Option<&str>, + ) -> crate::error::Result<()> { + let mut params = HashMap::new(); + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{rowId}", &row_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Decrement a specific column of a row by a given value. + #[allow(clippy::too_many_arguments)] + pub async fn decrement_row_column( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + column: impl Into, + value: Option, + min: Option, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = value { + params.insert("value".to_string(), json!(value)); + } + if let Some(value) = min { + params.insert("min".to_string(), json!(value)); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}/{column}/decrement".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{rowId}", &row_id.into().to_string()).replace("{column}", &column.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Increment a specific column of a row by a given value. + #[allow(clippy::too_many_arguments)] + pub async fn increment_row_column( + &self, + database_id: impl Into, + table_id: impl Into, + row_id: impl Into, + column: impl Into, + value: Option, + max: Option, + transaction_id: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = value { + params.insert("value".to_string(), json!(value)); + } + if let Some(value) = max { + params.insert("max".to_string(), json!(value)); + } + if let Some(value) = transaction_id { + params.insert("transactionId".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}/{column}/increment".to_string().replace("{databaseId}", &database_id.into().to_string()).replace("{tableId}", &table_id.into().to_string()).replace("{rowId}", &row_id.into().to_string()).replace("{column}", &column.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for TablesDB { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_tables_db_creation() { + let client = Client::new(); + let service = TablesDB::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/teams.rs b/src/services/teams.rs new file mode 100644 index 0000000..5c54c9c --- /dev/null +++ b/src/services/teams.rs @@ -0,0 +1,322 @@ +//! Teams service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Teams service allows you to group users of your project and to enable +/// them to share read and write access to your project resources +#[derive(Debug, Clone)] +pub struct Teams { + client: Client, +} + +impl Teams { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all the teams in which the current user is a member. You can + /// use the parameters to filter your results. + pub async fn list( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/teams".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new team. The user who creates the team will automatically be + /// assigned as the owner of the team. Only the users with the owner role can + /// invite new members, add new owners and delete or update the team. + pub async fn create( + &self, + team_id: impl Into, + name: impl Into, + roles: Option>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("teamId".to_string(), json!(team_id.into())); + params.insert("name".to_string(), json!(name.into())); + if let Some(value) = roles { + params.insert("roles".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a team by its ID. All team members have read access for this resource. + pub async fn get( + &self, + team_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/teams/{teamId}".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update the team's name by its unique ID. + pub async fn update_name( + &self, + team_id: impl Into, + name: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a team using its ID. Only team members with the owner role can + /// delete the team. + pub async fn delete( + &self, + team_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to list a team's members using the team's ID. All team + /// members have read access to this endpoint. Hide sensitive attributes from + /// the response by toggling membership privacy in the Console. + pub async fn list_memberships( + &self, + team_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/teams/{teamId}/memberships".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Invite a new member to join your team. Provide an ID for existing users, or + /// invite unregistered users using an email or phone number. If initiated from + /// a Client SDK, Appwrite will send an email or sms with a link to join the + /// team to the invited user, and an account will be created for them if one + /// doesn't exist. If initiated from a Server SDK, the new member will be added + /// automatically to the team. + /// + /// You only need to provide one of a user ID, email, or phone number. Appwrite + /// will prioritize accepting the user ID > email > phone number if you provide + /// more than one of these parameters. + /// + /// Use the `url` parameter to redirect the user from the invitation email to + /// your app. After the user is redirected, use the [Update Team Membership + /// Status](https://appwrite.io/docs/references/cloud/client-web/teams#updateMembershipStatus) + /// endpoint to allow the user to accept the invitation to the team. + /// + /// Please note that to avoid a [Redirect + /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + /// Appwrite will accept the only redirect URLs under the domains you have + /// added as a platform on the Appwrite Console. + #[allow(clippy::too_many_arguments)] + pub async fn create_membership( + &self, + team_id: impl Into, + roles: impl IntoIterator>, + email: Option<&str>, + user_id: Option<&str>, + phone: Option<&str>, + url: Option<&str>, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = email { + params.insert("email".to_string(), json!(value)); + } + if let Some(value) = user_id { + params.insert("userId".to_string(), json!(value)); + } + if let Some(value) = phone { + params.insert("phone".to_string(), json!(value)); + } + params.insert("roles".to_string(), json!(roles.into_iter().map(|s| s.into()).collect::>())); + if let Some(value) = url { + params.insert("url".to_string(), json!(value)); + } + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}/memberships".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a team member by the membership unique id. All team members have read + /// access for this resource. Hide sensitive attributes from the response by + /// toggling membership privacy in the Console. + pub async fn get_membership( + &self, + team_id: impl Into, + membership_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/teams/{teamId}/memberships/{membershipId}".to_string().replace("{teamId}", &team_id.into().to_string()).replace("{membershipId}", &membership_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Modify the roles of a team member. Only team members with the owner role + /// have access to this endpoint. Learn more about [roles and + /// permissions](https://appwrite.io/docs/permissions). + pub async fn update_membership( + &self, + team_id: impl Into, + membership_id: impl Into, + roles: impl IntoIterator>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("roles".to_string(), json!(roles.into_iter().map(|s| s.into()).collect::>())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}/memberships/{membershipId}".to_string().replace("{teamId}", &team_id.into().to_string()).replace("{membershipId}", &membership_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// This endpoint allows a user to leave a team or for a team owner to delete + /// the membership of any other team member. You can also use this endpoint to + /// delete a user membership even if it is not accepted. + pub async fn delete_membership( + &self, + team_id: impl Into, + membership_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}/memberships/{membershipId}".to_string().replace("{teamId}", &team_id.into().to_string()).replace("{membershipId}", &membership_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to allow a user to accept an invitation to join a team + /// after being redirected back to your app from the invitation email received + /// by the user. + /// + /// If the request is successful, a session for the user is automatically + /// created. + pub async fn update_membership_status( + &self, + team_id: impl Into, + membership_id: impl Into, + user_id: impl Into, + secret: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("secret".to_string(), json!(secret.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}/memberships/{membershipId}/status".to_string().replace("{teamId}", &team_id.into().to_string()).replace("{membershipId}", &membership_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get the team's shared preferences by its unique ID. If a preference doesn't + /// need to be shared by all team members, prefer storing them in [user + /// preferences](https://appwrite.io/docs/references/cloud/client-web/account#getPrefs). + pub async fn get_prefs( + &self, + team_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/teams/{teamId}/prefs".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update the team's preferences by its unique ID. The object you pass is + /// stored as is and replaces any previous value. The maximum allowed prefs + /// size is 64kB and throws an error if exceeded. + pub async fn update_prefs( + &self, + team_id: impl Into, + prefs: serde_json::Value, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("prefs".to_string(), json!(prefs)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/teams/{teamId}/prefs".to_string().replace("{teamId}", &team_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Teams { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_teams_creation() { + let client = Client::new(); + let service = Teams::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/tokens.rs b/src/services/tokens.rs new file mode 100644 index 0000000..e81835c --- /dev/null +++ b/src/services/tokens.rs @@ -0,0 +1,128 @@ +//! Tokens service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub struct Tokens { + client: Client, +} + +impl Tokens { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// List all the tokens created for a specific file or bucket. You can use the + /// query params to filter your results. + pub async fn list( + &self, + bucket_id: impl Into, + file_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/tokens/buckets/{bucketId}/files/{fileId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new token. A token is linked to a file. Token can be passed as a + /// request URL search parameter. + pub async fn create_file_token( + &self, + bucket_id: impl Into, + file_id: impl Into, + expire: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = expire { + params.insert("expire".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tokens/buckets/{bucketId}/files/{fileId}".to_string().replace("{bucketId}", &bucket_id.into().to_string()).replace("{fileId}", &file_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a token by its unique ID. + pub async fn get( + &self, + token_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/tokens/{tokenId}".to_string().replace("{tokenId}", &token_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a token by its unique ID. Use this endpoint to update a token's + /// expiry date. + pub async fn update( + &self, + token_id: impl Into, + expire: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = expire { + params.insert("expire".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tokens/{tokenId}".to_string().replace("{tokenId}", &token_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a token by its unique ID. + pub async fn delete( + &self, + token_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/tokens/{tokenId}".to_string().replace("{tokenId}", &token_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Tokens { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_tokens_creation() { + let client = Client::new(); + let service = Tokens::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/users.rs b/src/services/users.rs new file mode 100644 index 0000000..4d45b00 --- /dev/null +++ b/src/services/users.rs @@ -0,0 +1,906 @@ +//! Users service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +/// The Users service allows you to manage your project users. +#[derive(Debug, Clone)] +pub struct Users { + client: Client, +} + +impl Users { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all the project's users. You can use the query params to + /// filter your results. + pub async fn list( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/users".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new user. + pub async fn create( + &self, + user_id: impl Into, + email: Option<&str>, + phone: Option<&str>, + password: Option<&str>, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + if let Some(value) = email { + params.insert("email".to_string(), json!(value)); + } + if let Some(value) = phone { + params.insert("phone".to_string(), json!(value)); + } + if let Some(value) = password { + params.insert("password".to_string(), json!(value)); + } + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the + /// [Argon2](https://en.wikipedia.org/wiki/Argon2) algorithm. Use the [POST + /// /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + /// create users with a plain text password. + pub async fn create_argon2_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/argon2".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the + /// [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) algorithm. Use the [POST + /// /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + /// create users with a plain text password. + pub async fn create_bcrypt_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/bcrypt".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get identities for all users. + pub async fn list_identities( + &self, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/users/identities".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete an identity by its unique ID. + pub async fn delete_identity( + &self, + identity_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/identities/{identityId}".to_string().replace("{identityId}", &identity_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the + /// [MD5](https://en.wikipedia.org/wiki/MD5) algorithm. Use the [POST + /// /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + /// create users with a plain text password. + pub async fn create_md5_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/md5".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the + /// [PHPass](https://www.openwall.com/phpass/) algorithm. Use the [POST + /// /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + /// create users with a plain text password. + pub async fn create_ph_pass_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/phpass".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the + /// [Scrypt](https://github.com/Tarsnap/scrypt) algorithm. Use the [POST + /// /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + /// create users with a plain text password. + #[allow(clippy::too_many_arguments)] + pub async fn create_scrypt_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + password_salt: impl Into, + password_cpu: i64, + password_memory: i64, + password_parallel: i64, + password_length: i64, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + params.insert("passwordSalt".to_string(), json!(password_salt.into())); + params.insert("passwordCpu".to_string(), json!(password_cpu)); + params.insert("passwordMemory".to_string(), json!(password_memory)); + params.insert("passwordParallel".to_string(), json!(password_parallel)); + params.insert("passwordLength".to_string(), json!(password_length)); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/scrypt".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the [Scrypt + /// Modified](https://gist.github.com/Meldiron/eecf84a0225eccb5a378d45bb27462cc) + /// algorithm. Use the [POST + /// /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + /// create users with a plain text password. + #[allow(clippy::too_many_arguments)] + pub async fn create_scrypt_modified_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + password_salt: impl Into, + password_salt_separator: impl Into, + password_signer_key: impl Into, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + params.insert("passwordSalt".to_string(), json!(password_salt.into())); + params.insert("passwordSaltSeparator".to_string(), json!(password_salt_separator.into())); + params.insert("passwordSignerKey".to_string(), json!(password_signer_key.into())); + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/scrypt-modified".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Create a new user. Password provided must be hashed with the + /// [SHA](https://en.wikipedia.org/wiki/Secure_Hash_Algorithm) algorithm. Use + /// the [POST /users](https://appwrite.io/docs/server/users#usersCreate) + /// endpoint to create users with a plain text password. + pub async fn create_sha_user( + &self, + user_id: impl Into, + email: impl Into, + password: impl Into, + password_version: Option, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("userId".to_string(), json!(user_id.into())); + params.insert("email".to_string(), json!(email.into())); + params.insert("password".to_string(), json!(password.into())); + if let Some(value) = password_version { + params.insert("passwordVersion".to_string(), json!(value)); + } + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/sha".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a user by its unique ID. + pub async fn get( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/users/{userId}".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Delete a user by its unique ID, thereby releasing it's ID. Since ID is + /// released and can be reused, all user-related resources like documents or + /// storage files should be deleted before user deletion. If you want to keep + /// ID reserved, use the + /// [updateStatus](https://appwrite.io/docs/server/users#usersUpdateStatus) + /// endpoint instead. + pub async fn delete( + &self, + user_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Update the user email by its unique ID. + pub async fn update_email( + &self, + user_id: impl Into, + email: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("email".to_string(), json!(email.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/email".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Enable or disable whether a user can impersonate other users. When + /// impersonation headers are used, the request runs as the target user for API + /// behavior, while internal audit logs still attribute the action to the + /// original impersonator and store the impersonated target details only in + /// internal audit payload data. + pub async fn update_impersonator( + &self, + user_id: impl Into, + impersonator: bool, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("impersonator".to_string(), json!(impersonator)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/impersonator".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Use this endpoint to create a JSON Web Token for user by its unique ID. You + /// can use the resulting JWT to authenticate on behalf of the user. The JWT + /// secret will become invalid if the session it uses gets deleted. + pub async fn create_jwt( + &self, + user_id: impl Into, + session_id: Option<&str>, + duration: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = session_id { + params.insert("sessionId".to_string(), json!(value)); + } + if let Some(value) = duration { + params.insert("duration".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/jwts".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update the user labels by its unique ID. + /// + /// Labels can be used to grant access to resources. While teams are a way for + /// user's to share access to a resource, labels can be defined by the + /// developer to grant access without an invitation. See the [Permissions + /// docs](https://appwrite.io/docs/permissions) for more info. + pub async fn update_labels( + &self, + user_id: impl Into, + labels: impl IntoIterator>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("labels".to_string(), json!(labels.into_iter().map(|s| s.into()).collect::>())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/labels".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Get the user activity logs list by its unique ID. + pub async fn list_logs( + &self, + user_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/users/{userId}/logs".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get the user membership list by its unique ID. + pub async fn list_memberships( + &self, + user_id: impl Into, + queries: Option>, + search: Option<&str>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = search { + params.insert("search".to_string(), json!(value)); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/users/{userId}/memberships".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Enable or disable MFA on a user account. + pub async fn update_mfa( + &self, + user_id: impl Into, + mfa: bool, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("mfa".to_string(), json!(mfa)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/mfa".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete an authenticator app. + pub async fn delete_mfa_authenticator( + &self, + user_id: impl Into, + r#type: crate::enums::AuthenticatorType, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/mfa/authenticators/{type}".to_string().replace("{userId}", &user_id.into().to_string()).replace("{type}", &r#type.to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// List the factors available on the account to be used as a MFA challange. + pub async fn list_mfa_factors( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/users/{userId}/mfa/factors".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Get recovery codes that can be used as backup for MFA flow by User ID. + /// Before getting codes, they must be generated using + /// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + /// method. + pub async fn get_mfa_recovery_codes( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/users/{userId}/mfa/recovery-codes".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Regenerate recovery codes that can be used as backup for MFA flow by User + /// ID. Before regenerating codes, they must be first generated using + /// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + /// method. + pub async fn update_mfa_recovery_codes( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/mfa/recovery-codes".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Generate recovery codes used as backup for MFA flow for User ID. Recovery + /// codes can be used as a MFA verification type in + /// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + /// method by client SDK. + pub async fn create_mfa_recovery_codes( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/mfa/recovery-codes".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update the user name by its unique ID. + pub async fn update_name( + &self, + user_id: impl Into, + name: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/name".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update the user password by its unique ID. + pub async fn update_password( + &self, + user_id: impl Into, + password: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("password".to_string(), json!(password.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/password".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update the user phone by its unique ID. + pub async fn update_phone( + &self, + user_id: impl Into, + number: impl Into, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("number".to_string(), json!(number.into())); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/phone".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get the user preferences by its unique ID. + pub async fn get_prefs( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/users/{userId}/prefs".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update the user preferences by its unique ID. The object you pass is stored + /// as is, and replaces any previous value. The maximum allowed prefs size is + /// 64kB and throws error if exceeded. + pub async fn update_prefs( + &self, + user_id: impl Into, + prefs: serde_json::Value, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("prefs".to_string(), json!(prefs)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/prefs".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Get the user sessions list by its unique ID. + pub async fn list_sessions( + &self, + user_id: impl Into, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/users/{userId}/sessions".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Creates a session for a user. Returns an immediately usable session object. + /// + /// If you want to generate a token for a custom authentication flow, use the + /// [POST + /// /users/{userId}/tokens](https://appwrite.io/docs/server/users#createToken) + /// endpoint. + pub async fn create_session( + &self, + user_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/sessions".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Delete all user's sessions by using the user's unique ID. + pub async fn delete_sessions( + &self, + user_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/sessions".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Delete a user sessions by its unique ID. + pub async fn delete_session( + &self, + user_id: impl Into, + session_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/sessions/{sessionId}".to_string().replace("{userId}", &user_id.into().to_string()).replace("{sessionId}", &session_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Update the user status by its unique ID. Use this endpoint as an + /// alternative to deleting a user if you want to keep user's ID reserved. + pub async fn update_status( + &self, + user_id: impl Into, + status: bool, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("status".to_string(), json!(status)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/status".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// List the messaging targets that are associated with a user. + pub async fn list_targets( + &self, + user_id: impl Into, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/users/{userId}/targets".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a messaging target. + pub async fn create_target( + &self, + user_id: impl Into, + target_id: impl Into, + provider_type: crate::enums::MessagingProviderType, + identifier: impl Into, + provider_id: Option<&str>, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("targetId".to_string(), json!(target_id.into())); + params.insert("providerType".to_string(), json!(provider_type)); + params.insert("identifier".to_string(), json!(identifier.into())); + if let Some(value) = provider_id { + params.insert("providerId".to_string(), json!(value)); + } + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/targets".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a user's push notification target by ID. + pub async fn get_target( + &self, + user_id: impl Into, + target_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/users/{userId}/targets/{targetId}".to_string().replace("{userId}", &user_id.into().to_string()).replace("{targetId}", &target_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a messaging target. + pub async fn update_target( + &self, + user_id: impl Into, + target_id: impl Into, + identifier: Option<&str>, + provider_id: Option<&str>, + name: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = identifier { + params.insert("identifier".to_string(), json!(value)); + } + if let Some(value) = provider_id { + params.insert("providerId".to_string(), json!(value)); + } + if let Some(value) = name { + params.insert("name".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/targets/{targetId}".to_string().replace("{userId}", &user_id.into().to_string()).replace("{targetId}", &target_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Delete a messaging target. + pub async fn delete_target( + &self, + user_id: impl Into, + target_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/targets/{targetId}".to_string().replace("{userId}", &user_id.into().to_string()).replace("{targetId}", &target_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Returns a token with a secret key for creating a session. Use the user ID + /// and secret and submit a request to the [PUT + /// /account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. + pub async fn create_token( + &self, + user_id: impl Into, + length: Option, + expire: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = length { + params.insert("length".to_string(), json!(value)); + } + if let Some(value) = expire { + params.insert("expire".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/tokens".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Update the user email verification status by its unique ID. + pub async fn update_email_verification( + &self, + user_id: impl Into, + email_verification: bool, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("emailVerification".to_string(), json!(email_verification)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/verification".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + + /// Update the user phone verification status by its unique ID. + pub async fn update_phone_verification( + &self, + user_id: impl Into, + phone_verification: bool, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("phoneVerification".to_string(), json!(phone_verification)); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/users/{userId}/verification/phone".to_string().replace("{userId}", &user_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Users { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_users_creation() { + let client = Client::new(); + let service = Users::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/src/services/webhooks.rs b/src/services/webhooks.rs new file mode 100644 index 0000000..a861921 --- /dev/null +++ b/src/services/webhooks.rs @@ -0,0 +1,182 @@ +//! Webhooks service for Appwrite SDK + +use crate::client::Client; + +use reqwest::Method; +use serde_json::json; +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub struct Webhooks { + client: Client, +} + +impl Webhooks { + pub fn new(client: &Client) -> Self { + Self { client: client.clone() } + } + + pub fn client(&self) -> &Client { + &self.client + } + + /// Get a list of all webhooks belonging to the project. You can use the query + /// params to filter your results. + pub async fn list( + &self, + queries: Option>, + total: Option, + ) -> crate::error::Result { + let mut params = HashMap::new(); + if let Some(value) = queries { + params.insert("queries".to_string(), json!(value.into_iter().map(|s| s.into()).collect::>())); + } + if let Some(value) = total { + params.insert("total".to_string(), json!(value)); + } + + let path = "/webhooks".to_string(); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Create a new webhook. Use this endpoint to configure a URL that will + /// receive events from Appwrite when specific events occur. + #[allow(clippy::too_many_arguments)] + pub async fn create( + &self, + webhook_id: impl Into, + url: impl Into, + name: impl Into, + events: impl IntoIterator>, + enabled: Option, + security: Option, + http_user: Option<&str>, + http_pass: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("webhookId".to_string(), json!(webhook_id.into())); + params.insert("url".to_string(), json!(url.into())); + params.insert("name".to_string(), json!(name.into())); + params.insert("events".to_string(), json!(events.into_iter().map(|s| s.into()).collect::>())); + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = security { + params.insert("security".to_string(), json!(value)); + } + if let Some(value) = http_user { + params.insert("httpUser".to_string(), json!(value)); + } + if let Some(value) = http_pass { + params.insert("httpPass".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/webhooks".to_string(); + + self.client.call(Method::POST, &path, Some(api_headers), Some(params)).await + } + + /// Get a webhook by its unique ID. This endpoint returns details about a + /// specific webhook configured for a project. + pub async fn get( + &self, + webhook_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + + let path = "/webhooks/{webhookId}".to_string().replace("{webhookId}", &webhook_id.into().to_string()); + + self.client.call(Method::GET, &path, None, Some(params)).await + } + + /// Update a webhook by its unique ID. Use this endpoint to update the URL, + /// events, or status of an existing webhook. + #[allow(clippy::too_many_arguments)] + pub async fn update( + &self, + webhook_id: impl Into, + name: impl Into, + url: impl Into, + events: impl IntoIterator>, + enabled: Option, + security: Option, + http_user: Option<&str>, + http_pass: Option<&str>, + ) -> crate::error::Result { + let mut params = HashMap::new(); + params.insert("name".to_string(), json!(name.into())); + params.insert("url".to_string(), json!(url.into())); + params.insert("events".to_string(), json!(events.into_iter().map(|s| s.into()).collect::>())); + if let Some(value) = enabled { + params.insert("enabled".to_string(), json!(value)); + } + if let Some(value) = security { + params.insert("security".to_string(), json!(value)); + } + if let Some(value) = http_user { + params.insert("httpUser".to_string(), json!(value)); + } + if let Some(value) = http_pass { + params.insert("httpPass".to_string(), json!(value)); + } + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/webhooks/{webhookId}".to_string().replace("{webhookId}", &webhook_id.into().to_string()); + + self.client.call(Method::PUT, &path, Some(api_headers), Some(params)).await + } + + /// Delete a webhook by its unique ID. Once deleted, the webhook will no longer + /// receive project events. + pub async fn delete( + &self, + webhook_id: impl Into, + ) -> crate::error::Result<()> { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/webhooks/{webhookId}".to_string().replace("{webhookId}", &webhook_id.into().to_string()); + + self.client.call(Method::DELETE, &path, Some(api_headers), Some(params)).await + } + + /// Update the webhook signature key. This endpoint can be used to regenerate + /// the signature key used to sign and validate payload deliveries for a + /// specific webhook. + pub async fn update_signature( + &self, + webhook_id: impl Into, + ) -> crate::error::Result { + let params = HashMap::new(); + let mut api_headers = HashMap::new(); + api_headers.insert("content-type".to_string(), "application/json".to_string()); + + let path = "/webhooks/{webhookId}/signature".to_string().replace("{webhookId}", &webhook_id.into().to_string()); + + self.client.call(Method::PATCH, &path, Some(api_headers), Some(params)).await + } + +} + +impl crate::services::Service for Webhooks { + fn client(&self) -> &Client { + &self.client + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_webhooks_creation() { + let client = Client::new(); + let service = Webhooks::new(&client); + assert!(service.client().endpoint().contains("cloud.appwrite.io/v1")); + } +} diff --git a/tests/tests.rs b/tests/tests.rs new file mode 100644 index 0000000..ffbed8e --- /dev/null +++ b/tests/tests.rs @@ -0,0 +1,291 @@ +use appwrite::{Client, services::*, id::ID, permission::Permission, query::Query, role::Role, input_file::InputFile}; +use serde_json::json; +use std::path::Path; +use tokio; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let string_in_array = vec!["string in array".to_string()]; + + let client = Client::new() + .set_endpoint("http://mockapi/v1") + .set_project("appwrite") + .set_key("apikey") + .add_header("Origin", "http://localhost"); + + println!("\n\nTest Started"); + test_foo_service(&client, &string_in_array).await?; + test_bar_service(&client, &string_in_array).await?; + test_general_service(&client, &string_in_array).await?; + + Ok(()) +} + +async fn test_foo_service(client: &Client, string_in_array: &[String]) -> Result<(), Box> { + let foo = Foo::new(&client); + + // Foo Service + match foo.get("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("foo.get => error {}", e), + } + + match foo.post("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("foo.post => error {}", e), + } + + match foo.put("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("foo.put => error {}", e), + } + + match foo.patch("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("foo.patch => error {}", e), + } + + match foo.delete("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("foo.delete => error {}", e), + } + + Ok(()) +} + +async fn test_bar_service(client: &Client, string_in_array: &[String]) -> Result<(), Box> { + let bar = Bar::new(&client); + + // Bar Service + match bar.get("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("bar.get => error {}", e), + } + + match bar.post("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("bar.post => error {}", e), + } + + match bar.put("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("bar.put => error {}", e), + } + + match bar.patch("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("bar.patch => error {}", e), + } + + match bar.delete("string", 123, string_in_array).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("bar.delete => error {}", e), + } + + Ok(()) +} + +async fn test_general_service(client: &Client, string_in_array: &[String]) -> Result<(), Box> { + let general = General::new(&client); + + // redirect returns () + // and client follows redirect automatically + match general.redirected().await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("general.redirected => error {}", e), + } + + test_general_upload(client, string_in_array).await?; + test_large_upload(client, string_in_array).await?; + + // Extended General Responses + test_general_download(client).await?; + + // Exception Responses + match general.error400().await { + Ok(_) => {}, + Err(e) => { + println!("{}", e.message); + println!("{}", e.response); + }, + } + + match general.error500().await { + Ok(_) => {}, + Err(e) => { + println!("{}", e.message); + println!("{}", e.response); + }, + } + + match general.error502().await { + Ok(_) => {}, + Err(e) => { + println!("{}", e.message); + println!("{}", e.response); + }, + } + + println!("Invalid endpoint URL: htp://cloud.appwrite.io/v1"); + + let _ = general.empty().await; + + // Test Queries + test_queries(); + + // Test Permission Helpers + test_permission_helpers(); + + // Test Id Helpers + test_id_helpers(); + + // Final test + match general.headers().await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("general.headers => error {}", e), + } + + Ok(()) +} + +async fn test_general_upload(client: &Client, string_in_array: &[String]) -> Result<(), Box> { + let general = General::new(&client); + let upload_file = Path::new("/app/tests/resources/file.png"); + + match InputFile::from_path(upload_file, None).await { + Ok(input_file) => { + match general.upload("string", 123, string_in_array, input_file).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("general.upload => error {}", e), + } + }, + Err(e) => eprintln!("Failed to read file: {}", e), + } + + Ok(()) +} + +async fn test_general_download(client: &Client) -> Result<(), Box> { + let general = General::new(&client); + + match general.download().await { + Ok(response) => { + // Convert bytes to string for display + if let Ok(response_str) = String::from_utf8(response) { + println!("{}", response_str); + } + }, + Err(e) => eprintln!("general.download => error {}", e), + } + + Ok(()) +} + +async fn test_large_upload(client: &Client, string_in_array: &[String]) -> Result<(), Box> { + let general = General::new(&client); + let upload_file = Path::new("/app/tests/resources/large_file.mp4"); + + match InputFile::from_path(upload_file, None).await { + Ok(input_file) => { + match general.upload("string", 123, string_in_array, input_file).await { + Ok(response) => println!("{}", response.result), + Err(e) => eprintln!("general.upload => error {}", e), + } + }, + Err(e) => eprintln!("Failed to read large file: {}", e), + } + + Ok(()) +} + +fn test_queries() { + println!("{}", Query::equal("released", true)); + println!("{}", Query::equal("title", vec!["Spiderman", "Dr. Strange"])); + println!("{}", Query::not_equal("title", "Spiderman")); + println!("{}", Query::less_than("releasedYear", 1990)); + println!("{}", Query::greater_than("releasedYear", 1990)); + println!("{}", Query::search("name", "john")); + println!("{}", Query::is_null("name")); + println!("{}", Query::is_not_null("name")); + println!("{}", Query::between("age", 50, 100)); + println!("{}", Query::between("age", 50.5, 100.5)); + println!("{}", Query::between("name", "Anna", "Brad")); + println!("{}", Query::starts_with("name", "Ann")); + println!("{}", Query::ends_with("name", "nne")); + println!("{}", Query::select(vec!["name", "age"])); + println!("{}", Query::order_asc("title")); + println!("{}", Query::order_desc("title")); + println!("{}", Query::order_random()); + println!("{}", Query::cursor_after("my_movie_id")); + println!("{}", Query::cursor_before("my_movie_id")); + println!("{}", Query::limit(50)); + println!("{}", Query::offset(20)); + println!("{}", Query::contains("title", "Spider")); + println!("{}", Query::contains("labels", "first")); + println!("{}", Query::contains_any("labels", vec!["first", "second"])); + println!("{}", Query::contains_all("labels", vec!["first", "second"])); + println!("{}", Query::not_contains("title", "Spider")); + println!("{}", Query::not_search("name", "john")); + println!("{}", Query::not_between("age", 50, 100)); + println!("{}", Query::not_starts_with("name", "Ann")); + println!("{}", Query::not_ends_with("name", "nne")); + println!("{}", Query::created_before("2023-01-01")); + println!("{}", Query::created_after("2023-01-01")); + println!("{}", Query::created_between("2023-01-01", "2023-12-31")); + println!("{}", Query::updated_before("2023-01-01")); + println!("{}", Query::updated_after("2023-01-01")); + println!("{}", Query::updated_between("2023-01-01", "2023-12-31")); + println!("{}", Query::distance_equal("location", json!([[40.7128, -74], [40.7128, -74]]), 1000, true)); + println!("{}", Query::distance_equal("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::distance_not_equal("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::distance_not_equal("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::distance_greater_than("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::distance_greater_than("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::distance_less_than("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::distance_less_than("location", json!([40.7128, -74]), 1000, true)); + println!("{}", Query::intersects("location", json!([40.7128, -74]))); + println!("{}", Query::not_intersects("location", json!([40.7128, -74]))); + println!("{}", Query::crosses("location", json!([40.7128, -74]))); + println!("{}", Query::not_crosses("location", json!([40.7128, -74]))); + println!("{}", Query::overlaps("location", json!([40.7128, -74]))); + println!("{}", Query::not_overlaps("location", json!([40.7128, -74]))); + println!("{}", Query::touches("location", json!([40.7128, -74]))); + println!("{}", Query::not_touches("location", json!([40.7128, -74]))); + println!("{}", Query::contains("location", json!([[40.7128, -74], [40.7128, -74]]))); + println!("{}", Query::not_contains("location", json!([[40.7128, -74], [40.7128, -74]]))); + println!("{}", Query::equal("location", json!([[40.7128, -74], [40.7128, -74]]))); + println!("{}", Query::not_equal("location", json!([[40.7128, -74], [40.7128, -74]]))); + println!("{}", Query::or(vec![ + Query::equal("released", true).to_string(), + Query::less_than("releasedYear", 1990).to_string(), + ])); + println!("{}", Query::and(vec![ + Query::equal("released", false).to_string(), + Query::greater_than("releasedYear", 2015).to_string(), + ])); + println!("{}", Query::regex("name", "pattern.*")); + println!("{}", Query::exists(vec!["attr1", "attr2"])); + println!("{}", Query::not_exists(vec!["attr1", "attr2"])); + println!("{}", Query::elem_match("friends", vec![ + Query::equal("name", "Alice").to_string(), + Query::greater_than("age", 18).to_string(), + ])); +} + +fn test_permission_helpers() { + println!("{}", Permission::read(&Role::any().to_string())); + println!("{}", Permission::write(&Role::user(ID::custom("userid"), None).to_string())); + println!("{}", Permission::create(&Role::users(None).to_string())); + println!("{}", Permission::update(&Role::guests().to_string())); + println!("{}", Permission::delete(&Role::team("teamId", Some("owner")).to_string())); + println!("{}", Permission::delete(&Role::team("teamId", None::<&str>).to_string())); + println!("{}", Permission::create(&Role::member("memberId").to_string())); + println!("{}", Permission::update(&Role::users(Some("verified")).to_string())); + println!("{}", Permission::update(&Role::user(ID::custom("userid"), Some("unverified")).to_string())); + println!("{}", Permission::create(&Role::label("admin").to_string())); +} + +fn test_id_helpers() { + println!("{}", ID::unique()); + println!("{}", ID::custom("custom_id")); +} From ee9d00724c388863d4d35337a400cf98e7ccb535 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 23 Mar 2026 12:36:37 +0000 Subject: [PATCH 2/2] chore: update Rust SDK to 0.1.0 --- CHANGELOG.md | 4 ++-- Cargo.toml | 2 +- README.md | 2 +- src/client.rs | 4 ++-- src/lib.rs | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b84ce63..b4dc1a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.1.1] - TBD +## [0.1.0] - TBD ### Added - Initial release of Appwrite Rust SDK @@ -849,4 +849,4 @@ If you want to generate a token for a custom authentication flow, use the [POST - File upload examples - Query builder documentation -[0.1.1]: https://github.com/appwrite/sdk-for-rust/releases/tag/0.1.1 +[0.1.0]: https://github.com/appwrite/sdk-for-rust/releases/tag/0.1.0 diff --git a/Cargo.toml b/Cargo.toml index c38baea..b705a6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "appwrite" -version = "0.1.1" +version = "0.1.0" edition = "2021" rust-version = "1.83" authors = ["appwrite"] diff --git a/README.md b/README.md index 3317665..0fd6227 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -appwrite = "0.1.1" +appwrite = "0.1.0" tokio = { version = "1.48", features = ["full"] } ``` diff --git a/src/client.rs b/src/client.rs index 3ef3d65..40a0f55 100644 --- a/src/client.rs +++ b/src/client.rs @@ -89,11 +89,11 @@ impl Client { pub fn new() -> Self { let mut headers = HeaderMap::new(); headers.insert("X-Appwrite-Response-Format", "1.9.0".parse().unwrap()); - headers.insert("user-agent", format!("AppwriteRustSDK/0.1.1 ({}; {})", std::env::consts::OS, std::env::consts::ARCH).parse().unwrap()); + headers.insert("user-agent", format!("AppwriteRustSDK/0.1.0 ({}; {})", std::env::consts::OS, std::env::consts::ARCH).parse().unwrap()); headers.insert("x-sdk-name", "Rust".parse().unwrap()); headers.insert("x-sdk-platform", "server".parse().unwrap()); headers.insert("x-sdk-language", "rust".parse().unwrap()); - headers.insert("x-sdk-version", "0.1.1".parse().unwrap()); + headers.insert("x-sdk-version", "0.1.0".parse().unwrap()); let config = Config { endpoint: "https://cloud.appwrite.io/v1".to_string(), diff --git a/src/lib.rs b/src/lib.rs index 161b3ce..88050cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ //! //! ```toml //! [dependencies] -//! appwrite = "0.1.1" +//! appwrite = "0.1.0" //! ``` //! //! ## Usage @@ -51,7 +51,7 @@ pub use input_file::InputFile; pub type Result = std::result::Result; /// SDK version -pub const VERSION: &str = "0.1.1"; +pub const VERSION: &str = "0.1.0"; /// SDK name pub const SDK_NAME: &str = "Rust";