@ngxtm/devkit 3.4.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
- package/skills/learn/SKILL.md +476 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Rust Core
|
|
3
|
+
description: Rust language fundamentals, ownership, error handling, and project patterns.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [rust, core, language]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['Cargo.toml', '**/*.rs']
|
|
8
|
+
keywords: [fn, impl, struct, enum, Result, Option]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Rust Core Standards
|
|
12
|
+
|
|
13
|
+
## Ownership & Borrowing
|
|
14
|
+
|
|
15
|
+
1. **Ownership Rules**:
|
|
16
|
+
- Each value has exactly one owner
|
|
17
|
+
- Value dropped when owner goes out of scope
|
|
18
|
+
- **Do**: Move or clone explicitly when needed
|
|
19
|
+
- **Don't**: Fight the borrow checker with unsafe
|
|
20
|
+
|
|
21
|
+
2. **Borrowing**:
|
|
22
|
+
- Immutable: `&T` - multiple allowed
|
|
23
|
+
- Mutable: `&mut T` - only one, no immutable refs
|
|
24
|
+
- **Rule**: References must not outlive data
|
|
25
|
+
|
|
26
|
+
## Error Handling
|
|
27
|
+
|
|
28
|
+
```rust
|
|
29
|
+
// Use Result for recoverable errors
|
|
30
|
+
fn parse_config(path: &str) -> Result<Config, ConfigError> {
|
|
31
|
+
let content = std::fs::read_to_string(path)?;
|
|
32
|
+
toml::from_str(&content).map_err(ConfigError::Parse)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Use Option for optional values
|
|
36
|
+
fn find_user(id: u64) -> Option<User> { /* ... */ }
|
|
37
|
+
|
|
38
|
+
// Custom error types
|
|
39
|
+
#[derive(Debug, thiserror::Error)]
|
|
40
|
+
enum AppError {
|
|
41
|
+
#[error("database error: {0}")]
|
|
42
|
+
Database(#[from] sqlx::Error),
|
|
43
|
+
#[error("not found: {0}")]
|
|
44
|
+
NotFound(String),
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Patterns**:
|
|
49
|
+
- `?` operator for propagation
|
|
50
|
+
- `thiserror` for library errors
|
|
51
|
+
- `anyhow` for application errors
|
|
52
|
+
- **Never**: `unwrap()` in production code (use `expect` with context)
|
|
53
|
+
|
|
54
|
+
## Async/Await
|
|
55
|
+
|
|
56
|
+
- **Runtime**: Tokio for production
|
|
57
|
+
- **Rule**: Async functions return `Future`, need executor
|
|
58
|
+
|
|
59
|
+
```rust
|
|
60
|
+
#[tokio::main]
|
|
61
|
+
async fn main() {
|
|
62
|
+
let result = fetch_data().await;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async fn fetch_data() -> Result<Data, Error> {
|
|
66
|
+
let response = reqwest::get("https://api.example.com").await?;
|
|
67
|
+
response.json().await.map_err(Into::into)
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Concurrency Patterns**:
|
|
72
|
+
- `tokio::spawn` for background tasks
|
|
73
|
+
- `tokio::select!` for racing futures
|
|
74
|
+
- `tokio::sync::Mutex` for shared async state
|
|
75
|
+
- **Warning**: `std::sync::Mutex` blocks; use `tokio::sync` in async
|
|
76
|
+
|
|
77
|
+
## Traits & Generics
|
|
78
|
+
|
|
79
|
+
```rust
|
|
80
|
+
// Define trait bounds
|
|
81
|
+
fn process<T: Serialize + Debug>(item: T) -> String { /* ... */ }
|
|
82
|
+
|
|
83
|
+
// Impl blocks
|
|
84
|
+
impl<T: Clone> Container<T> {
|
|
85
|
+
fn duplicate(&self) -> Self { /* ... */ }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Associated types for clarity
|
|
89
|
+
trait Iterator {
|
|
90
|
+
type Item;
|
|
91
|
+
fn next(&mut self) -> Option<Self::Item>;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Best Practices**:
|
|
96
|
+
- Prefer `impl Trait` for return types
|
|
97
|
+
- Use `where` clauses for complex bounds
|
|
98
|
+
- `#[derive]` for common traits: `Debug, Clone, PartialEq`
|
|
99
|
+
|
|
100
|
+
## Project Structure
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
my-project/
|
|
104
|
+
├── Cargo.toml
|
|
105
|
+
├── src/
|
|
106
|
+
│ ├── main.rs # Entry point
|
|
107
|
+
│ ├── lib.rs # Library root (optional)
|
|
108
|
+
│ ├── config.rs # Configuration
|
|
109
|
+
│ ├── error.rs # Error types
|
|
110
|
+
│ ├── handlers/ # Request handlers
|
|
111
|
+
│ │ └── mod.rs
|
|
112
|
+
│ └── models/ # Data structures
|
|
113
|
+
│ └── mod.rs
|
|
114
|
+
└── tests/
|
|
115
|
+
└── integration.rs # Integration tests
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Conventions**:
|
|
119
|
+
- `mod.rs` for module roots
|
|
120
|
+
- `pub` only what's needed
|
|
121
|
+
- Re-export with `pub use` at module root
|
|
122
|
+
|
|
123
|
+
## Testing
|
|
124
|
+
|
|
125
|
+
```rust
|
|
126
|
+
#[cfg(test)]
|
|
127
|
+
mod tests {
|
|
128
|
+
use super::*;
|
|
129
|
+
|
|
130
|
+
#[test]
|
|
131
|
+
fn test_parse() {
|
|
132
|
+
let result = parse("valid");
|
|
133
|
+
assert_eq!(result, Ok(Expected));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#[tokio::test]
|
|
137
|
+
async fn test_async_fn() {
|
|
138
|
+
let data = fetch().await;
|
|
139
|
+
assert!(data.is_ok());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
- Unit tests in same file with `#[cfg(test)]`
|
|
145
|
+
- Integration tests in `tests/` directory
|
|
146
|
+
- Use `mockall` for mocking traits
|
|
147
|
+
|
|
148
|
+
## Security
|
|
149
|
+
|
|
150
|
+
1. **Input Validation**: Validate all external input before processing
|
|
151
|
+
2. **SQL Injection**: Use parameterized queries (sqlx, diesel)
|
|
152
|
+
3. **Dependencies**: Run `cargo audit` regularly
|
|
153
|
+
4. **Unsafe**: Minimize `unsafe` blocks, document invariants
|
|
154
|
+
5. **Secrets**: Use `secrecy` crate for sensitive data in memory
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Rust Core References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**Error Handling**](error-handling.md) - Result, thiserror, anyhow patterns
|
|
6
|
+
- [**Ownership Patterns**](ownership-patterns.md) - Borrowing, lifetimes, smart pointers
|
|
7
|
+
|
|
8
|
+
## Quick Checks
|
|
9
|
+
|
|
10
|
+
- [ ] Use Result for fallible operations
|
|
11
|
+
- [ ] Use thiserror for library errors, anyhow for applications
|
|
12
|
+
- [ ] Prefer borrowing over ownership transfer
|
|
13
|
+
- [ ] Use `?` operator for error propagation
|
|
14
|
+
- [ ] Derive Clone, Debug for data types
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Error Handling Patterns
|
|
2
|
+
|
|
3
|
+
## Using thiserror (Libraries)
|
|
4
|
+
|
|
5
|
+
```rust
|
|
6
|
+
use thiserror::Error;
|
|
7
|
+
|
|
8
|
+
#[derive(Error, Debug)]
|
|
9
|
+
pub enum UserError {
|
|
10
|
+
#[error("user not found: {0}")]
|
|
11
|
+
NotFound(String),
|
|
12
|
+
|
|
13
|
+
#[error("invalid email format")]
|
|
14
|
+
InvalidEmail,
|
|
15
|
+
|
|
16
|
+
#[error("database error")]
|
|
17
|
+
Database(#[from] sqlx::Error),
|
|
18
|
+
|
|
19
|
+
#[error("validation failed: {field} - {message}")]
|
|
20
|
+
Validation { field: String, message: String },
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Usage
|
|
24
|
+
fn find_user(id: &str) -> Result<User, UserError> {
|
|
25
|
+
let user = db.find(id).map_err(UserError::Database)?;
|
|
26
|
+
user.ok_or_else(|| UserError::NotFound(id.to_string()))
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Using anyhow (Applications)
|
|
31
|
+
|
|
32
|
+
```rust
|
|
33
|
+
use anyhow::{Context, Result, bail};
|
|
34
|
+
|
|
35
|
+
fn process_config(path: &str) -> Result<Config> {
|
|
36
|
+
let content = std::fs::read_to_string(path)
|
|
37
|
+
.context("failed to read config file")?;
|
|
38
|
+
|
|
39
|
+
let config: Config = serde_json::from_str(&content)
|
|
40
|
+
.context("failed to parse config")?;
|
|
41
|
+
|
|
42
|
+
if config.port == 0 {
|
|
43
|
+
bail!("port cannot be zero");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Ok(config)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// In main
|
|
50
|
+
fn main() -> Result<()> {
|
|
51
|
+
let config = process_config("config.json")?;
|
|
52
|
+
run_server(config)?;
|
|
53
|
+
Ok(())
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Error Conversion
|
|
58
|
+
|
|
59
|
+
```rust
|
|
60
|
+
// From trait for automatic conversion
|
|
61
|
+
impl From<std::io::Error> for AppError {
|
|
62
|
+
fn from(err: std::io::Error) -> Self {
|
|
63
|
+
AppError::Io(err.to_string())
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Or use #[from] with thiserror
|
|
68
|
+
#[derive(Error, Debug)]
|
|
69
|
+
pub enum AppError {
|
|
70
|
+
#[error("IO error: {0}")]
|
|
71
|
+
Io(#[from] std::io::Error),
|
|
72
|
+
|
|
73
|
+
#[error("Parse error: {0}")]
|
|
74
|
+
Parse(#[from] serde_json::Error),
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Pattern Matching Errors
|
|
79
|
+
|
|
80
|
+
```rust
|
|
81
|
+
match result {
|
|
82
|
+
Ok(value) => println!("Success: {}", value),
|
|
83
|
+
Err(UserError::NotFound(id)) => println!("User {} not found", id),
|
|
84
|
+
Err(UserError::InvalidEmail) => println!("Invalid email"),
|
|
85
|
+
Err(e) => println!("Other error: {}", e),
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Or with if let
|
|
89
|
+
if let Err(UserError::NotFound(id)) = result {
|
|
90
|
+
// handle not found
|
|
91
|
+
}
|
|
92
|
+
```
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Diesel ORM
|
|
3
|
+
description: Type-safe Rust ORM with compile-time query validation.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [rust, diesel, orm, database, postgresql]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/schema.rs', 'diesel.toml']
|
|
8
|
+
keywords: [diesel, Queryable, Insertable, table]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Diesel ORM Standards
|
|
12
|
+
|
|
13
|
+
## Schema Definition
|
|
14
|
+
|
|
15
|
+
```rust
|
|
16
|
+
// Generated by diesel migration run
|
|
17
|
+
// src/schema.rs
|
|
18
|
+
diesel::table! {
|
|
19
|
+
users (id) {
|
|
20
|
+
id -> Int4,
|
|
21
|
+
name -> Varchar,
|
|
22
|
+
email -> Varchar,
|
|
23
|
+
created_at -> Timestamp,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Model Structs
|
|
29
|
+
|
|
30
|
+
```rust
|
|
31
|
+
use diesel::prelude::*;
|
|
32
|
+
use crate::schema::users;
|
|
33
|
+
|
|
34
|
+
#[derive(Queryable, Selectable, Debug)]
|
|
35
|
+
#[diesel(table_name = users)]
|
|
36
|
+
pub struct User {
|
|
37
|
+
pub id: i32,
|
|
38
|
+
pub name: String,
|
|
39
|
+
pub email: String,
|
|
40
|
+
pub created_at: NaiveDateTime,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[derive(Insertable)]
|
|
44
|
+
#[diesel(table_name = users)]
|
|
45
|
+
pub struct NewUser<'a> {
|
|
46
|
+
pub name: &'a str,
|
|
47
|
+
pub email: &'a str,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#[derive(AsChangeset)]
|
|
51
|
+
#[diesel(table_name = users)]
|
|
52
|
+
pub struct UpdateUser<'a> {
|
|
53
|
+
pub name: Option<&'a str>,
|
|
54
|
+
pub email: Option<&'a str>,
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Connection Pool
|
|
59
|
+
|
|
60
|
+
```rust
|
|
61
|
+
use diesel::pg::PgConnection;
|
|
62
|
+
use diesel::r2d2::{Pool, ConnectionManager};
|
|
63
|
+
|
|
64
|
+
type DbPool = Pool<ConnectionManager<PgConnection>>;
|
|
65
|
+
|
|
66
|
+
fn establish_pool(database_url: &str) -> DbPool {
|
|
67
|
+
let manager = ConnectionManager::<PgConnection>::new(database_url);
|
|
68
|
+
Pool::builder()
|
|
69
|
+
.max_size(15)
|
|
70
|
+
.build(manager)
|
|
71
|
+
.expect("Failed to create pool")
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## CRUD Operations
|
|
76
|
+
|
|
77
|
+
```rust
|
|
78
|
+
use diesel::prelude::*;
|
|
79
|
+
use crate::schema::users::dsl::*;
|
|
80
|
+
|
|
81
|
+
// Create
|
|
82
|
+
fn create_user(conn: &mut PgConnection, new_user: &NewUser) -> QueryResult<User> {
|
|
83
|
+
diesel::insert_into(users)
|
|
84
|
+
.values(new_user)
|
|
85
|
+
.get_result(conn)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Read
|
|
89
|
+
fn find_user(conn: &mut PgConnection, user_id: i32) -> QueryResult<User> {
|
|
90
|
+
users.find(user_id).first(conn)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fn list_users(conn: &mut PgConnection) -> QueryResult<Vec<User>> {
|
|
94
|
+
users.load(conn)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Update
|
|
98
|
+
fn update_user(conn: &mut PgConnection, user_id: i32, changes: &UpdateUser) -> QueryResult<User> {
|
|
99
|
+
diesel::update(users.find(user_id))
|
|
100
|
+
.set(changes)
|
|
101
|
+
.get_result(conn)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Delete
|
|
105
|
+
fn delete_user(conn: &mut PgConnection, user_id: i32) -> QueryResult<usize> {
|
|
106
|
+
diesel::delete(users.find(user_id)).execute(conn)
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Query Building
|
|
111
|
+
|
|
112
|
+
```rust
|
|
113
|
+
// Filtering
|
|
114
|
+
let active_users = users
|
|
115
|
+
.filter(active.eq(true))
|
|
116
|
+
.filter(created_at.gt(cutoff_date))
|
|
117
|
+
.load::<User>(conn)?;
|
|
118
|
+
|
|
119
|
+
// Ordering and pagination
|
|
120
|
+
let page = users
|
|
121
|
+
.order(created_at.desc())
|
|
122
|
+
.limit(10)
|
|
123
|
+
.offset(20)
|
|
124
|
+
.load::<User>(conn)?;
|
|
125
|
+
|
|
126
|
+
// Select specific columns
|
|
127
|
+
let emails: Vec<String> = users
|
|
128
|
+
.select(email)
|
|
129
|
+
.load(conn)?;
|
|
130
|
+
|
|
131
|
+
// Joins
|
|
132
|
+
let user_posts = users
|
|
133
|
+
.inner_join(posts::table)
|
|
134
|
+
.select((users::name, posts::title))
|
|
135
|
+
.load::<(String, String)>(conn)?;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Transactions
|
|
139
|
+
|
|
140
|
+
```rust
|
|
141
|
+
conn.transaction(|conn| {
|
|
142
|
+
diesel::insert_into(users)
|
|
143
|
+
.values(&new_user)
|
|
144
|
+
.execute(conn)?;
|
|
145
|
+
|
|
146
|
+
diesel::insert_into(audit_log)
|
|
147
|
+
.values(&log_entry)
|
|
148
|
+
.execute(conn)?;
|
|
149
|
+
|
|
150
|
+
Ok(())
|
|
151
|
+
})
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Migrations
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Create migration
|
|
158
|
+
diesel migration generate create_users
|
|
159
|
+
|
|
160
|
+
# Run pending migrations
|
|
161
|
+
diesel migration run
|
|
162
|
+
|
|
163
|
+
# Revert last migration
|
|
164
|
+
diesel migration revert
|
|
165
|
+
|
|
166
|
+
# Redo last migration
|
|
167
|
+
diesel migration redo
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Best Practices
|
|
171
|
+
|
|
172
|
+
1. **Schema sync**: Run `diesel migration run` before compile
|
|
173
|
+
2. **Pool sizing**: Match to expected concurrent connections
|
|
174
|
+
3. **Derive macros**: Use `Queryable` for reads, `Insertable` for writes
|
|
175
|
+
4. **Nullable**: Use `Option<T>` for nullable columns
|
|
176
|
+
5. **Raw SQL**: Use `sql_query()` for complex queries when needed
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Diesel ORM References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**Schema Patterns**](schema-patterns.md) - Models, queries, associations
|
|
6
|
+
|
|
7
|
+
## Quick Checks
|
|
8
|
+
|
|
9
|
+
- [ ] Use diesel CLI for migrations
|
|
10
|
+
- [ ] Derive Queryable for reads
|
|
11
|
+
- [ ] Derive Insertable for writes
|
|
12
|
+
- [ ] Type-safe query DSL
|
|
13
|
+
- [ ] Connection pooling with r2d2
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Diesel Schema Patterns
|
|
2
|
+
|
|
3
|
+
## Schema Definition
|
|
4
|
+
|
|
5
|
+
```rust
|
|
6
|
+
// schema.rs (generated by diesel)
|
|
7
|
+
diesel::table! {
|
|
8
|
+
users (id) {
|
|
9
|
+
id -> Int4,
|
|
10
|
+
name -> Varchar,
|
|
11
|
+
email -> Varchar,
|
|
12
|
+
active -> Bool,
|
|
13
|
+
created_at -> Timestamp,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
diesel::table! {
|
|
18
|
+
posts (id) {
|
|
19
|
+
id -> Int4,
|
|
20
|
+
title -> Varchar,
|
|
21
|
+
body -> Text,
|
|
22
|
+
user_id -> Int4,
|
|
23
|
+
published -> Bool,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
diesel::joinable!(posts -> users (user_id));
|
|
28
|
+
diesel::allow_tables_to_appear_in_same_query!(users, posts);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Models
|
|
32
|
+
|
|
33
|
+
```rust
|
|
34
|
+
use diesel::prelude::*;
|
|
35
|
+
use crate::schema::users;
|
|
36
|
+
|
|
37
|
+
#[derive(Queryable, Selectable, Debug)]
|
|
38
|
+
#[diesel(table_name = users)]
|
|
39
|
+
pub struct User {
|
|
40
|
+
pub id: i32,
|
|
41
|
+
pub name: String,
|
|
42
|
+
pub email: String,
|
|
43
|
+
pub active: bool,
|
|
44
|
+
pub created_at: chrono::NaiveDateTime,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#[derive(Insertable)]
|
|
48
|
+
#[diesel(table_name = users)]
|
|
49
|
+
pub struct NewUser<'a> {
|
|
50
|
+
pub name: &'a str,
|
|
51
|
+
pub email: &'a str,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#[derive(AsChangeset)]
|
|
55
|
+
#[diesel(table_name = users)]
|
|
56
|
+
pub struct UpdateUser<'a> {
|
|
57
|
+
pub name: Option<&'a str>,
|
|
58
|
+
pub email: Option<&'a str>,
|
|
59
|
+
pub active: Option<bool>,
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## CRUD Operations
|
|
64
|
+
|
|
65
|
+
```rust
|
|
66
|
+
use diesel::prelude::*;
|
|
67
|
+
use crate::schema::users::dsl::*;
|
|
68
|
+
|
|
69
|
+
// Create
|
|
70
|
+
fn create_user(conn: &mut PgConnection, user_name: &str, user_email: &str) -> QueryResult<User> {
|
|
71
|
+
let new_user = NewUser {
|
|
72
|
+
name: user_name,
|
|
73
|
+
email: user_email,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
diesel::insert_into(users)
|
|
77
|
+
.values(&new_user)
|
|
78
|
+
.returning(User::as_returning())
|
|
79
|
+
.get_result(conn)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Read
|
|
83
|
+
fn find_user(conn: &mut PgConnection, user_id: i32) -> QueryResult<Option<User>> {
|
|
84
|
+
users.find(user_id).first(conn).optional()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
fn list_active_users(conn: &mut PgConnection) -> QueryResult<Vec<User>> {
|
|
88
|
+
users
|
|
89
|
+
.filter(active.eq(true))
|
|
90
|
+
.order(name.asc())
|
|
91
|
+
.limit(10)
|
|
92
|
+
.load(conn)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Update
|
|
96
|
+
fn update_user(conn: &mut PgConnection, user_id: i32, new_name: &str) -> QueryResult<User> {
|
|
97
|
+
diesel::update(users.find(user_id))
|
|
98
|
+
.set(name.eq(new_name))
|
|
99
|
+
.returning(User::as_returning())
|
|
100
|
+
.get_result(conn)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fn update_user_partial(conn: &mut PgConnection, user_id: i32, changes: &UpdateUser) -> QueryResult<User> {
|
|
104
|
+
diesel::update(users.find(user_id))
|
|
105
|
+
.set(changes)
|
|
106
|
+
.returning(User::as_returning())
|
|
107
|
+
.get_result(conn)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Delete
|
|
111
|
+
fn delete_user(conn: &mut PgConnection, user_id: i32) -> QueryResult<usize> {
|
|
112
|
+
diesel::delete(users.find(user_id)).execute(conn)
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Associations
|
|
117
|
+
|
|
118
|
+
```rust
|
|
119
|
+
use diesel::prelude::*;
|
|
120
|
+
|
|
121
|
+
#[derive(Queryable, Identifiable, Selectable)]
|
|
122
|
+
#[diesel(table_name = users)]
|
|
123
|
+
pub struct User {
|
|
124
|
+
pub id: i32,
|
|
125
|
+
pub name: String,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#[derive(Queryable, Identifiable, Selectable, Associations)]
|
|
129
|
+
#[diesel(belongs_to(User))]
|
|
130
|
+
#[diesel(table_name = posts)]
|
|
131
|
+
pub struct Post {
|
|
132
|
+
pub id: i32,
|
|
133
|
+
pub title: String,
|
|
134
|
+
pub user_id: i32,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
fn posts_for_user(conn: &mut PgConnection, user: &User) -> QueryResult<Vec<Post>> {
|
|
138
|
+
Post::belonging_to(user)
|
|
139
|
+
.select(Post::as_select())
|
|
140
|
+
.load(conn)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fn users_with_posts(conn: &mut PgConnection) -> QueryResult<Vec<(User, Vec<Post>)>> {
|
|
144
|
+
let all_users = users::table.load::<User>(conn)?;
|
|
145
|
+
let all_posts = Post::belonging_to(&all_users)
|
|
146
|
+
.select(Post::as_select())
|
|
147
|
+
.load(conn)?;
|
|
148
|
+
|
|
149
|
+
Ok(all_posts.grouped_by(&all_users)
|
|
150
|
+
.into_iter()
|
|
151
|
+
.zip(all_users)
|
|
152
|
+
.map(|(posts, user)| (user, posts))
|
|
153
|
+
.collect())
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Connection Pool
|
|
158
|
+
|
|
159
|
+
```rust
|
|
160
|
+
use diesel::r2d2::{ConnectionManager, Pool};
|
|
161
|
+
|
|
162
|
+
type DbPool = Pool<ConnectionManager<PgConnection>>;
|
|
163
|
+
|
|
164
|
+
fn establish_pool(database_url: &str) -> DbPool {
|
|
165
|
+
let manager = ConnectionManager::<PgConnection>::new(database_url);
|
|
166
|
+
Pool::builder()
|
|
167
|
+
.max_size(10)
|
|
168
|
+
.build(manager)
|
|
169
|
+
.expect("Failed to create pool")
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Usage
|
|
173
|
+
let pool = establish_pool("postgres://localhost/mydb");
|
|
174
|
+
let mut conn = pool.get().expect("Failed to get connection");
|
|
175
|
+
let users = list_active_users(&mut conn)?;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Migrations
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Install CLI
|
|
182
|
+
cargo install diesel_cli --no-default-features --features postgres
|
|
183
|
+
|
|
184
|
+
# Setup
|
|
185
|
+
diesel setup
|
|
186
|
+
|
|
187
|
+
# Create migration
|
|
188
|
+
diesel migration generate create_users
|
|
189
|
+
|
|
190
|
+
# Run migrations
|
|
191
|
+
diesel migration run
|
|
192
|
+
|
|
193
|
+
# Revert
|
|
194
|
+
diesel migration revert
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```sql
|
|
198
|
+
-- migrations/00000000000000_create_users/up.sql
|
|
199
|
+
CREATE TABLE users (
|
|
200
|
+
id SERIAL PRIMARY KEY,
|
|
201
|
+
name VARCHAR NOT NULL,
|
|
202
|
+
email VARCHAR NOT NULL UNIQUE,
|
|
203
|
+
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
204
|
+
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
205
|
+
);
|
|
206
|
+
```
|