总结与代码清理

894339
2021/11/26 04:40:50

本章代码在06/清理分支。

AppError 的处理

因为我们的 MsgTemplate 已经提供了 err() 方法,所以在 AppError 可以直接调用该方法:

let tmpl = MsgTemplate::err(msg.clone());
let html = tmpl.render().unwrap_or(msg);
Html(html).into_response()

另外,为了处理保留字的检测,我们还要加上:

pub fn reserved_word(word: &str) -> Self {
    let msg = format!("{}是保留字", word);
    Self::from_str(&msg, AppErrorType::ReservedWord)
}

AppErrorType 的处理

当然,AppErrorType 也要加上保留字的枚举项:

MsgTemplate 的处理

MsgTemplate::ok() 方法删除,因为没有任何地方用到它。

handler 的处理

为了便于显示添加成功的短链接,我们将index_action()的跳转改为 index()

index_action()

let redirect_url = format!("/?id={}", result.id);
Ok(redirect(&redirect_url))

另外,为了检测生成的短链接是否是保留字(虽然概率极小,在开启自定义短链接时,这个检测非常有必要),我们还需要增加:

if (&state).short_url_cfg.in_reserved_words(&id) {
    return Err(AppError::reserved_word(&id));
};

index()

#[derive(Deserialize)]
pub struct IndexArgs {
    pub id: Option<String>,
}
pub async fn index(
    Extension(state): Extension<AppState>,
    Query(args): Query<IndexArgs>,
) -> HandlerHtmlResult {
    let handler_name = "index";
    let tmpl = IndexTemplate {
        id: args.id.clone(),
        short_url_domain: state.short_url_cfg.domain.clone(),
    };
    render(tmpl).map_err(log_error(handler_name.to_string()))
}

模板结构体

对应的,IndexTemplate 也要进行处理:

#[derive(Template)]
#[template(path = "index.html")]
pub struct IndexTemplate {
    pub id: Option<String>,
    pub short_url_domain: String,
}
impl IndexTemplate {
    pub fn id(&self) -> String {
        self.id.clone().unwrap_or("".to_string())
    }
}

模板文件

同时,templates/index.html 也要进行处理:

<h1>创建你的短网址</h1>
{%if !self.id().is_empty() %}
<div class="alert alert-info my-3">
  短链接创建成功:<a href="//{{short_url_domain}}/{{self.id()}}" target="_blank"
    >{{short_url_domain}}/{{self.id()}}</a
  >
</div>
{% endif%}
<form action="/" method="post" autocomplete="off"></form>

核心算法的处理

数据库的处理

execute() 函数加上 #[allow(unused)]

总结

本专题带你实现了一个短链接服务。

  • 短链接算法:使用 murmur3 将原始链接转成 32 位的正整数哈希值,然后将这个哈希值转成字符形式的 base62, 这个就是我们的短链接

  • 模板:本专题使用了模板引擎

  • PostgreSQL:当然,本专题少不了数据库

  • 静态资源:为了配合模板引用的静态文件,我们加上了静态资源的处理

  • 配置文件、日志:这两个“标配”自然少不了