Lewati ke konten utama

Helper Utilities

This module provides reusable utility functions used across the application.

The helper functions cover:

  • Datetime formatting
  • String normalization
  • Empty value validation
  • Email validation
  • Name validation
  • Price validation
  • Sequence generation
  • Module prefix formatting

File Structure


Module Dependencies

use chrono::{DateTime, Local};
use regex::Regex;
use crate::utils::Responses;
use axum::{http::StatusCode, response::{AppendHeaders, IntoResponse, Response}, Json};
use serde::Serializer;
use serde_json::json;

Helper Function Overview

FunctionPurpose
time_now_modifGet current local datetime
format_datetimeSerialize datetime into formatted string
convert_to_normalize_lowerNormalize string to lowercase
is_emptyCheck empty string
not_emptyCheck non-empty string
is_valid_nameValidate name format
is_valid_emailValidate email format
is_valid_priceValidate numeric price
sequence_numberGenerate padded sequence number
prefix_moduleGenerate prefixed document code
splits_prefix_moduleValidate module prefix

Utility Architecture


Current Datetime Helper

Source Code

//format : 2026-05-07 14:30:00
#[allow(dead_code)]
pub fn time_now_modif() -> DateTime<Local> {
Local::now()
}

Explanation

Returns the current local datetime using Chrono.


Return Type

DateTime<Local>

Represents timezone-aware local datetime.


Datetime Formatter

Source Code

pub fn format_datetime<S>(
date: &Option<DateTime<Local>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match date {
Some(dt) => serializer.serialize_str(
&dt.format("%Y-%m-%d %H:%M:%S").to_string()
),
None => serializer.serialize_none(),
}
}

Datetime Serialization Flow


Datetime Format

2026-05-07 14:30:00

String Normalization

Source Code

// trim + lower
#[allow(dead_code)]
pub fn convert_to_normalize_lower(value:&str)->String{
value.trim().to_lowercase()
}

Explanation

Performs:

  • Whitespace trimming
  • Lowercase conversion

Example

InputOutput
" ADMIN ""admin"

Empty String Validation

is_empty

pub fn is_empty(value:&str)->bool{
value.trim().is_empty()
}

Explanation

Checks whether a string is empty after trimming whitespace.


Example

InputResult
" "true
"hello"false

Non-Empty Validation

Source Code

/// Check not empty string
#[allow(dead_code)]
pub fn not_empty(value: &str) -> bool {
!value.trim().is_empty()
}

Explanation

Returns the inverse result of is_empty.


Name Validation

Source Code

/// Valid name:
/// a-z A-Z 0-9 . space
#[allow(dead_code)]
pub fn is_valid_name(name: &str) -> bool {
let regex = Regex::new(r"^[a-zA-Z0-9.\s]+$").unwrap();
regex.is_match(name)
}

Allowed Characters

Character TypeAllowed
Uppercase lettersYes
Lowercase lettersYes
NumbersYes
Dot (.)Yes
SpaceYes

Regex Pattern

^[a-zA-Z0-9.\s]+$

Validation Examples

InputResult
"John Doe"true
"User.01"true
"Admin@Root"false

Email Validation

Source Code

/// Validate email
pub fn is_valid_email(email: &str) -> bool {
let regex =
Regex::new(r"^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$").unwrap();

regex.is_match(email)
}

Email Validation Flow


Supported Email Format

Examples:

user@example.com
admin.system@test.org

Price Validation

Source Code

/// Validate price
/// only number + dot + space
#[allow(dead_code)]
pub fn is_valid_price(price: &str) -> bool {
let regex = Regex::new(r"^[0-9.\s]+$").unwrap();
regex.is_match(price)
}

Allowed Characters

CharacterAllowed
NumbersYes
Dot (.)Yes
SpaceYes

Example

InputResult
"1000"true
"10.500"true
"1000USD"false

Sequence Number Generator

Source Code

/// Example:
/// 1 => 000001
#[allow(dead_code)]
pub fn sequence_number(n: i64) -> String {
format!("{:06}", n)
}

Sequence Format

Pads numbers into 6-digit format.


Examples

InputOutput
1000001
25000025
1000001000

Prefix Module Generator

Source Code

/// Example:
/// INV-2605000001
pub fn prefix_module(code: &str, seq: i64) -> String {
let date = Local::now().format("%y%m").to_string();

format!("{}-{}{}", code, date, sequence_number(seq))
}

Prefix Format Structure


Format Example

INV-2605000001

Format Breakdown

SegmentDescription
INVModule code
2605Year and month
000001Sequence number

Prefix Validation

Source Code

pub fn splits_prefix_module(code:&str, value:&str) ->bool{
value.trim().to_lowercase().starts_with(&format!("{}-",code.trim().to_lowercase()))
}

Explanation

Checks whether a value starts with a specific module prefix.


Validation Example

CodeValueResult
INVINV-2605000001true
TRXINV-2605000001false

Validation Logic


Utility Design Summary

CategoryResponsibility
Datetime UtilityCurrent time and formatting
String UtilityNormalize and trim values
Validation UtilityValidate names, emails, prices
Sequence UtilityGenerate formatted identifiers
Prefix UtilityValidate module codes

Design Characteristics

Lightweight

Functions are reusable and independent.


Stateless

No shared mutable state is used.


Reusable

Can be reused across:

  • Services
  • Middleware
  • Validation layers
  • Response formatting
  • Database modules

Common Use Cases

FeatureHelper Function
Generate invoice numberprefix_module
Validate email inputis_valid_email
Normalize user inputconvert_to_normalize_lower
Serialize datetime responseformat_datetime
Validate empty form fieldis_empty
Validate product priceis_valid_price