a lot of shit

This commit is contained in:
grechkagk 2025-11-16 23:25:38 +08:00
parent 002767b85a
commit c3f365e1f6
16 changed files with 1247 additions and 2 deletions

1025
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -4,3 +4,12 @@ version = "0.1.0"
edition = "2024"
[dependencies]
axum = "0.8.7"
chrono = "0.4"
http = "1.3.1"
mime_guess = "2.0"
rust-embed = "8.9.0"
term_size = "0.1"
tokio = { version = "*", features = ["full"] }
tower-http = "0.6.6"
tower-service = "0.3.3"

0
README.md Normal file
View file

30
TECHDOC.md Normal file
View file

@ -0,0 +1,30 @@
# Техдок проекта
## Идея
- Что делает проект:
должен выполнять front и back задач
- Зачем нужен:
чтобы выпендрится
## Технологии
- Язык:
rust
- Фреймворки:
- Библиотеки:
tokio
## Структура проекта
- Основные файлы:
- Модули:
## TODO
- Задача 1:
- Задача 2:
## Проблемы и решения
- Проблема 1:
- Решение:
## Заметки
- Идеи для улучшений:
- Вопросы:

0
assets/content/about.md Normal file
View file

BIN
assets/media/uzi.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

14
assets/pages/about.html Normal file
View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About</title>
<base href="{{BASE_URL}}">
</head>
<body>
<h1>About Page</h1>
<p>This is the about page.</p>
<a href="/">index</a>
</body>
</html>

14
assets/pages/index.html Normal file
View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<base href="{{BASE_URL}}">
</head>
<body>
<h1>Hello world!</h1>
<img src="media/uzi.gif"/>
<a href="about/">about</a>
</body>
</html>

0
assets/scripts/hello.js Normal file
View file

0
assets/styles/main.css Normal file
View file

5
src/assets.rs Normal file
View file

@ -0,0 +1,5 @@
use rust_embed::Embed;
#[derive(Embed, Debug)]
#[folder = "assets"]
pub struct Assets;

1
src/debug/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod static_content;

View file

@ -0,0 +1,12 @@
use crate::assets::Assets;
// Добавляем импорт для функции logger
use crate::logger::logger as log;
pub fn print_static_content() {
// Собираем список файлов и логируем каждый как DEBUG (3)
let total_files: Vec<_> = Assets::iter().collect();
for file in total_files {
log(3, file.as_ref(), false);
}
}

33
src/logger.rs Normal file
View file

@ -0,0 +1,33 @@
use chrono::Local;
use term_size;
const RESET: &str = "\x1b[0m";
const WHITE: &str = "\x1b[1;37m";
const YELLOW: &str = "\x1b[1;33m";
const RED: &str = "\x1b[1;31m";
const BLUE: &str = "\x1b[1;34m";
const GREEN: &str = "\x1b[1;32m";
const TEXT_COLOR_NORMAL: &str = "\x1b[22;37m";
const TEXT_COLOR_BOLD: &str = "\x1b[1;37m";
pub fn logger(level: i32, string: &str, bold: bool) {
let (level_str, color) = match level {
0 => ("INFO", GREEN),
1 => ("WARN", YELLOW),
2 => ("ERROR", RED),
3 => ("DEBUG", BLUE),
_ => ("UNKNOWN", WHITE),
};
let text_color = if bold { TEXT_COLOR_BOLD } else { TEXT_COLOR_NORMAL };
let time = Local::now().format("%H:%M:%S").to_string();
let width = term_size::dimensions().map(|(w, _)| w).unwrap_or(80);
let inner_width = width - 2; // Account for 1 space padding on each side
let prefix = format!("[{}]", level_str);
let visible_len = prefix.len() + 1 + string.len(); // [TYPE] space message
let spaces = inner_width.saturating_sub(visible_len + time.len());
print!(" {}{}{}{}{}{}{}{}{}\n", color, prefix, " ", text_color, string, RESET, " ".repeat(spaces), color, time);
}

View file

@ -1,3 +1,21 @@
fn main() {
println!("Hello, world!");
mod logger;
use crate::logger::logger as log;
mod debug;
mod assets;
mod routing;
#[tokio::main]
async fn main() {
// build our application with auto-routing
let app = routing::create_router();
debug::static_content::print_static_content();
// run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
log(0, "Server started successfully on port 3000", true);
axum::serve(listener, app).await.unwrap();
log(0, "gkweb started", true)
}

84
src/routing.rs Normal file
View file

@ -0,0 +1,84 @@
use axum::{response::Response, routing::get, Router, extract::Path};
use crate::assets::Assets;
use mime_guess::from_path;
use http::{StatusCode, header};
use std::env;
fn get_base_url() -> String {
env::var("BASE_URL").unwrap_or_else(|_| "/".to_string())
}
fn internal_error() -> Response {
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body("500 Internal Server Error".into())
.unwrap()
}
fn serve_static_file(path: &str) -> Option<Response> {
if let Some(file) = Assets::get(path) {
let mime_type = from_path(path).first_or_octet_stream();
Some(Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, mime_type.as_ref())
.body(file.data.into())
.unwrap())
} else {
None
}
}
fn serve_html_page(page_path: &str) -> Option<Response> {
if let Some(file) = Assets::get(page_path) {
let content = match String::from_utf8(file.data.into_owned()) {
Ok(c) => c,
Err(_) => return Some(internal_error()),
};
let base_url = get_base_url();
let new_content = content.replace("{{BASE_URL}}", &base_url);
let mime_type = from_path(page_path).first_or_octet_stream();
Some(Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, mime_type.as_ref())
.body(new_content.into())
.unwrap())
} else {
None
}
}
/// создаёт роуты для axum
pub fn create_router() -> Router {
Router::new()
.route("/", get(index_handler))
.route("/{*path}", get(static_file_handler)) // <-- Заменяем other_handler
}
// особый хэндлер для index.html
async fn index_handler() -> Response {
if let Some(response) = serve_html_page("pages/index.html") {
response
} else {
Response::builder()
.status(StatusCode::NOT_FOUND)
.body("404 Not Found".into())
.unwrap()
}
}
async fn static_file_handler(Path(raw_path): Path<String>) -> Response {
let path = raw_path.trim_end_matches('/').to_string();
if let Some(response) = serve_static_file(&path) {
return response;
}
let page_path = format!("pages/{}.html", path);
if let Some(response) = serve_html_page(&page_path) {
return response;
}
Response::builder()
.status(StatusCode::NOT_FOUND)
.body("404 Not Found".into())
.unwrap()
}