Skip to content

Develop#1

Merged
mingcheng merged 5 commits intomainfrom
develop
Feb 15, 2026
Merged

Develop#1
mingcheng merged 5 commits intomainfrom
develop

Conversation

@mingcheng
Copy link
Owner

@mingcheng mingcheng commented Feb 15, 2026


Continue Tasks: ▶️ 1 queued — View all

Summary by Sourcery

Set up default configuration behavior, add licensing information, and document the mail-forwarder tool.

Enhancements:

  • Introduce a default config file path and simplify configuration loading to rely on a single TOML file.

Documentation:

  • Add a README describing features, configuration, installation, and usage of the mail-forwarder tool.

Chores:

  • Add an MIT LICENSE file and a source file copyright header.

Summary by CodeRabbit

  • Documentation

    • Added comprehensive README with project overview, installation instructions, and configuration examples.
  • Chores

    • Added MIT License file.
    • Added file headers to source modules.
  • Configuration Changes

    • Configuration file loading now uses a default system path location.

Copilot AI review requested due to automatic review settings February 15, 2026 11:55
@mingcheng mingcheng self-assigned this Feb 15, 2026
@sourcery-ai
Copy link

sourcery-ai bot commented Feb 15, 2026

Reviewer's Guide

Adds licensing/header metadata, introduces a default config file path for configuration loading while simplifying environment-based overrides, and documents the project via a new README and LICENSE file.

Class diagram for updated AppConfig configuration loading

classDiagram
    class AppConfig {
        <<struct>>
        +String forward_to
        +SenderConfig sender
        +Vec~ReceiverConfig~ receivers
        +AppConfig new()
        +AppConfig new_from_file(path)
        <<const>> DEFAULT_CHECK_INTERVAL_SECONDS : u64
        <<const>> DEFAULT_CONFIG_PATH : &str
    }

    class SenderConfig {
        <<struct>>
        +String host
        +u16 port
        +String username
        +String password
    }

    class ReceiverConfig {
        <<struct>>
        +String protocol
        +String host
        +u16 port
        +String username
        +String password
        +bool use_tls
        +u64 check_interval_seconds
        +bool delete_after_forward
        +String imap_folder
    }

    AppConfig o-- SenderConfig : has
    AppConfig o-- ReceiverConfig : has many

    class ConfigBuilder {
        +ConfigBuilder add_source(source)
        +Config build()
    }

    class FileSource {
        +with_name(path)
        +required(required)
    }

    AppConfig ..> ConfigBuilder : uses
    ConfigBuilder ..> FileSource : uses
Loading

Flow diagram for AppConfig configuration resolution with default path

flowchart TD
    A["start AppConfig new"] --> B["create ConfigBuilder"]
    B --> C["add_source File::with_name(DEFAULT_CONFIG_PATH).required(false)"]
    C --> D["build Config"]
    D --> E["try_deserialize into AppConfig"]
    E --> F["return AppConfig or ConfigError"]

    subgraph explicit_config_file
        A2["start AppConfig new_from_file(path)"] --> B2["create ConfigBuilder"]
        B2 --> C2["add_source File::with_name(path).required(true)"]
        C2 --> D2["build Config"]
        D2 --> E2["try_deserialize into AppConfig"]
        E2 --> F2["return AppConfig or ConfigError"]
    end

    subgraph constants
        G["DEFAULT_CONFIG_PATH = /etc/mail-forwarder/config.toml"]
        H["DEFAULT_CHECK_INTERVAL_SECONDS = 300"]
    end

    G -. used by .-> C
    H -. used by .-> E2
Loading

File-Level Changes

Change Details Files
Add source file license/header metadata to main entry point.
  • Introduce a MIT license-style comment header block at the top of the main application source file.
src/main.rs
Refine configuration defaults and loading behavior.
  • Document default protocol and IMAP folder helper functions with comments.
  • Introduce DEFAULT_CONFIG_PATH constant for the TOML configuration file.
  • Change AppConfig::new to load configuration from the default absolute config path rather than a bare "config" name.
  • Remove environment-variable based overrides from AppConfig::new and AppConfig::new_from_file to rely solely on file-based configuration.
src/config.rs
Add basic project documentation and licensing artifacts.
  • Create a README describing purpose, features, configuration format, and usage examples.
  • Add a LICENSE file to declare the project’s MIT licensing terms.
README.md
LICENSE

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

Warning

Rate limit exceeded

@mingcheng has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 17 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request introduces project licensing and documentation (LICENSE and README.md), adds a new default configuration path constant to the config module, removes a redundant test case from the IMAP receiver tests, and includes file header comments across source files.

Changes

Cohort / File(s) Summary
Project Documentation
LICENSE, README.md
Adds MIT License and comprehensive README with project overview, features, installation, configuration examples, and usage notes.
Configuration Updates
src/config.rs
Introduces DEFAULT_CONFIG_PATH constant pointing to /etc/mail-forwarder/config.toml and modifies config loading to use this path; removes environment-based configuration source.
Source File Metadata
src/main.rs, src/traits.rs
Adds file header comments containing license, authorship, and timestamp information; main.rs also declares new module declarations for smtp_sender and traits.
Test Cleanup
src/imap_receiver.rs
Removes test_imap_receiver_creation test function from the imap_receiver_tests module.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A burrow of files, now tidily dressed,
With licenses clear and docs at their best,
Config paths set where the mail shall run,
Headers in place—the setup is done! 🐰📬

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Develop' is overly vague and generic, failing to describe the actual changes being introduced in this comprehensive pull request. Replace with a more specific title that highlights a key change, such as 'Add MIT license, README documentation, and default config path' or focus on the most significant change.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The change from File::with_name("config") to File::with_name(DEFAULT_CONFIG_PATH) alters the default lookup location from the working directory to /etc/mail-forwarder/config.toml, which contradicts the README instructions that say to place config.toml in the working directory; consider aligning the default path or updating the configuration loading behavior to support both.
  • Both AppConfig::new and AppConfig::new_from_file previously layered environment variables via Environment::with_prefix("APP"), but this source has been removed; if this was not intentional, reintroduce env-based overrides or document the change in configuration precedence.
  • You are using File::with_name with absolute paths that include the .toml extension (e.g., DEFAULT_CONFIG_PATH and new_from_file examples); double-check that this matches the config crate’s expectations and consider using File::from for explicit file paths to avoid subtle path/extension handling issues.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The change from `File::with_name("config")` to `File::with_name(DEFAULT_CONFIG_PATH)` alters the default lookup location from the working directory to `/etc/mail-forwarder/config.toml`, which contradicts the README instructions that say to place `config.toml` in the working directory; consider aligning the default path or updating the configuration loading behavior to support both.
- Both `AppConfig::new` and `AppConfig::new_from_file` previously layered environment variables via `Environment::with_prefix("APP")`, but this source has been removed; if this was not intentional, reintroduce env-based overrides or document the change in configuration precedence.
- You are using `File::with_name` with absolute paths that include the `.toml` extension (e.g., `DEFAULT_CONFIG_PATH` and `new_from_file` examples); double-check that this matches the `config` crate’s expectations and consider using `File::from` for explicit file paths to avoid subtle path/extension handling issues.

## Individual Comments

### Comment 1
<location> `src/config.rs:67` </location>
<code_context>
 pub const DEFAULT_CHECK_INTERVAL_SECONDS: u64 = 300;

+// Default config file path
+pub const DEFAULT_CONFIG_PATH: &str = "/etc/mail-forwarder/config.toml";
+
 impl AppConfig {
</code_context>

<issue_to_address>
**suggestion:** Hard-coding an absolute config path may limit deployment flexibility

A hardcoded `/etc/mail-forwarder/config.toml` path reduces portability across local dev, containers, and non-Linux systems. Consider keeping this as the default but allowing overrides (e.g., CLI flag, env var, or a search strategy like: explicit path > CWD > `/etc/...`).
</issue_to_address>

### Comment 2
<location> `README.md:5` </location>
<code_context>
+
+A lightweight tool to forward emails from POP3/IMAP accounts to a specified SMTP destination written in Rust. 
+
+The Gmail DO NOT support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719). 
+
+So, I wrote this tool to forward emails from POP3/IMAP accounts to a specified SMTP destination, which can be used with Gmail or any other email service that supports SMTP.
</code_context>

<issue_to_address>
**issue (typo):** Fix grammar in the sentence about Gmail POP3/Gmailify support.

Please adjust the sentence for subject–verb agreement and remove the extra article. For example: "Gmail does not support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication."

```suggestion
Gmail does not support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719). 
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

pub const DEFAULT_CHECK_INTERVAL_SECONDS: u64 = 300;

// Default config file path
pub const DEFAULT_CONFIG_PATH: &str = "/etc/mail-forwarder/config.toml";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Hard-coding an absolute config path may limit deployment flexibility

A hardcoded /etc/mail-forwarder/config.toml path reduces portability across local dev, containers, and non-Linux systems. Consider keeping this as the default but allowing overrides (e.g., CLI flag, env var, or a search strategy like: explicit path > CWD > /etc/...).

README.md Outdated

A lightweight tool to forward emails from POP3/IMAP accounts to a specified SMTP destination written in Rust.

The Gmail DO NOT support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Fix grammar in the sentence about Gmail POP3/Gmailify support.

Please adjust the sentence for subject–verb agreement and remove the extra article. For example: "Gmail does not support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication."

Suggested change
The Gmail DO NOT support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).
Gmail does not support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces project-level documentation/licensing files and adds per-file header blocks, while also changing the application’s default configuration loading behavior.

Changes:

  • Added README and MIT LICENSE files for project documentation and licensing.
  • Added header blocks to several Rust source files.
  • Updated config loading to use a fixed default path (/etc/mail-forwarder/config.toml) and removed environment-variable config sources.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/traits.rs Adds a file header block.
src/main.rs Adds a file header block.
src/config.rs Adds a file header; changes default config loading path and removes env-based config loading.
README.md Adds initial user documentation, including configuration and usage instructions.
LICENSE Adds MIT license text.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +66 to +68
// Default config file path
pub const DEFAULT_CONFIG_PATH: &str = "/etc/mail-forwarder/config.toml";

Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting DEFAULT_CONFIG_PATH to an absolute /etc/... path changes the default behavior for running the app without --config (it will no longer pick up a local ./config.toml, and the repo includes one). Consider adding a working-directory fallback, or ensure all user-facing docs/packaging consistently point to /etc/mail-forwarder/config.toml as the default.

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +25
## Configuration

Create a `config.toml` file in the working directory:

Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation says to create config.toml in the working directory, but the code’s default config path is now /etc/mail-forwarder/config.toml unless --config is provided. Please update the README to match the actual search path (or update the code to also load ./config.toml by default).

Copilot uses AI. Check for mistakes.
README.md Outdated

A lightweight tool to forward emails from POP3/IMAP accounts to a specified SMTP destination written in Rust.

The Gmail DO NOT support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar: "The Gmail DO NOT support" reads incorrectly and is confusing. Consider rewriting this sentence (e.g., "Gmail does not support …"), and clarifying precisely what Gmail limitation this refers to.

Suggested change
The Gmail DO NOT support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).
Gmail does not support using POP3 or Gmailify with a forwarding-only address, so you must use an App Password for SMTP authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,21 @@
MIT License

Copyright (c) since 2005 mingcheng<mingcheng@outlook.com>
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The copyright line is non-standard/unclear ("Copyright (c) since 2005 mingcheng<...>") and is missing a space before the email address. For legal clarity, consider using a conventional MIT copyright line format (year or year range + name).

Suggested change
Copyright (c) since 2005 mingcheng<mingcheng@outlook.com>
Copyright (c) 2005 mingcheng <mingcheng@outlook.com>

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +13
/*!
* Copyright (c) 2026 Ming Lyu, aka mingcheng
*
* This source code is licensed under the MIT License,
* which is located in the LICENSE file in the source tree's root directory.
*
* File: main.rs
* Author: mingcheng <mingcheng@apache.org>
* File Created: 2026-02-12 15:38:23
*
* Modified By: mingcheng <mingcheng@apache.org>
* Last Modified: 2026-02-15 14:25:38
*/
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header is written as an inner doc comment (/*! ... */), so it will be treated as module-level documentation and show up in generated rustdoc output. If this is intended as a license/header block only, switch to a non-doc comment style (e.g., /* ... */ or // ...) to avoid polluting public docs.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +13
/*!
* Copyright (c) 2026 Ming Lyu, aka mingcheng
*
* This source code is licensed under the MIT License,
* which is located in the LICENSE file in the source tree's root directory.
*
* File: config.rs
* Author: mingcheng <mingcheng@apache.org>
* File Created: 2026-02-12 22:37:25
*
* Modified By: mingcheng <mingcheng@apache.org>
* Last Modified: 2026-02-15 14:37:31
*/
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header is written as an inner doc comment (/*! ... */), so it will be treated as module-level documentation and show up in generated rustdoc output. If this is intended as a license/header block only, switch to a non-doc comment style (e.g., /* ... */ or // ...) to avoid polluting public docs.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +13
/*!
* Copyright (c) 2026 Ming Lyu, aka mingcheng
*
* This source code is licensed under the MIT License,
* which is located in the LICENSE file in the source tree's root directory.
*
* File: traits.rs
* Author: mingcheng <mingcheng@apache.org>
* File Created: 2026-02-11 16:14:32
*
* Modified By: mingcheng <mingcheng@apache.org>
* Last Modified: 2026-02-15 14:28:07
*/
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header is written as an inner doc comment (/*! ... */), so it will be treated as module-level documentation and show up in generated rustdoc output. If this is intended as a license/header block only, switch to a non-doc comment style (e.g., /* ... */ or // ...) to avoid polluting public docs.

Copilot uses AI. Check for mistakes.
pub const DEFAULT_CONFIG_PATH: &str = "/etc/mail-forwarder/config.toml";

impl AppConfig {
/// Load config from defaults, then file (if exists), then environment variables
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc comment says config is loaded from file and then environment variables, but AppConfig::new() no longer adds an environment source. Either re-add the Environment::with_prefix(... ) source or update this comment so it matches the actual loading behavior.

Suggested change
/// Load config from defaults, then file (if exists), then environment variables
/// Load config from defaults and then from the default config file (if it exists)

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@LICENSE`:
- Line 3: The LICENSE file's copyright line uses mingcheng@outlook.com while
source headers in src/traits.rs, src/main.rs, and src/config.rs use
mingcheng@apache.org; update the email in the LICENSE entry (the single
copyright line) to match the source headers (mingcheng@apache.org) so all files
use the same contact.

In `@README.md`:
- Line 5: Fix the grammatical error in the README sentence that currently reads
"The Gmail DO NOT support POP3 or Gmailify..." by changing it to "Gmail does not
support POP3 or Gmailify for the forwarding email address" (preserve the rest of
the sentence and the existing link to the official Gmail documentation); update
only that sentence text to correct subject-verb agreement.
- Line 24: README currently instructs creating config.toml in the working
directory but the code's DEFAULT_CONFIG_PATH constant in src/config.rs points to
/etc/mail-forwarder/config.toml; update the README to either (a) change the
instruction to create the config at /etc/mail-forwarder/config.toml, or (b)
document both options: the default location (/etc/mail-forwarder/config.toml as
defined by DEFAULT_CONFIG_PATH) and how to override it using the --config flag;
reference DEFAULT_CONFIG_PATH and the --config flag in the README text so users
know where the program looks by default and how to supply a custom path.

In `@src/config.rs`:
- Line 70: Update the stale doc comment in src/config.rs that reads "Load config
from defaults, then file (if exists), then environment variables" to accurately
reflect the current behavior (e.g., "Load config from defaults, then file (if
exists)") and ensure any surrounding documentation for the associated function
(e.g., the config loader function or method such as load, load_config, or
Config::load) no longer references environment variable loading; adjust wording
consistently wherever that doc string or summary appears.
- Around line 66-76: The docstring on AppConfig::new is stale; update the
triple-slash comment above pub fn new() to say "Load config from file (if
exists)" (remove any mention of environment variables), leaving the
implementation using Config::builder() with File::with_name(DEFAULT_CONFIG_PATH)
unchanged; ensure the comment sits immediately above the AppConfig::new
declaration so it documents that function.

@@ -0,0 +1,21 @@
MIT License

Copyright (c) since 2005 mingcheng<mingcheng@outlook.com>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: Inconsistent email address across project files.

The LICENSE uses mingcheng@outlook.com while source file headers (e.g., src/traits.rs, src/main.rs, src/config.rs) use mingcheng@apache.org. Consider aligning them for consistency.

🤖 Prompt for AI Agents
In `@LICENSE` at line 3, The LICENSE file's copyright line uses
mingcheng@outlook.com while source headers in src/traits.rs, src/main.rs, and
src/config.rs use mingcheng@apache.org; update the email in the LICENSE entry
(the single copyright line) to match the source headers (mingcheng@apache.org)
so all files use the same contact.

README.md Outdated

A lightweight tool to forward emails from POP3/IMAP accounts to a specified SMTP destination written in Rust.

The Gmail DO NOT support POP3 or Gmailify for the forwarding email address, so you need to use an App Password for authentication. For more details, please refer to the [official Gmail documentation](https://support.google.com/mail/answer/16604719).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Grammatical error.

"The Gmail DO NOT support POP3 or Gmailify" → should be something like "Gmail does not support POP3 or Gmailify".

🤖 Prompt for AI Agents
In `@README.md` at line 5, Fix the grammatical error in the README sentence that
currently reads "The Gmail DO NOT support POP3 or Gmailify..." by changing it to
"Gmail does not support POP3 or Gmailify for the forwarding email address"
(preserve the rest of the sentence and the existing link to the official Gmail
documentation); update only that sentence text to correct subject-verb
agreement.


## Configuration

Create a `config.toml` file in the working directory:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Documentation mismatch with default config path.

The README says to create config.toml in "the working directory," but src/config.rs defines DEFAULT_CONFIG_PATH as /etc/mail-forwarder/config.toml. Either update the README to reference the actual default path or mention both options (default path + --config flag).

🤖 Prompt for AI Agents
In `@README.md` at line 24, README currently instructs creating config.toml in the
working directory but the code's DEFAULT_CONFIG_PATH constant in src/config.rs
points to /etc/mail-forwarder/config.toml; update the README to either (a)
change the instruction to create the config at /etc/mail-forwarder/config.toml,
or (b) document both options: the default location
(/etc/mail-forwarder/config.toml as defined by DEFAULT_CONFIG_PATH) and how to
override it using the --config flag; reference DEFAULT_CONFIG_PATH and the
--config flag in the README text so users know where the program looks by
default and how to supply a custom path.

Comment on lines +66 to 76
// Default config file path
pub const DEFAULT_CONFIG_PATH: &str = "/etc/mail-forwarder/config.toml";

impl AppConfig {
/// Load config from defaults, then file (if exists), then environment variables
pub fn new() -> Result<Self, ConfigError> {
Config::builder()
.add_source(File::with_name("config").required(false))
.add_source(Environment::with_prefix("APP").separator("__"))
.add_source(File::with_name(DEFAULT_CONFIG_PATH).required(false))
.build()?
.try_deserialize()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

config crate Rust File::with_name behavior file extension 0.13

💡 Result:

In config crate 0.13.x, config::File::with_name(base_name) means “try to find an existing config file by using base_name and (if needed) appending a known extension.” (docs.rs)

Behavior (from the 0.13.4 implementation):

  • It first checks an exact path match (relative paths are resolved against std::env::current_dir()):

    • If base_name (as given) already exists as a file, it uses that file.
    • If you didn’t explicitly hint a format, it infers the format from the file’s extension and errors if that extension is not one of the registered extensions (based on enabled features). (android.googlesource.com)
  • If the exact file does not exist, it tries appending extensions for registered formats:

    • It uses a “dummy extension” trick so it doesn’t overwrite an existing extension segment. So "Settings.local" becomes "Settings.local.toml" (not "Settings.toml"), and "Settings" becomes "Settings.toml", etc. (android.googlesource.com)
    • It searches extensions from the registered formats (e.g. toml, json, yaml/yml, ini, ron, json5, depending on features). (android.googlesource.com)
  • If multiple candidates exist (e.g. both Settings.toml and Settings.yaml), the winner is the first one found during iteration; since the registry is stored in a HashMap, the search order is not something you should rely on. (android.googlesource.com)

If you want deterministic behavior, either:

  • pass the full filename with extension (so the “exact match” path is used), or
  • use File::new("...", FileFormat::Toml /* etc */) / .format(...) to force the format. (android.googlesource.com)

Citations:


🏁 Script executed:

# Find and check Cargo.toml to see the config crate version
fd Cargo.toml | head -5

Repository: mingcheng/mail-forwarder

Length of output: 78


🏁 Script executed:

# Read the relevant section of src/config.rs
cat -n src/config.rs | sed -n '1,80p'

Repository: mingcheng/mail-forwarder

Length of output: 2871


Update the docstring to remove reference to environment variables.

The docstring on line 70 is stale. It mentions "then environment variables" but environment variable loading was removed (Environment import is no longer present). Update it to reflect the current implementation:

/// Load config from file (if exists)

The File::with_name() usage with the full path /etc/mail-forwarder/config.toml is correct—the config crate checks for an exact path match first before attempting to append extensions, so the .toml extension will be properly recognized and no double-extension issues will occur.

🤖 Prompt for AI Agents
In `@src/config.rs` around lines 66 - 76, The docstring on AppConfig::new is
stale; update the triple-slash comment above pub fn new() to say "Load config
from file (if exists)" (remove any mention of environment variables), leaving
the implementation using Config::builder() with
File::with_name(DEFAULT_CONFIG_PATH) unchanged; ensure the comment sits
immediately above the AppConfig::new declaration so it documents that function.

pub const DEFAULT_CONFIG_PATH: &str = "/etc/mail-forwarder/config.toml";

impl AppConfig {
/// Load config from defaults, then file (if exists), then environment variables
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Stale doc comment references environment variables.

The doc says "then environment variables" but environment-based loading has been removed from this method.

Proposed fix
-    /// Load config from defaults, then file (if exists), then environment variables
+    /// Load config from the default config file path (if exists)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Load config from defaults, then file (if exists), then environment variables
/// Load config from the default config file path (if exists)
🤖 Prompt for AI Agents
In `@src/config.rs` at line 70, Update the stale doc comment in src/config.rs that
reads "Load config from defaults, then file (if exists), then environment
variables" to accurately reflect the current behavior (e.g., "Load config from
defaults, then file (if exists)") and ensure any surrounding documentation for
the associated function (e.g., the config loader function or method such as
load, load_config, or Config::load) no longer references environment variable
loading; adjust wording consistently wherever that doc string or summary
appears.

@mingcheng mingcheng merged commit bba96e7 into main Feb 15, 2026
14 checks passed
@mingcheng mingcheng deleted the develop branch February 15, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants