Skip to content

Commit

Permalink
Merge branch 'master' into loco-cli-validate-project-name
Browse files Browse the repository at this point in the history
  • Loading branch information
kaplanelad authored Oct 20, 2024
2 parents ce78a88 + e3804aa commit 570f6b4
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 49 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,4 @@ insta = { version = "1.34.0", features = ["redactions", "yaml", "filters"] }
tree-fs = { version = "0.1.0" }
reqwest = { version = "0.12.7" }
serial_test = "3.1.1"
tower = { workspace = true, features = ["util"]}
113 changes: 113 additions & 0 deletions README-pt_BR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<div align="center">

<img src="https://github.com/loco-rs/loco/assets/83390/992d215a-3cd3-42ee-a1c7-de9fd25a5bac"/>

<h1>Bem-vindo ao Loco</h1>

<h3>
<!-- <snip id="description" inject_from="yaml"> -->
🚂 Loco é Rust on Rails.
<!--</snip> -->
</h3>

[![crate](https://img.shields.io/crates/v/loco-rs.svg)](https://crates.io/crates/loco-rs)
[![docs](https://docs.rs/loco-rs/badge.svg)](https://docs.rs/loco-rs)
[![Discord channel](https://img.shields.io/badge/discord-Join-us)](https://discord.gg/fTvyBzwKS8)

</div>

[English](./README.md) · [中文](./README-zh_CN.md) · [Français](./README.fr.md) · Portuguese (Brazil)


## O que é o Loco?
`Loco` é fortemente inspirado no Rails. Se você conhece Rails e Rust, se sentirá em casa. Se você só conhece Rails e é novo em Rust, achará o Loco refrescante. Não presumimos que você conheça o Rails.

Para uma imersão mais profunda em como o Loco funciona, incluindo guias detalhados, exemplos e referências da API, confira nosso [site de documentação](https://loco.rs).


## Recursos do Loco:

* `Convenção sobre Configuração:` Semelhante ao Ruby on Rails, o Loco enfatiza simplicidade e produtividade ao reduzir a necessidade de código boilerplate. Ele utiliza padrões sensatos, permitindo que os desenvolvedores se concentrem em escrever a lógica de negócios em vez de perder tempo com configuração.

* `Desenvolvimento Rápido:` Com o objetivo de alta produtividade para o desenvolvedor, o design do Loco se concentra em reduzir código boilerplate e fornecer APIs intuitivas, permitindo que os desenvolvedores iteren rapidamente e construam protótipos com esforço mínimo.

* `Integração ORM:` Modele seu negócio com entidades robustas, eliminando a necessidade de escrever SQL. Defina relacionamentos, validações e lógica personalizada diretamente em suas entidades para melhorar a manutenção e escalabilidade.

* `Controladores:` Manipule os parâmetros de solicitações web, corpo, validação e renderize uma resposta que é consciente do conteúdo. Usamos Axum para o melhor desempenho, simplicidade e extensibilidade. Os controladores também permitem que você construa facilmente middlewares, que podem ser usados para adicionar lógica como autenticação, registro ou tratamento de erros antes de passar as solicitações para as ações principais do controlador.

* `Views:` O Loco pode se integrar com mecanismos de template para gerar conteúdo HTML dinâmico a partir de templates.

* `Trabalhos em segundo plano:` Realize trabalhos intensivos de computação ou I/O em segundo plano com uma fila baseada em Redis ou com threads. Implementar um trabalhador é tão simples quanto implementar uma função de execução para o trait Worker.

* `Scheduler:` Simplifica o tradicional e frequentemente complicado sistema crontab, tornando mais fácil e elegante agendar tarefas ou scripts shell.

* `Mailers:` Um mailer entregará e-mails em segundo plano usando a infraestrutura de trabalhador existente do loco. Tudo será transparente para você.

* `Armazenamento:` No Armazenamento do Loco, facilitamos o trabalho com arquivos por meio de várias operações. O armazenamento pode ser em memória, no disco ou utilizar serviços em nuvem, como AWS S3, GCP e Azure.

* `Cache:` O Loco fornece uma camada de cache para melhorar o desempenho da aplicação armazenando dados acessados frequentemente.

Para ver mais recursos do Loco, confira nosso [site de documentação](https://loco.rs/docs/getting-started/tour/).



## Começando
<!-- <snip id="quick-installation-command" inject_from="yaml" template="sh"> -->
```sh
cargo install loco-cli
cargo install sea-orm-cli # Only when DB is needed
```
<!-- </snip> -->

Agora você pode criar seu novo aplicativo (escolha "`SaaS` app").


<!-- <snip id="loco-cli-new-from-template" inject_from="yaml" template="sh"> -->
```sh
❯ loco new
✔ ❯ App name? · myapp
✔ ❯ What would you like to build? · SaaS app (with DB and user auth)
✔ ❯ Select a DB Provider · Sqlite
✔ ❯ Select your background worker type · Async (in-process tokio async tasks)
✔ ❯ Select an asset serving configuration · Client (configures assets for frontend serving)

🚂 Loco app generated successfully in:
myapp/
```
<!-- </snip> -->

Agora execute `cd` no seu `myapp` e inicie seu aplicativo:
<!-- <snip id="starting-the-server-command-with-output" inject_from="yaml" template="sh"> -->
```sh
$ cargo loco start

▄ ▀
▀ ▄
▄ ▀ ▄ ▄ ▄▀
▄ ▀▄▄
▄ ▀ ▀ ▀▄▀█▄
▀█▄
▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▀▀█
██████ █████ ███ █████ ███ █████ ███ ▀█
██████ █████ ███ █████ ▀▀▀ █████ ███ ▄█▄
██████ █████ ███ █████ █████ ███ ████▄
██████ █████ ███ █████ ▄▄▄ █████ ███ █████
██████ █████ ███ ████ ███ █████ ███ ████▀
▀▀▀██▄ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ██▀
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
https://loco.rs

listening on port 5150
```
<!-- </snip> -->

## Impulsionado pelo Loco
+ [SpectralOps](https://spectralops.io) - vários serviços impulsionados pelo framework Loco
+ [Nativish](https://nativi.sh) - backend do aplicativo impulsionado pelo framework Loco

## Contribuidores ✨
Agradecimentos a essas pessoas maravilhosas:

<a href="https://github.com/loco-rs/loco/graphs/contributors">
<img src="https://contrib.rocks/image?repo=loco-rs/loco" />
</a>
2 changes: 1 addition & 1 deletion README-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

</div>

[English](./README.md) · 中文 · [Français](./README.fr.md)
[English](./README.md) · 中文 · [Français](./README.fr.md) · [Portuguese (Brazil)](./README-pt_BR.md)

Loco 是一个用 Rust 编写的 Web 框架,类似于 Rails。Loco 提供快速构建 Web 应用的功能,并且允许创建自定义任务,可以通过 CLI 运行。

Expand Down
2 changes: 1 addition & 1 deletion README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

</div>

[English](./README.md) · [中文](./README-zh_CN.md) · Français
[English](./README.md) · [中文](./README-zh_CN.md) · Français · [Portuguese (Brazil)](./README-pt_BR.md)


## À propos de Loco
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

</div>

English · [中文](./README-zh_CN.md) · [Français](./README.fr.md)
English · [中文](./README-zh_CN.md) · [Français](./README.fr.md) · [Portuguese (Brazil)](./README-pt_BR.md)


## What's Loco?
Expand Down
32 changes: 13 additions & 19 deletions loco-extras/src/initializers/mongodb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,21 @@ fn merge_config_with_client(co: &mut ClientOptions, config: MongoDbConfig) -> Cl
co.command_event_handler = client_options
.command_event_handler
.or(co.command_event_handler.clone());
co.connect_timeout = client_options
.connect_timeout
.or(co.connect_timeout.clone());
co.connect_timeout = client_options.connect_timeout.or(co.connect_timeout);
co.credential = client_options.credential.or(co.credential.clone());
co.direct_connection = client_options
.direct_connection
.or(co.direct_connection.clone());
co.direct_connection = client_options.direct_connection.or(co.direct_connection);
co.driver_info = client_options.driver_info.or(co.driver_info.clone());
co.heartbeat_freq = client_options.heartbeat_freq.or(co.heartbeat_freq.clone());
co.load_balanced = client_options.load_balanced.or(co.load_balanced.clone());
co.local_threshold = client_options
.local_threshold
.or(co.local_threshold.clone());
co.max_idle_time = client_options.max_idle_time.or(co.max_idle_time.clone());
co.max_pool_size = client_options.max_pool_size.or(co.max_pool_size.clone());
co.min_pool_size = client_options.min_pool_size.or(co.min_pool_size.clone());
co.max_connecting = client_options.max_connecting.or(co.max_connecting.clone());
co.heartbeat_freq = client_options.heartbeat_freq.or(co.heartbeat_freq);
co.load_balanced = client_options.load_balanced.or(co.load_balanced);
co.local_threshold = client_options.local_threshold.or(co.local_threshold);
co.max_idle_time = client_options.max_idle_time.or(co.max_idle_time);
co.max_pool_size = client_options.max_pool_size.or(co.max_pool_size);
co.min_pool_size = client_options.min_pool_size.or(co.min_pool_size);
co.max_connecting = client_options.max_connecting.or(co.max_connecting);
co.read_concern = client_options.read_concern.or(co.read_concern.clone());
co.repl_set_name = client_options.repl_set_name.or(co.repl_set_name.clone());
co.retry_reads = client_options.retry_reads.or(co.retry_reads.clone());
co.retry_writes = client_options.retry_writes.or(co.retry_writes.clone());
co.retry_reads = client_options.retry_reads.or(co.retry_reads);
co.retry_writes = client_options.retry_writes.or(co.retry_writes);
co.sdam_event_handler = client_options
.sdam_event_handler
.or(co.sdam_event_handler.clone());
Expand All @@ -100,15 +94,15 @@ fn merge_config_with_client(co: &mut ClientOptions, config: MongoDbConfig) -> Cl
co.server_api = client_options.server_api.or(co.server_api.clone());
co.server_selection_timeout = client_options
.server_selection_timeout
.or(co.server_selection_timeout.clone());
.or(co.server_selection_timeout);
co.default_database = client_options
.default_database
.or(co.default_database.clone());
co.tls = client_options.tls.or(co.tls.clone());
// co.tracing_max_document_length_bytes =
// client_options.tracing_max_document_length_bytes;
co.write_concern = client_options.write_concern.or(co.write_concern.clone());
co.srv_max_hosts = client_options.srv_max_hosts.or(co.srv_max_hosts.clone());
co.srv_max_hosts = client_options.srv_max_hosts.or(co.srv_max_hosts);

co.clone()
}
Expand Down
2 changes: 1 addition & 1 deletion loco-extras/src/initializers/opentelemetry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl Initializer for OpenTelemetryInitializer {

async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
let router = router
.layer(OtelInResponseLayer::default())
.layer(OtelInResponseLayer)
.layer(OtelAxumLayer::default());
Ok(router)
}
Expand Down
6 changes: 5 additions & 1 deletion macros/tests/attr_macro.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// tests/attribute_macro.rs

#[allow(unused)]
use loco_macros::*;

// macro converts struct S to struct H

#[test]
//#[test_request]
fn test_macro() {
assert!(true);
#[allow(clippy::assertions_on_constants)]
{
assert!(true);
}
}
5 changes: 3 additions & 2 deletions src/bgworker/skq.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::{marker::PhantomData, sync::Arc};

use super::{BackgroundWorker, Queue};
use crate::{config::RedisQueueConfig, Result};
use async_trait::async_trait;
use bb8::Pool;
use sidekiq::{Processor, ProcessorConfig, RedisConnectionManager};

use super::{BackgroundWorker, Queue};
use crate::{config::RedisQueueConfig, Result};
pub type RedisPool = Pool<RedisConnectionManager>;

#[derive(Debug)]
Expand Down
5 changes: 3 additions & 2 deletions src/controller/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,12 @@ pub fn render() -> RenderBuilder {
#[cfg(test)]
mod tests {

use super::*;
use crate::{controller::views::engines::TeraView, prelude::*};
use insta::assert_debug_snapshot;
use tree_fs;

use super::*;
use crate::{controller::views::engines::TeraView, prelude::*};

async fn response_body_to_string(response: hyper::Response<Body>) -> String {
let bytes = axum::body::to_bytes(response.into_body(), 200)
.await
Expand Down
22 changes: 13 additions & 9 deletions src/controller/middleware/powered_by.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
//! Powered-By Middleware
//!
//! This middleware injects an HTTP header `X-Powered-By` into the response headers of
//! every request handled by the application. The header identifies the software or technology
//! stack powering the application. It supports a custom identifier string or defaults to "loco.rs"
//! if no identifier is provided.
//! This middleware injects an HTTP header `X-Powered-By` into the response
//! headers of every request handled by the application. The header identifies
//! the software or technology stack powering the application. It supports a
//! custom identifier string or defaults to "loco.rs" if no identifier is
//! provided.
use crate::{app::AppContext, controller::middleware::MiddlewareLayer, Result};
use axum::{
http::header::{HeaderName, HeaderValue},
Router as AXRouter,
};
use tower_http::set_header::SetResponseHeaderLayer;

use crate::{app::AppContext, controller::middleware::MiddlewareLayer, Result};

lazy_static::lazy_static! {
static ref DEFAULT_IDENT_HEADER_VALUE: HeaderValue =
HeaderValue::from_static("loco.rs");
}

/// [`Middleware`] struct responsible for managing the identifier value for the `X-Powered-By` header.
/// [`Middleware`] struct responsible for managing the identifier value for the
/// `X-Powered-By` header.
#[derive(Debug)]
pub struct Middleware {
ident: Option<HeaderValue>,
}

/// Creates a new instance of [`Middleware`] by cloning the [`Config`] configuration.
/// Creates a new instance of [`Middleware`] by cloning the [`Config`]
/// configuration.
#[must_use]
pub fn new(ident: Option<&str>) -> Middleware {
let ident_value = ident.map_or_else(
Expand Down Expand Up @@ -68,8 +72,8 @@ impl MiddlewareLayer for Middleware {
)
}

/// Applies the middleware to the application by adding the `X-Powered-By` header to
/// each response.
/// Applies the middleware to the application by adding the `X-Powered-By`
/// header to each response.
fn apply(&self, app: AXRouter<AppContext>) -> Result<AXRouter<AppContext>> {
Ok(app.layer(SetResponseHeaderLayer::overriding(
HeaderName::from_static("x-powered-by"),
Expand Down
4 changes: 2 additions & 2 deletions src/controller/views/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ impl<E> ViewEngine<E> {

/// A struct representing an inline Tera view renderer.
///
/// This struct provides functionality to render templates using the Tera templating engine
/// directly from raw template strings.
/// This struct provides functionality to render templates using the Tera
/// templating engine directly from raw template strings.
///
/// # Example
/// ```
Expand Down
20 changes: 10 additions & 10 deletions src/scheduler.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
//! # Scheduler Module
//! TBD
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fmt, io,
path::{Path, PathBuf},
time::Instant,
};

use crate::{app::Hooks, environment::Environment, task::Tasks};

use regex::Regex;
use serde::{Deserialize, Serialize};
use tokio_cron_scheduler::{JobScheduler, JobSchedulerError};

use crate::{app::Hooks, environment::Environment, task::Tasks};

lazy_static::lazy_static! {
static ref RE_IS_CRON_SYNTAX: Regex = Regex::new(r"^[\*\d]").unwrap();
}
Expand Down Expand Up @@ -71,7 +71,7 @@ pub struct Job {
///
/// The format is as follows:
/// sec min hour day of month month day of week year
/// * * * * * * *
/// * * * * * * *
pub cron: String,
/// Tags for tagging the job.
pub tags: Option<Vec<String>>,
Expand Down Expand Up @@ -219,8 +219,8 @@ impl Scheduler {

/// Creates a new scheduler instance from the provided configuration data.
///
/// When creating a new scheduler instance all register task should be loaded for validate the
/// given configuration.
/// When creating a new scheduler instance all register task should be
/// loaded for validate the given configuration.
///
/// # Errors
///
Expand Down Expand Up @@ -352,14 +352,14 @@ impl Scheduler {
#[cfg(test)]
mod tests {

use super::*;
use crate::tests_cfg;
use insta::assert_debug_snapshot;

use rstest::rstest;
use tests_cfg::db::AppHook;
use tokio::time::{self, Duration};

use super::*;
use crate::tests_cfg;

fn get_scheduler_from_config() -> Result<Scheduler, Error> {
let scheduler_config_path = PathBuf::from("tests")
.join("fixtures")
Expand Down

0 comments on commit 570f6b4

Please sign in to comment.