reorganize module

This commit is contained in:
Timur Gordon
2025-04-04 08:28:07 +02:00
parent 1ea37e2e7f
commit 939b6b4e57
375 changed files with 7580 additions and 191 deletions

251
database/Cargo.lock generated Normal file
View File

@@ -0,0 +1,251 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"const-random",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "calendar_backend"
version = "0.1.0"
dependencies = [
"rhai",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "crunchy"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
]
[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
dependencies = [
"portable-atomic",
]
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rhai"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce4d759a4729a655ddfdbb3ff6e77fb9eadd902dae12319455557796e435d2a6"
dependencies = [
"ahash",
"bitflags",
"instant",
"num-traits",
"once_cell",
"rhai_codegen",
"smallvec",
"smartstring",
"thin-vec",
]
[[package]]
name = "rhai_codegen"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "smallvec"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
[[package]]
name = "smartstring"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
dependencies = [
"autocfg",
"static_assertions",
"version_check",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thin-vec"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d"
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

11
database/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "calendar_backend"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "rhai_engine"
path = "main.rs"
[dependencies]
rhai = "1.12.0"

View File

@@ -0,0 +1,31 @@
{
"calendars": [
{
"id": "cal1",
"name": "Work Calendar",
"owner_id": "user1",
"description": "Main work calendar for team coordination",
"color": "#4285F4",
"shared_with": ["user2", "user3", "user4"],
"visibility": "team"
},
{
"id": "cal2",
"name": "Personal Calendar",
"owner_id": "user1",
"description": "Personal appointments and reminders",
"color": "#0F9D58",
"shared_with": ["user5"],
"visibility": "private"
},
{
"id": "cal3",
"name": "Project Calendar",
"owner_id": "user2",
"description": "Project-specific deadlines and milestones",
"color": "#DB4437",
"shared_with": ["user1", "user3", "user4"],
"visibility": "public"
}
]
}

57
database/data/events.json Normal file
View File

@@ -0,0 +1,57 @@
{
"events": [
{
"id": "event1",
"title": "Team Meeting",
"description": "Weekly team sync meeting",
"start_time": "2025-04-04T10:00:00",
"end_time": "2025-04-04T11:00:00",
"location": "Conference Room A",
"calendar_id": "cal1",
"organizer_id": "user1",
"attendees": ["user1", "user2", "user3"],
"recurring": false,
"status": "confirmed"
},
{
"id": "event2",
"title": "Project Deadline",
"description": "Final submission for Q2 project",
"start_time": "2025-04-15T17:00:00",
"end_time": "2025-04-15T18:00:00",
"location": "Virtual",
"calendar_id": "cal1",
"organizer_id": "user2",
"attendees": ["user1", "user2", "user4"],
"recurring": false,
"status": "confirmed"
},
{
"id": "event3",
"title": "Lunch with Client",
"description": "Discuss upcoming partnership",
"start_time": "2025-04-10T12:30:00",
"end_time": "2025-04-10T14:00:00",
"location": "Downtown Cafe",
"calendar_id": "cal2",
"organizer_id": "user1",
"attendees": ["user1", "user5"],
"recurring": false,
"status": "tentative"
},
{
"id": "event4",
"title": "Weekly Status Update",
"description": "Regular status update meeting",
"start_time": "2025-04-05T09:00:00",
"end_time": "2025-04-05T09:30:00",
"location": "Conference Room B",
"calendar_id": "cal1",
"organizer_id": "user3",
"attendees": ["user1", "user2", "user3", "user4"],
"recurring": true,
"recurrence_pattern": "weekly",
"status": "confirmed"
}
]
}

54
database/data/users.json Normal file
View File

@@ -0,0 +1,54 @@
{
"users": [
{
"id": "user1",
"name": "John Doe",
"email": "john.doe@example.com",
"timezone": "UTC+2",
"preferences": {
"notification_time": 15,
"default_calendar_id": "cal1"
}
},
{
"id": "user2",
"name": "Jane Smith",
"email": "jane.smith@example.com",
"timezone": "UTC+1",
"preferences": {
"notification_time": 30,
"default_calendar_id": "cal1"
}
},
{
"id": "user3",
"name": "Bob Johnson",
"email": "bob.johnson@example.com",
"timezone": "UTC",
"preferences": {
"notification_time": 10,
"default_calendar_id": "cal2"
}
},
{
"id": "user4",
"name": "Alice Brown",
"email": "alice.brown@example.com",
"timezone": "UTC-5",
"preferences": {
"notification_time": 20,
"default_calendar_id": "cal1"
}
},
{
"id": "user5",
"name": "Charlie Davis",
"email": "charlie.davis@example.com",
"timezone": "UTC+3",
"preferences": {
"notification_time": 15,
"default_calendar_id": "cal2"
}
}
]
}

118
database/main.rhai Normal file
View File

@@ -0,0 +1,118 @@
// main.rhai - Main script for the calendar backend
// Import all modules
import "scripts/events" as events;
import "scripts/users" as users;
import "scripts/calendars" as calendars;
import "scripts/utils" as utils;
// Example function to get a user's upcoming events
fn get_user_upcoming_events(user_id, days_ahead) {
let user = users::get_user(user_id);
if utils::is_empty(user) {
return "User not found";
}
// Get current date
let current_date = utils::get_current_date();
// Calculate end date
let end_date = utils::add_days_to_date(current_date, days_ahead);
// Get events in the date range
let upcoming_events = events::get_events_by_date_range(current_date, end_date);
// Filter to only include events where the user is an attendee
let user_events = [];
for event in upcoming_events {
if utils::array_contains(event.attendees, user_id) {
user_events.push(event);
}
}
return user_events;
}
// Example function to get a user's calendar summary
fn get_user_calendar_summary(user_id) {
let user = users::get_user(user_id);
if utils::is_empty(user) {
return "User not found";
}
let user_calendars = calendars::get_accessible_calendars(user_id);
let calendar_count = user_calendars.len();
let user_events = events::get_events_by_attendee(user_id);
let event_count = user_events.len();
let organized_events = events::get_events_by_organizer(user_id);
let organized_count = organized_events.len();
return #{
user_name: user.name,
calendar_count: calendar_count,
event_count: event_count,
organized_count: organized_count
};
}
// Example function to get details of a specific event
fn get_event_details(event_id) {
let event = events::get_event(event_id);
if utils::is_empty(event) {
return "Event not found";
}
let organizer = users::get_user(event.organizer_id);
let calendar = calendars::get_calendar(event.calendar_id);
let attendees_info = [];
for attendee_id in event.attendees {
let attendee = users::get_user(attendee_id);
if !utils::is_empty(attendee) {
attendees_info.push(attendee.name);
}
}
return #{
title: event.title,
description: event.description,
start_time: event.start_time,
end_time: event.end_time,
location: event.location,
organizer: organizer.name,
calendar: calendar.name,
attendees: attendees_info,
status: event.status
};
}
// Example function to create a new event
fn create_new_event(title, description, start_time, end_time, location, calendar_id, organizer_id, attendees) {
// Validate inputs
let calendar = calendars::get_calendar(calendar_id);
if utils::is_empty(calendar) {
return "Calendar not found";
}
let organizer = users::get_user(organizer_id);
if utils::is_empty(organizer) {
return "Organizer not found";
}
// Create the event
let new_event = events::create_event(
title, description, start_time, end_time, location,
calendar_id, organizer_id, attendees, false, "confirmed"
);
return #{
message: "Event created successfully",
event_id: new_event.id,
title: new_event.title
};
}

11
database/main.rs Normal file
View File

@@ -0,0 +1,11 @@
use rhai::{Engine};
use std::path::{Path, PathBuf};
fn main() -> Result<(), Box<rhai::EvalAltResult>> {
let engine = Engine::new();
// Rhai's import system works relative to current working dir
engine.eval_file::<()>(PathBuf::from("main.rhai"))?;
Ok(())
}

View File

@@ -0,0 +1,54 @@
// calendar_model.rhai - Calendar data model
// Create a new calendar object
fn create_calendar(id, name, owner_id, description, color, shared_with, visibility) {
return #{
id: id,
name: name,
owner_id: owner_id,
description: description,
color: color,
shared_with: shared_with,
visibility: visibility
};
}
// Sample calendars data
fn get_sample_calendars() {
let calendars = [];
// Calendar 1: Work Calendar
calendars.push(create_calendar(
"cal1",
"Work Calendar",
"user1",
"Main work calendar for team coordination",
"#4285F4",
["user2", "user3", "user4"],
"team"
));
// Calendar 2: Personal Calendar
calendars.push(create_calendar(
"cal2",
"Personal Calendar",
"user1",
"Personal appointments and reminders",
"#0F9D58",
["user5"],
"private"
));
// Calendar 3: Project Calendar
calendars.push(create_calendar(
"cal3",
"Project Calendar",
"user2",
"Project-specific deadlines and milestones",
"#DB4437",
["user1", "user3", "user4"],
"public"
));
return calendars;
}

View File

@@ -0,0 +1,92 @@
// event_model.rhai - Event data model
// Create a new event object
fn create_event(id, title, description, start_time, end_time, location, calendar_id, organizer_id, attendees, recurring, status) {
return #{
id: id,
title: title,
description: description,
start_time: start_time,
end_time: end_time,
location: location,
calendar_id: calendar_id,
organizer_id: organizer_id,
attendees: attendees,
recurring: recurring,
status: status
};
}
// Create a recurring event object (extends regular event)
fn create_recurring_event(id, title, description, start_time, end_time, location, calendar_id, organizer_id, attendees, recurrence_pattern, status) {
let event = create_event(id, title, description, start_time, end_time, location, calendar_id, organizer_id, attendees, true, status);
event.recurrence_pattern = recurrence_pattern;
return event;
}
// Sample events data
fn get_sample_events() {
let events = [];
// Event 1: Team Meeting
events.push(create_event(
"event1",
"Team Meeting",
"Weekly team sync meeting",
"2025-04-04T10:00:00",
"2025-04-04T11:00:00",
"Conference Room A",
"cal1",
"user1",
["user1", "user2", "user3"],
false,
"confirmed"
));
// Event 2: Project Deadline
events.push(create_event(
"event2",
"Project Deadline",
"Final submission for Q2 project",
"2025-04-15T17:00:00",
"2025-04-15T18:00:00",
"Virtual",
"cal1",
"user2",
["user1", "user2", "user4"],
false,
"confirmed"
));
// Event 3: Lunch with Client
events.push(create_event(
"event3",
"Lunch with Client",
"Discuss upcoming partnership",
"2025-04-10T12:30:00",
"2025-04-10T14:00:00",
"Downtown Cafe",
"cal2",
"user1",
["user1", "user5"],
false,
"tentative"
));
// Event 4: Weekly Status Update (recurring)
events.push(create_recurring_event(
"event4",
"Weekly Status Update",
"Regular status update meeting",
"2025-04-05T09:00:00",
"2025-04-05T09:30:00",
"Conference Room B",
"cal1",
"user3",
["user1", "user2", "user3", "user4"],
"weekly",
"confirmed"
));
return events;
}

View File

@@ -0,0 +1,72 @@
// user_model.rhai - User data model
// Create user preferences object
fn create_user_preferences(notification_time, default_calendar_id) {
return #{
notification_time: notification_time,
default_calendar_id: default_calendar_id
};
}
// Create a new user object
fn create_user(id, name, email, timezone, preferences) {
return #{
id: id,
name: name,
email: email,
timezone: timezone,
preferences: preferences
};
}
// Sample users data
fn get_sample_users() {
let users = [];
// User 1: John Doe
users.push(create_user(
"user1",
"John Doe",
"john.doe@example.com",
"UTC+2",
create_user_preferences(15, "cal1")
));
// User 2: Jane Smith
users.push(create_user(
"user2",
"Jane Smith",
"jane.smith@example.com",
"UTC+1",
create_user_preferences(30, "cal1")
));
// User 3: Bob Johnson
users.push(create_user(
"user3",
"Bob Johnson",
"bob.johnson@example.com",
"UTC",
create_user_preferences(10, "cal2")
));
// User 4: Alice Brown
users.push(create_user(
"user4",
"Alice Brown",
"alice.brown@example.com",
"UTC-5",
create_user_preferences(20, "cal1")
));
// User 5: Charlie Davis
users.push(create_user(
"user5",
"Charlie Davis",
"charlie.davis@example.com",
"UTC+3",
create_user_preferences(15, "cal2")
));
return users;
}

View File

@@ -0,0 +1,73 @@
// calendars.rhai - Functions for handling calendars
import "utils" as utils;
import "../models/calendar_model" as calendar_model;
// Get all calendars
fn get_calendars() {
return calendar_model::get_sample_calendars();
}
// Get a specific calendar by ID
fn get_calendar(calendar_id) {
let calendars = get_all_calendars();
return utils::find_by_id(calendars, calendar_id);
}
// Get calendars owned by a specific user
fn get_calendars_by_owner(user_id) {
let calendars = get_all_calendars();
return utils::filter_by_property(calendars, "owner_id", user_id);
}
// Get calendars shared with a specific user
fn get_calendars_shared_with(user_id) {
let calendars = get_all_calendars();
let shared_calendars = [];
for calendar in calendars {
if utils::array_contains(calendar.shared_with, user_id) {
shared_calendars.push(calendar);
}
}
return shared_calendars;
}
// Get all calendars accessible by a user (owned + shared)
fn get_accessible_calendars(user_id) {
let owned = get_calendars_by_owner(user_id);
let shared_calendars = get_calendars_shared_with(user_id);
// Combine the two arrays
for calendar in shared_calendars {
owned.push(calendar);
}
return owned;
}
// Create a new calendar
fn create_calendar(name, owner_id, description, color, shared_with, visibility) {
// Generate a simple ID (in a real app, we would use a proper ID generation method)
let id = "cal" + (get_all_calendars().len() + 1).to_string();
return calendar_model::create_calendar(
id, name, owner_id, description, color, shared_with, visibility
);
}
// Format calendar details for display
fn format_calendar(calendar) {
if utils::is_empty(calendar) {
return "Calendar not found";
}
let shared_with_count = calendar.shared_with.len();
return `${calendar.name} (${calendar.color})
Description: ${calendar.description}
Owner: ${calendar.owner_id}
Visibility: ${calendar.visibility}
Shared with: ${shared_with_count} users`;
}

View File

@@ -0,0 +1,85 @@
// events.rhai - Functions for handling calendar events
import "utils" as utils;
import "../models/event_model" as event_model;
// Get all events
fn get_all_events() {
return event_model::get_sample_events();
}
// Get a specific event by ID
fn get_event(event_id) {
let events = get_all_events();
return utils::find_by_id(events, event_id);
}
// Get events for a specific calendar
fn get_events_by_calendar(calendar_id) {
let events = get_all_events();
return utils::filter_by_property(events, "calendar_id", calendar_id);
}
// Get events for a specific user (as attendee)
fn get_events_by_attendee(user_id) {
let events = get_all_events();
let user_events = [];
for event in events {
if utils::array_contains(event.attendees, user_id) {
user_events.push(event);
}
}
return user_events;
}
// Get events organized by a specific user
fn get_events_by_organizer(user_id) {
let events = get_all_events();
return utils::filter_by_property(events, "organizer_id", user_id);
}
// Get events for a specific date range
fn get_events_by_date_range(start_date, end_date) {
let events = get_all_events();
let filtered_events = [];
for event in events {
let event_start = event.start_time;
// Simple string comparison - in a real app, we would use proper date comparison
if event_start >= start_date && event_start <= end_date {
filtered_events.push(event);
}
}
return filtered_events;
}
// Create a new event
fn create_event(title, description, start_time, end_time, location, calendar_id, organizer_id, attendees, recurring, status) {
// Generate a simple ID (in a real app, we would use a proper ID generation method)
let id = "event" + (get_all_events().len() + 1).to_string();
return event_model::create_event(
id, title, description, start_time, end_time, location,
calendar_id, organizer_id, attendees, recurring, status
);
}
// Format event details for display
fn format_event(event) {
if utils::is_empty(event) {
return "Event not found";
}
let start_date = utils::format_date(event.start_time);
let start_time = utils::format_time(event.start_time);
let end_time = utils::format_time(event.end_time);
return `${event.title} (${start_date}, ${start_time} - ${end_time})
Location: ${event.location}
Description: ${event.description}
Status: ${event.status}`;
}

View File

@@ -0,0 +1,60 @@
// users.rhai - Functions for handling calendar users
import "utils" as utils;
import "../models/user_model" as user_model;
// Get all users
fn get_all_users() {
return user_model::get_sample_users();
}
// Get a specific user by ID
fn get_user(user_id) {
let users = get_all_users();
return utils::find_by_id(users, user_id);
}
// Get user by email
fn get_user_by_email(email) {
let users = get_all_users();
for user in users {
if user.email == email {
return user;
}
}
return #{}; // Return empty object if not found
}
// Get users by timezone
fn get_users_by_timezone(timezone) {
let users = get_all_users();
return utils::filter_by_property(users, "timezone", timezone);
}
// Create a new user
fn create_user(name, email, timezone, notification_time, default_calendar_id) {
// Generate a simple ID (in a real app, we would use a proper ID generation method)
let id = "user" + (get_all_users().len() + 1).to_string();
let preferences = user_model::create_user_preferences(
notification_time, default_calendar_id
);
return user_model::create_user(
id, name, email, timezone, preferences
);
}
// Format user details for display
fn format_user(user) {
if utils::is_empty(user) {
return "User not found";
}
return `${user.name} (${user.email})
Timezone: ${user.timezone}
Default Calendar: ${user.preferences.default_calendar_id}
Notification Time: ${user.preferences.notification_time} minutes before`;
}

View File

@@ -0,0 +1,84 @@
// utils.rhai - Utility functions for the calendar backend
// Function to find an item by ID in an array
fn find_by_id(array, id) {
for item in array {
if item.id == id {
return item;
}
}
return #{}; // Return empty object if not found
}
// Function to filter array by a property value
fn filter_by_property(array, property, value) {
let result = [];
for item in array {
if item[property] == value {
result.push(item);
}
}
return result;
}
// Function to check if an object is empty
fn is_empty(obj) {
if obj.type_of() == "object" {
return obj.keys().len() == 0;
}
if obj.type_of() == "array" {
return obj.len() == 0;
}
return false;
}
// Function to format date string
fn format_date(date_str) {
// Simple formatting - in a real app, we would use proper date formatting
return date_str.substr(0, 10);
}
// Function to format time string
fn format_time(date_str) {
// Simple formatting - in a real app, we would use proper time formatting
if date_str.len() >= 16 {
return date_str.substr(11, 5);
}
return "";
}
// Function to check if an array contains a value
fn array_contains(array, value) {
for item in array {
if item == value {
return true;
}
}
return false;
}
// Function to get current date (simplified for demo)
fn get_current_date() {
return "2025-04-03";
}
// Function to calculate a future date (simplified for demo)
fn add_days_to_date(date_str, days) {
let year = date_str.substr(0, 4).parse_int();
let month = date_str.substr(5, 2).parse_int();
let day = date_str.substr(8, 2).parse_int() + days;
// Very simplified date calculation - in a real app, we would handle month/year boundaries
if day > 30 {
day = day - 30;
month += 1;
}
if month > 12 {
month = 1;
year += 1;
}
return `${year}-${month.to_string().pad_left(2, '0')}-${day.to_string().pad_left(2, '0')}`;
}