Skip to content

A comprehensive toolkit for Free Pascal that provides an easy-to-use, unified interface for common operations. Inspired by C++'s Boost.

License

Notifications You must be signed in to change notification settings

ikelaiah/tidykit-fp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”§ TidyKit: Robust Tools for Free Pascal Development!

FPC Lazarus License Documentation Tests Status Version

TidyKit streamlines your Pascal development experience.

Warning

⚠️ This library is under active development and is not yet ready for production use. APIs may change without notice.

✨ Say Goodbye to Boilerplate

Tired of writing the same code over and over? TidyKit helps you focus on your application logic instead of reinventing the wheel.

// JSON has never been easier
var
  Json: TJSONValue;
begin
  Json := TJSON.Parse('{"name":"Pascal","age":50}');
  WriteLn('Name: ', Json['name'].AsString);

  // Easy file operations
  var
    Files: TStringArray;
    FileName: string;
  begin
    Files := TFileKit.ListFiles('./data', '*.csv', True); // Recursively find all CSVs
    for FileName in Files do
      TFileKit.CopyFile(FileName, './backup/' + TFileKit.GetFileName(FileName));
  end;
  
  // Easy-to-use collections with interface-based memory management
  var
    NameList: IList<string>;
  begin
    NameList := CreateList<string>;  // no need to worry about freeing!
    NameList.Add('Alice');
    NameList.Add('Bob');
    NameList.Sort;
  end;
end;

🌟 Why TidyKit?

  • Everything You Need: One library with everything from JSON to file handling to collections
  • Modern Pascal: Clean, consistent APIs with FPC 3.2.2 compatibility
  • Rock-Solid Reliability: Extensive test suite ensures things just work
  • No Dependency Nightmares: Works on Windows and Linux with minimal external requirements
  • Smart Memory Management: Forget manual Destroy calls with interface-based reference counting
  • Ready-to-Use Collections: Lists, dictionaries, sets, and more with generic type safety

πŸ“‘ Table of Contents

πŸ’ͺ How TidyKit Makes Your Life Easier

We've designed TidyKit with one goal in mind: making your development experience smoother. Here's how we've organized things:

🧰 Three Simple Approaches

1. Just Call It - For simple operations like file handling or string manipulation:

// No objects to create, just call and go!
TFileKit.WriteTextFile('log.txt', 'Hello World');
NewStr := TStringKit.ToUpperCase('make me shout');

2. Smart Objects - For complex operations like JSON handling, with automatic cleanup:

// No manual memory management needed!
var JsonObj := TJSON.Parse(JsonText);
JsonObj['config']['enabled'] := True;
// When JsonObj goes out of scope, memory is automatically freed

3. Simple Records - For operations that need state without complexity:

// Easy to use with method chaining
var Request := TRequest.Create('https://api.example.com')
  .AddHeader('Content-Type', 'application/json')
  .SetTimeout(5000);
var Response := Request.Get;

Note

In our next version, we're streamlining things even further to make the API even more consistent and intuitive.

✨ What's Inside TidyKit?

TidyKit is packed with tools that make common programming tasks simple. Here's a taste of what you can do:

πŸ“ Text & Strings

Transform, validate, and manipulate text with ease

// Convert case styles seamlessly
var
  snake, kebab: string;
begin
  snake := TStringKit.ToSnakeCase('HelloWorld');
  kebab := TStringKit.ToKebabCase('HelloWorld');

  // Validate email addresses
  if TStringKit.IsValidEmail(email) then ...
end;

πŸ“‚ Files & Directories

Work with files without the headaches

// Find and filter files
var
  PascalFiles: TStringArray;
  Dir, FileName: string;
begin
  PascalFiles := TFileKit.ListFiles('.', '*.pas', True, fsDateDesc);

  // Easy path operations
  Dir := TFileKit.GetDirectory(Path);
  FileName := TFileKit.GetFileName(Path);
end;

πŸ“¦ Archives & Compression

Create and extract ZIP/TAR archives

// Extract ZIP files
TArchiveKit.ExtractZipFile('archive.zip', 'output_dir');

// Create TAR archives
TArchiveKit.CreateTarFile('src_dir', 'output.tar', '*.txt');

πŸ” Security & Crypto

Modern encryption and hashing

// Modern SHA3 hashing
var
  hash, encrypted: string;
begin
  hash := TCrypto.SHA3.ComputeHash(Data);

  // Simple AES-256 encryption
  encrypted := TCrypto.AES.Encrypt(plaintext, password);
end;

🌐 HTTP & Networking

Simplified web requests without the complexity

// GET request with just one line
var
  Response: TResponse;
begin
  Response := TRequest.Create(url).Get();
  
  // POST JSON data easily
  Response := TRequest.Create(url)
    .SetJSON(jsonObj).Post();
end;

πŸ” JSON Handling

Parse, create and modify JSON with ease

// Parse existing JSON
var
  config, user: TJSONValue;
begin
  config := TJSON.Parse(jsonText);

  // Build JSON programmatically
  user := TJSON.Obj
    .Add('name', 'Alice')
    .Add('age', 30);
end;

πŸ“ Powerful Logging

Flexible logging with multiple outputs

// Quick console logging (correct usage)
TLogger.CreateConsoleLogger();
Logger.Info('Starting up...');

// Structured file logging (correct usage)
TLogger.CreateFileLogger('app.log');
Logger.LogStructured(llInfo, 'UserLogin', [NameValuePair('user', username)]);

πŸ“š Type-Safe Collections

Modern generic collections with memory management

// Create a dictionary with string keys
var
  Dict: IDictionary<string, Integer>;
begin
  Dict := CreateDictionary<string, Integer>(@FNV1aHash, @TidyKitStringEquals);

  // Add and retrieve values
  Dict.Add('Alice', 30);
  WriteLn(Dict['Alice']); // Displays: 30
end;

πŸ“… DateTime Handling

Powerful date and time operations

// Date calculations made simple
var
  Today, Tomorrow, NextWeek: TDateTime;
  FormattedDate: string;
begin
  Today := TDateTimeKit.Today;
  Tomorrow := TDateTimeKit.AddDays(Today, 1);
  NextWeek := TDateTimeKit.AddWeeks(Today, 1);
  
  // Format dates easily
  FormattedDate := TDateTimeKit.Format(Today, 'yyyy-mm-dd');
end;

πŸ’‘ Command-Line Parsing

Parse command-line arguments with ease

// Define and parse arguments
var
  Args: TParseArgs;
begin
  Args := TParseArgs.Create
    .Add('v|verbose', 'Enable verbose output')
    .Add('f|file=', 'Input file path')
    .Parse;
end;

πŸ“š Documentation

Extensive documentation for all features

// Documentation for all units
// See our detailed docs for more information

All Features at a Glance

  • πŸ“ String Operations: Case conversion, validation, pattern matching, Unicode support
  • πŸ“‚ File System: File manipulation, path operations, searching and filtering
  • πŸ“¦ Archive: ZIP/TAR compression with pattern-based filtering
  • πŸ” Cryptography: SHA3, SHA2, AES-256 encryption, secure hashing
  • 🌐 Network: HTTP client with request/response handling
  • πŸ” JSON: Memory-managed JSON with full Unicode support
  • πŸ“ Logging: Multi-destination logging with structured data support
    • πŸ› οΈ Command Line Parsing: Easy-to-use argument parser with support for various data types
      • TidyKit.ParseArgs - For parsing command-line arguments with support for:
        • String, integer, float, and boolean options
        • Required and optional parameters
        • Automatic help generation
        • Callback support for custom argument handling
        • Array parameters for handling multiple values
    • πŸ“š Collections: Type-safe lists, dictionaries, sets, and queues
      • When to use each collection:
        • TidyKit.Collections.List - For sequential access and general-purpose ordered collections
        • TidyKit.Collections.Dictionary - For key-value storage with O(1) average time complexity (uses separate chaining for collision resolution)
        • TidyKit.Collections.Deque - For double-ended queues and efficient operations at both ends
        • TidyKit.Collections.HashSet - For unique unordered collections with fast lookups
      • Documentation: See our detailed docs for Dictionary and HashSet
      • All collections support automatic memory management via interfaces (no manual Destroy calls needed)
      • Note: for..in..do enumeration is not supported; use indexed access or ToArray for traversal

πŸ’» Installation (Lazarus IDE)

  1. Clone the repository:
git clone https://github.com/ikelaiah/tidykit-fp
  1. Open / start a new project in Lazarus IDE

  2. Go to Package β†’ Open Package File (.lpk)...

  3. Navigate to the TidyKit packages in the packages/lazarus/ folder and select TidyKit.lpk

  4. In the package window that opens, click Compile

  5. Click Use β†’ Add to Project to install the package

The TidyKit package is now ready to use in your Lazarus project.

πŸ’» Installation (General)

  1. Clone the repository:
git clone https://github.com/ikelaiah/tidykit-fp
  1. Add the source directory to your project's search path.

πŸ“ Library Usage

uses
  // String manipulation unit
  TidyKit.Strings,           // String operations

  // File system operations
  TidyKit.FS,                // File system operations

  // Date Time manipulation unit
  TidyKit.DateTime,          // Date Time operations

  // JSON functionality
  TidyKit.JSON,              // All JSON functionality

  // Logging functionality
  TidyKit.Logger,            // Easy to use logging system

  // Network units
  TidyKit.Request,           // HTTP client with simple and advanced features

  // Cryptography units
  TidyKit.Crypto,            // Base crypto operations
  TidyKit.Crypto.SHA2,       // SHA2 implementation
  TidyKit.Crypto.SHA3,       // SHA3 implementation
  TidyKit.Crypto.AES256,     // AES-256 implementation

  // Archive operations
  TidyKit.Archive,           // Archive operations

  // Command-line argument parsing
  TidyKit.ParseArgs,         // Simple argument parser

  // Collections
  TidyKit.Collections.List,  // Generic List implementation
  TidyKit.Collections.Deque, // Generic Deque implementation
  TidyKit.Collections.HashSet; // Generic HashSet implementation

πŸš€ Quick Start

πŸ“ String Operations

var
  Text: string;
begin
  // Email validation
  if TStringKit.MatchesPattern('[email protected]', '^[\w\.-]+@[\w\.-]+\.\w+$') then
    WriteLn('Valid email');
    
  // Format phone number
  Text := TStringKit.PadLeft('5551234', 10, '0');  // Returns '0005551234'
  
  // Clean user input
  Text := TStringKit.CollapseWhitespace('  Hello    World  ');  // Returns 'Hello World'
  
  // Format product code
  Text := TStringKit.PadCenter('A123', 8, '-');  // Returns '--A123---'
end;

πŸ“‚ File System Operations

var
  Files: TFilePathArray;
  Attrs: TFileAttributes;
  Content: string;
begin
  // Basic file operations
  TFileKit.WriteFile('example.txt', 'Hello World');
  Content := TFileKit.ReadFile('example.txt');
  
  // Directory operations
  TFileKit.CreateDirectory('new_folder');
  TFileKit.EnsureDirectory('path/to/folder');
  
  // List files with pattern matching
  Files := TFileKit.ListFiles('src', '*.pas', True, fsName);
  
  // Get file attributes
  Attrs := TFileKit.GetAttributes('example.txt');
  WriteLn(Format('Read-only: %s', [BoolToStr(Attrs.ReadOnly, True)]));
  
  // File manipulation
  TFileKit.CopyFile('source.txt', 'dest.txt');
  TFileKit.MoveFile('old.txt', 'new.txt');
  TFileKit.DeleteFile('temp.txt');
  
  // Path operations
  WriteLn(TFileKit.GetFileName('path/to/file.txt')); // Returns 'file.txt'
  WriteLn(TFileKit.GetExtension('script.pas')); // Returns '.pas'
  WriteLn(TFileKit.ChangeExtension('test.txt', '.bak')); // Returns 'test.bak'
end;

πŸ“… DateTime Operations

var
  CurrentTime: TDateTime;
  NextWorkday: TDateTime;
  TZInfo: TTimeZoneInfo;
  OriginalTZ: string;
  DSTTransitionDate: TDateTime;
begin
  // Get next business day for delivery date
  CurrentTime := TDateTimeKit.GetNow;
  NextWorkday := TDateTimeKit.NextBusinessDay(CurrentTime);
  
  // Format for display
  WriteLn(TDateTimeKit.GetAsString(NextWorkday, 'yyyy-mm-dd'));
  
  // Check if within business hours (9 AM - 5 PM)
  if TDateTimeKit.IsWithinInterval(CurrentTime, 
     TDateTimeKit.CreateInterval(
       TDateTimeKit.StartOfDay(CurrentTime) + EncodeTime(9, 0, 0, 0),
       TDateTimeKit.StartOfDay(CurrentTime) + EncodeTime(17, 0, 0, 0)
     )) then
    WriteLn('Within business hours');
    
  // Cross-platform timezone handling
  TZInfo := TDateTimeKit.GetTimeZone(CurrentTime);
  WriteLn('Current timezone: ', TZInfo.Name);
  WriteLn('Offset from UTC: ', TZInfo.Offset, ' minutes');
  WriteLn('DST active: ', BoolToStr(TZInfo.IsDST, True));
  
  // Convert between timezones
  WriteLn('UTC time: ', TDateTimeKit.GetAsString(
    TDateTimeKit.WithTimeZone(CurrentTime, 'UTC'), 
    'yyyy-mm-dd hh:nn:ss'));
    
  // Cross-platform environment variables for testing
  OriginalTZ := GetEnvVar('TZ');
  try
    // Change timezone for testing
    SetEnvVar('TZ', 'America/New_York');
    
    // Create a datetime value near the US DST transition 
    // (2:00 AM on second Sunday in March 2024)
    DSTTransitionDate := EncodeDateTime(2024, 3, 10, 2, 0, 0, 0);
    
    // Check if this time is in DST using GetTimeZone
    TZInfo := TDateTimeKit.GetTimeZone(DSTTransitionDate);
    WriteLn('DST active: ', BoolToStr(TZInfo.IsDST, True));
    WriteLn('Timezone offset: ', TZInfo.Offset, ' minutes');
  finally
    // Restore original timezone
    SetEnvVar('TZ', OriginalTZ);
  end;
end;

πŸ”„ JSON Operations

var
  Person: IJSONObject;
  Address: IJSONObject;
  Hobbies: IJSONArray;
  JSON: string;
  Value: IJSONValue;
begin
  // Create a person object
  Person := TJSON.Obj;
  Person.Add('name', 'John Smith');
  Person.Add('age', 30);
  Person.Add('isActive', True);
  
  // Create and add an address object
  Address := TJSON.Obj;
  Address.Add('street', '123 Main St');
  Address.Add('city', 'Springfield');
  Address.Add('zipCode', '12345');
  Person.Add('address', Address);
  
  // Create and add a hobbies array
  Hobbies := TJSON.Arr;
  Hobbies.Add('reading');
  Hobbies.Add('cycling');
  Hobbies.Add('swimming');
  Person.Add('hobbies', Hobbies);
  
  // Convert to JSON string with pretty printing
  JSON := Person.ToString(True);
  WriteLn(JSON);
  
  // Parse JSON string
  JSON := '{"name":"Jane Doe","age":25,"skills":["Pascal","Python"]}';
  Value := TJSON.Parse(JSON);
  Person := Value.AsObject;
  
  // Access values
  WriteLn('Name: ', Person['name'].AsString);
  WriteLn('Age: ', Person['age'].AsInteger);
  WriteLn('First Skill: ', Person['skills'].AsArray[0].AsString);
  
  // Error handling
  try
    Value := TJSON.Parse('{invalid json}');
  except
    on E: EJSONException do
      WriteLn('Error: ', E.Message);
  end;
end;

πŸ“ Logging Operations

// Simple one-line setup for console and file logging
TLogger.CreateConsoleAndFileLogger('application.log', llInfo);

// Log messages with different levels
Logger.Debug('Processing started'); // Only shown if minimum level is Debug
Logger.Info('User %s logged in', ['JohnDoe']);
Logger.Warning('Disk space is low: %d%% remaining', [5]);
Logger.Error('Failed to save file: %s', ['Access denied']);
Logger.Fatal('Application crashed: %s', ['Segmentation fault']);

// Create category-based loggers for better organization
var
  UILogger, DBLogger: ILogContext;
begin
  UILogger := Logger.CreateContext('UI');
  DBLogger := Logger.CreateContext('DB');
  
  UILogger.Info('Window created');
  DBLogger.Warning('Slow query detected: %s', ['SELECT * FROM large_table']);
end;

// Time operations and log their duration
var
  Timer: ITimedOperation;
begin
  Timer := Logger.TimedBlock('Data processing');
  // ... perform long operation ...
  // Timer automatically logs completion with duration when it goes out of scope
end;

// IMPORTANT: Always close log files when shutting down
try
  // Your application logic with logging...
finally
  Logger.CloseLogFiles;  // Ensures all data is written to disk
end;

🌐 HTTP Request Operations

var
  Response: TResponse;
  UserData: IJSONObject;
  ApiResponse: IJSONObject;
  Result: TRequestResult;
begin
  // Simple GET request with JSON response
  Response := Http.Get('https://api.example.com/data');
  if Response.StatusCode = 200 then
  begin
    ApiResponse := Response.JSON.AsObject;
    WriteLn('User ID: ', ApiResponse['id'].AsInteger);
    WriteLn('Username: ', ApiResponse['username'].AsString);
  end;
    
  // POST with JSON data
  UserData := TJSON.Obj;
  UserData.Add('name', 'John Smith');
  UserData.Add('email', '[email protected]');
  UserData.Add('age', 30);
  
  Response := Http.PostJSON('https://api.example.com/users',
    UserData.ToString);
    
  if Response.StatusCode = 201 then
    WriteLn('User created with ID: ', Response.JSON.AsObject['id'].AsString);
    
  // Error handling with TryGet pattern
  Result := Http.TryGet('https://api.example.com/users');
  if Result.Success then
    WriteLn('Found ', Result.Response.JSON.AsObject['count'].AsInteger, ' users')
  else
    WriteLn('Error: ', Result.Error);
    
  // Download file with custom headers
  Response := Http.Get('https://example.com/large-file.zip');
  TFileKit.WriteFile('download.zip', Response.Text);
end;

πŸ” Crypto Operations

var
  Hash: string;
  Encrypted: string;
begin
  // Hash password for storage
  Hash := TCryptoKit.SHA512Hash('user_password');
  
  // Secure configuration data
  Encrypted := TCryptoKit.BlowfishCrypt(
    '{"api_key": "secret123"}',
    'encryption_key',
    bmEncrypt
  );
  
  // Verify file integrity
  Hash := TCryptoKit.SHA256Hash(TFileKit.ReadFile('important.dat'));
end;

πŸ“¦ Archive Operations

var
  SourceDir, DestDir: string;
begin
  // Create ZIP archive
  SourceDir := 'path/to/source';
  TArchiveKit.CompressToZip(SourceDir, 'archive.zip', True);  // Recursive
  
  // Extract specific files
  DestDir := 'path/to/extract';
  TArchiveKit.DecompressFromZip('archive.zip', DestDir, '*.txt');  // Only .txt files
  
  // Create TAR archive with specific files
  TArchiveKit.CompressToTar(SourceDir, 'backup.tar', True, '*.pas');  // Only .pas files
  
  // Extract entire TAR archive
  TArchiveKit.DecompressFromTar('backup.tar', DestDir);
end;

πŸ“š Collections Operations

uses
  TidyKit.Collections.List, TidyKit.Collections.Deque, 
  TidyKit.Collections.HashSet, TidyKit.Collections.HashFunction, 
  TidyKit.Collections.EqualityFunction;

var
  // Example for TList<T>
  MyIntList: IList<Integer>;
  I: Integer;

  // Example for TDeque<T>
  MyStringDeque: IDeque<string>;

  // Example for THashSet<T>
  MyHashSet: IHashSet<string>;
begin
  // --- TList<T> Example ---
  MyIntList := CreateList<Integer>; // Using helper for interface-based management
  MyIntList.Add(10);
  MyIntList.Add(20);
  MyIntList.Insert(1, 15); // List is now: 10, 15, 20

  Write('List items: ');
  for I := 0 to MyIntList.Count - 1 do
    Write(MyIntList[I], ' ');
  WriteLn; // Output: 10 15 20

  // --- TDeque<T> Example ---
  MyStringDeque := CreateDeque<string>; // Using helper for interface-based management
  MyStringDeque.PushBack('apples');
  MyStringDeque.PushFront('bananas'); // Deque is now: 'bananas', 'apples'
  MyStringDeque.PushBack('cherries'); // Deque is now: 'bananas', 'apples', 'cherries'

  Write('Deque items (popping from front): ');
  while MyStringDeque.Count > 0 do
    Write(MyStringDeque.PopFront, ' ');
  WriteLn; // Output: bananas apples cherries

  // --- THashSet<T> Example with specialized hash functions ---
  MyHashSet := CreateHashSet<string>(@XXHash32, @TidyKitStringEquals);
  MyHashSet.Add('apple');
  MyHashSet.Add('banana');
  MyHashSet.Add('cherry');
  MyHashSet.Add('apple'); // Duplicate, won't be added

  Write('HashSet items: ');
  for I := 0 to MyHashSet.ToArray.Count - 1 do
    Write(MyHashSet.ToArray[I], ' ');
  WriteLn; // Output: apple banana cherry

  // No explicit Free needed as these are interface variables
  // and will be automatically managed.
end;

πŸ“– System Requirements

Tested Environments

Module Windows 11 Ubuntu 24.04.2
TidyKit.Strings βœ… βœ…
TidyKit.FS βœ… βœ…
TidyKit.DateTime βœ… βœ…
TidyKit.JSON βœ… βœ…
TidyKit.JSON.Factory βœ… βœ…
TidyKit.JSON.Parser βœ… βœ…
TidyKit.JSON.Scanner βœ… βœ…
TidyKit.JSON.Types βœ… βœ…
TidyKit.JSON.Writer βœ… βœ…
TidyKit.Logger βœ… βœ…
TidyKit.Request βœ… βœ…
TidyKit.Crypto βœ… βœ…
TidyKit.Crypto.AES256 βœ… βœ…
TidyKit.Crypto.SHA2 βœ… βœ…
TidyKit.Crypto.SHA3 βœ… βœ…
TidyKit.Archive βœ… βœ…
TidyKit.Collections βœ… βœ…
TidyKit.Collections.Deque βœ… βœ…
TidyKit.Collections.Dictionary βœ… βœ…
TidyKit.Collections.EqualityFunction βœ… βœ…
TidyKit.Collections.HashFunction βœ… βœ…
TidyKit.Collections.HashSet βœ… βœ…
TidyKit.Collections.List βœ… βœ…
TidyKit.ParseArgs βœ… βœ…

Dependencies

  • Windows
    • No external dependencies required
  • Linux
    • Ubuntu/Debian: sudo apt-get install libssl-dev (needed for HTTPS in TidyKit.Request)
    • Fedora/RHEL: sudo dnf install openssl-devel (needed for HTTPS in TidyKit.Request)
  • Uses only standard Free Pascal RTL units

Build Requirements

  • Free Pascal Compiler (FPC) 3.2.2+
  • Lazarus 3.6+
  • Basic development tools (git, terminal, etc)

πŸ“š Documentation

For detailed documentation, see:

πŸ“Š Real-World Examples

TidyKit can be used to build a wide variety of applications quickly:

Example Project Description Source Code
File System Utility Batch operations on files with pattern matching View Example
Simple File Explorer Navigate directories, view files, and perform file operations with an interactive console UI View Example
File Analyzer Analyze text files, count word frequencies, and gather directory statistics View Example
File Backup Backup files and folders, supports simulate run View Example
Simple Data Logger Record sensor readings with timestamp and export as CSV View Example
Configuration Manager Load, parse, and validate JSON configuration files View Example
Secure Password Storage Hash and verify passwords with SHA-256 View Example
Date Calculator Business day calculator with timezone handling View Example

πŸ’¬ Community & Support

⚠️ Known Limitations

  • Platform Support: Currently only tested on Windows 11 and Ubuntu 24.04. MacOS and FreeBSD are not officially supported.
  • Threading: Batch logging mode is not thread-safe. Use in single-threaded contexts or implement your own synchronization.
  • HTTP SSL: HTTPS requests require OpenSSL libraries on Linux systems (see Dependencies section).
  • Timezone Support: Limited timezone support on Unix-like systems.
  • Language Features: Designed for FPC 3.2.2, so no use of inline var declarations or anonymous functions.
  • Library Integration: Currently no integration with package managers.

βœ… Testing

  1. Open the TestRunner.lpi using Lazarus IDE
  2. Compile the project
  3. Run the Test Runner:
$ cd tests
$ ./TestRunner.exe -a --format=plain

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

βš–οΈ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • FPC Team for Free Pascal
  • Contributors and maintainers

πŸ—ΊοΈ Roadmap

TidyKit is under active development. Here's what's planned:

Planned for v0.2.0 (Q3 2025) - Simplify API

  • Provide a simpler API.

Planned for v0.3.0 (Q4 2025) - Examples & Refinements

  • Add more real-world examples and tutorials demonstrating common use cases.
  • Performance optimizations based on profiling.
  • Expand unit test coverage, especially for edge cases identified during API simplification.

Future Goals

  • Command line argument parser module.
  • Thread-safe collections and data structures module.
  • Concurrency module.
  • Integration with package managers.

Feedback and suggestions are welcome! See the issues page to contribute ideas or track progress.

About

A comprehensive toolkit for Free Pascal that provides an easy-to-use, unified interface for common operations. Inspired by C++'s Boost.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages