Skip to main content

encryption/
pet.rs

1// Copyright (c) 2026 erik <erik@erik.xyz> — https://erik.xyz
2
3//! 项目宠物「Locky」(小锁)。
4//!
5//! 图形本体见 `docs/pet.svg`(`SVG` 常量以 `include_str!` 内联,零运行时开销,
6//! 不用就不链接);终端里没有 SVG,因此保留一份等价的 ASCII 版本
7//! (与 PHP 版 `Erikwang2013\Encryption\Mascot::ascii()` 逐字符一致)。
8
9/// 宠物名。
10pub const NAME: &str = "Locky";
11
12/// 一句话标语。
13pub const TAGLINE: &str = "每个算法各持一把子密钥,每次加密都用新的 IV,钥匙孔从不泄露秘密";
14
15/// 终端横幅用的 ASCII 版本:纯 ASCII、等宽 17 列,不依赖字体或颜色(无尾随换行)。
16pub const ASCII: &str = concat!(
17    "     .-------.\n",
18    "     /       \\\n",
19    "  .-------------.\n",
20    "  |  o       o  |\n",
21    "  |             |\n",
22    "  |     ,-.     |\n",
23    "  |    (   )    |\n",
24    "  |     '-'     |\n",
25    "  |      |      |\n",
26    "  '-------------'",
27);
28
29/// 项目宠物 SVG(`docs/pet.svg` 原文;可内联进 HTML,或自行转成 data URI 使用)。
30pub const SVG: &str = include_str!("../docs/pet.svg");
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn ascii_matches_php_mascot_line_for_line() {
38        let lines: Vec<&str> = ASCII.lines().collect();
39        assert_eq!(lines.len(), 10);
40        assert_eq!(lines[0].trim_start(), ".-------.");
41        assert_eq!(lines[2].trim_start(), ".-------------.");
42        assert_eq!(lines[9].trim_start(), "'-------------'");
43        assert!(!ASCII.ends_with('\n'));
44    }
45
46    #[test]
47    fn svg_is_inlined_from_docs() {
48        assert!(SVG.trim_start().starts_with("<svg"));
49        assert!(SVG.contains("Locky"));
50    }
51
52    #[test]
53    fn name_and_tagline_are_public() {
54        assert_eq!(NAME, "Locky");
55        assert!(!TAGLINE.is_empty());
56    }
57}