pub trait Project {
// Provided methods
fn cli_metadata(&self) -> CliMetadata { ... }
fn config(&self, config_name: &str) -> Result<ProjectConfig> { ... }
fn register_tasks(&self, cli: &mut Cli) { ... }
fn register_apps(
&self,
apps: &mut AppBuilder,
context: &ProjectContext<WithConfig>,
) { ... }
fn auth_backend(
&self,
context: &ProjectContext<WithApps>,
) -> Box<dyn AuthBackend> { ... }
fn middlewares(
&self,
handler: RootHandlerBuilder,
context: &ProjectContext<WithApps>,
) -> BoxedHandler { ... }
fn server_error_handler(&self) -> Box<dyn ErrorPageHandler> { ... }
fn not_found_handler(&self) -> Box<dyn ErrorPageHandler> { ... }
}Expand description
The main trait for a Cot project.
This is the main entry point for your application. This trait defines the configuration, apps, and other project-wide resources.
It’s mainly meant to be used with the cot::main attribute macro.
§Examples
use cot::cli::CliMetadata;
use cot::Project;
struct MyProject;
impl Project for MyProject {
fn cli_metadata(&self) -> CliMetadata {
cot::cli::metadata!()
}
}
#[cot::main]
fn main() -> impl Project {
MyProject
}Provided Methods§
Sourcefn cli_metadata(&self) -> CliMetadata
fn cli_metadata(&self) -> CliMetadata
Returns the metadata for the CLI.
This method is used to set the name, version, authors, and description
of the CLI application. This is meant to be typically used with
cli::metadata!() which automatically retrieves this data from the
crate metadata.
The default implementation sets the name, version, authors, and
description of the cot crate.
§Examples
use cot::cli::CliMetadata;
use cot::Project;
struct HelloProject;
impl Project for HelloProject {
fn cli_metadata(&self) -> CliMetadata {
cot::cli::metadata!()
}
}Sourcefn config(&self, config_name: &str) -> Result<ProjectConfig>
fn config(&self, config_name: &str) -> Result<ProjectConfig>
Returns the configuration for the project.
The default implementation reads the configuration from the config
directory in the current working directory (for instance, if
config_name is test, then config/test.toml in the current working
directory is read). If the file does not exist, it tries to read the
file directly at config_name path.
You might want to override this method if you want to read the configuration from a different source, or if you want to hardcode it in the binary.
§Errors
This method may return an error if it cannot read or parse the configuration.
§Examples
use cot::config::ProjectConfig;
use cot::Project;
struct MyProject;
impl Project for MyProject {
fn config(&self, config_name: &str) -> cot::Result<ProjectConfig> {
Ok(ProjectConfig::default())
}
}Sourcefn register_tasks(&self, cli: &mut Cli)
fn register_tasks(&self, cli: &mut Cli)
Adds a task to the CLI.
This method is used to add a task to the CLI. The task will be available as a subcommand of the main CLI command.
§Examples
use async_trait::async_trait;
use clap::{ArgMatches, Command};
use cot::cli::{Cli, CliTask};
use cot::project::WithConfig;
use cot::{Bootstrapper, Project};
struct Frobnicate;
#[async_trait(?Send)]
impl CliTask for Frobnicate {
fn subcommand(&self) -> Command {
Command::new("frobnicate")
}
async fn execute(
&mut self,
_matches: &ArgMatches,
_bootstrapper: Bootstrapper<WithConfig>,
) -> cot::Result<()> {
println!("Frobnicating...");
Ok(())
}
}
struct MyProject;
impl Project for MyProject {
fn register_tasks(&self, cli: &mut Cli) {
cli.add_task(Frobnicate)
}
}Sourcefn register_apps(
&self,
apps: &mut AppBuilder,
context: &ProjectContext<WithConfig>,
)
fn register_apps( &self, apps: &mut AppBuilder, context: &ProjectContext<WithConfig>, )
Registers the apps for the project.
§Examples
use cot::project::{AppBuilder, WithConfig};
use cot::{App, Project, ProjectContext};
struct MyApp;
impl App for MyApp {
fn name(&self) -> &str {
"my_app"
}
}
struct MyProject;
impl Project for MyProject {
fn register_apps(&self, apps: &mut AppBuilder, context: &ProjectContext<WithConfig>) {
apps.register(MyApp);
}
}Sourcefn auth_backend(
&self,
context: &ProjectContext<WithApps>,
) -> Box<dyn AuthBackend>
fn auth_backend( &self, context: &ProjectContext<WithApps>, ) -> Box<dyn AuthBackend>
Sets the authentication backend to use.
Note that it’s typically not necessary to override this method, as it already provides a default implementation that uses the auth backend specified in the project’s configuration.
§Examples
use cot::auth::{AuthBackend, NoAuthBackend};
use cot::project::WithApps;
use cot::{App, Project, ProjectContext};
struct HelloProject;
impl Project for HelloProject {
fn auth_backend(&self, context: &ProjectContext<WithApps>) -> Box<dyn AuthBackend> {
Box::new(NoAuthBackend)
}
}Sourcefn middlewares(
&self,
handler: RootHandlerBuilder,
context: &ProjectContext<WithApps>,
) -> BoxedHandler
fn middlewares( &self, handler: RootHandlerBuilder, context: &ProjectContext<WithApps>, ) -> BoxedHandler
Returns the middlewares for the project.
This method is used to return the middlewares for the project. The middlewares will be applied to all routes in the project.
§Examples
use cot::middleware::LiveReloadMiddleware;
use cot::project::{RootHandlerBuilder, WithApps};
use cot::{BoxedHandler, Project, ProjectContext};
struct MyProject;
impl Project for MyProject {
fn middlewares(
&self,
handler: RootHandlerBuilder,
context: &ProjectContext<WithApps>,
) -> BoxedHandler {
handler
.middleware(LiveReloadMiddleware::from_context(context))
.build()
}
}Sourcefn server_error_handler(&self) -> Box<dyn ErrorPageHandler>
fn server_error_handler(&self) -> Box<dyn ErrorPageHandler>
Returns the 500 Internal Server Error handler for the project.
The default handler returns a simple, static page.
§Errors
This method may return an error if the handler fails to build a response. In this case, the error will be logged and a generic error page will be returned to the user.
§Panics
Note that this handler is exempt of the typical panic handling
machinery in Cot. This means that if this handler panics, no
response will be sent to a user. Because of that, you should
avoid panicking here and return Err instead.
§Examples
use cot::project::ErrorPageHandler;
use cot::response::{Response, ResponseExt};
use cot::{Body, Project, StatusCode};
struct MyProject;
impl Project for MyProject {
fn server_error_handler(&self) -> Box<dyn ErrorPageHandler> {
Box::new(MyHandler)
}
}
struct MyHandler;
impl ErrorPageHandler for MyHandler {
fn handle(&self) -> cot::Result<Response> {
Ok(Response::new_html(
StatusCode::INTERNAL_SERVER_ERROR,
Body::fixed("Internal Server Error"),
))
}
}Sourcefn not_found_handler(&self) -> Box<dyn ErrorPageHandler>
fn not_found_handler(&self) -> Box<dyn ErrorPageHandler>
Returns the 404 Not Found handler for the project.
The default handler returns a simple, static page.
§Errors
This method may return an error if the handler fails to build a response. In this case, the error will be logged and a generic error page will be returned to the user.
§Panics
Note that this handler is exempt of the typical panic handling
machinery in Cot. This means that if this handler panics, no
response will be sent to a user. Because of that, you should
avoid panicking here and return Err instead.
§Examples
use cot::project::ErrorPageHandler;
use cot::response::{Response, ResponseExt};
use cot::{Body, Project, StatusCode};
struct MyProject;
impl Project for MyProject {
fn not_found_handler(&self) -> Box<dyn ErrorPageHandler> {
Box::new(MyHandler)
}
}
struct MyHandler;
impl ErrorPageHandler for MyHandler {
fn handle(&self) -> cot::Result<Response> {
Ok(Response::new_html(
StatusCode::NOT_FOUND,
Body::fixed("Not Found"),
))
}
}