Skip to content

Elevate the maintainability and readability of your code by integrating Spinner. With its user-friendly features and intuitive design, Spinner streamlines development, making it easier to manage and comprehend intricate codebases.

License

Notifications You must be signed in to change notification settings

Daniel-iel/Spinner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

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

Repository files navigation


🎯 Introduction

Spinner is a high-performance .NET library for converting objects to and from positional (fixed-width) strings. Designed for scenarios where you need to work with legacy file formats, mainframe data, or any system that uses fixed-position text records.

Why Spinner?

  • ⚑ Blazing Fast - Up to 79x faster than previous versions
  • πŸ’Ύ Memory Efficient - Up to 26x less memory allocation
  • 🎯 Type-Safe - Compile-time validation with attributes
  • πŸ”§ Easy to Use - Simple, intuitive API
  • πŸ§ͺ Battle-Tested - High test coverage with mutation testing
  • πŸ“¦ Zero Dependencies - Lightweight and self-contained

Features

  • ? Blazing Fast Performance - Up to 79x faster than v1.x with optimized compiled delegates
  • ?? Memory Efficient - Up to 26x less memory allocation with ThreadStatic StringBuilder
  • ?? High-Throughput Ready - Process millions of records in milliseconds
  • ?? Zero-Allocation Scenarios - Near-zero allocation with Span-based operations
  • ?? Seamless Conversions - Effortlessly transform objects to/from positional strings
  • ?? Type-Safe Parsing - Built-in support for 18+ primitive types (int, decimal, DateTime, etc.)
  • ?? Configurable Padding - Left/Right padding with custom characters
  • ?? Custom Interceptors - Extensible value transformation pipeline

Performance Highlights

Operation v1.x v2.0 Improvement
ReadFromString 2.8 οΏ½s 46 ns 60x faster ?
WriteAsString 1.2 οΏ½s 40 ns 31x faster ?
Memory Usage 664-808 B 32-128 B 6-20x less ??

Benchmarks run on .NET 10.0 with BenchmarkDotNet. See detailed benchmarks for more information.

πŸ“‹ Use Cases

Spinner is perfect for:

  • Legacy System Integration - Parse and generate mainframe-style fixed-width files
  • EDI Processing - Handle Electronic Data Interchange formats
  • Banking & Finance - Process CNAB, FEBRABAN, and other financial formats
  • Government Systems - Work with standardized fixed-position government data
  • Data Migration - Convert between legacy and modern data formats
  • Report Generation - Create fixed-width reports for legacy systems

πŸš€ Quick Start

Installation

Install via NuGet Package Manager:

dotnet add package Spinner

Or via Package Manager Console:

Install-Package Spinner

Basic Usage - Writing Objects

Transform objects into positional strings:

[ObjectMapper(length: 50)]
public struct Nothing
{
  public Nothing(string name, string webSite)
  {
    this.Name = name;
    this.WebSite = webSite;
  }
  
  [WriteProperty(length: 20, order: 1, paddingChar: ' ')]
  public string Name { get; private set; }
  
  [WriteProperty(length: 30, order: 2, paddingChar: ' ')]
  public string WebSite { get; private set; }
}
    
 var nothing = new Nothing("spinner", "www.spinner.com.br");
 var spinner = new Spinner<Nothing>();
 var stringResponse = spinner.WriteAsString(nothing);   
 // Output: "              spinner            www.spinner.com.br"

Basic Usage - Reading Strings

Parse positional strings into objects:

[ObjectMapper(length: 50)]
public class NothingReader
{
  [ReadProperty(start: 0, length: 20)]        
  public string Name { get; set; }

  [ReadProperty(start: 20, length: 30)]        
  public string WebSite { get; set; }
}

var spinner = new Spinner<NothingReader>();
var obj = spinner.ReadFromString("              spinner            www.spinner.com.br");
// obj.Name = "spinner"
// obj.WebSite = "www.spinner.com.br"

Advanced Features

// Use Span for better performance
ReadOnlySpan<char> data = input.AsSpan();
var obj = spinner.ReadFromSpan(data);

// Custom padding
[WriteProperty(length: 10, order: 1, paddingChar: '0', padding: PaddingType.Left)]
public string Code { get; set; }  // "123" β†’ "0000000123"

// Automatic type conversion
[ReadProperty(start: 0, length: 10)]
public int Age { get; set; }  // Automatically parses string to int

[ReadProperty(start: 10, length: 20)]
public DateTime BirthDate { get; set; }  // Automatically parses to DateTime

For more examples, see the full documentation.

πŸ“š Documentation

For comprehensive documentation, visit our official website: spinnerframework.com

Quick Links

Contributing

We welcome contributions from the community! Here's how you can help:

Ways to Contribute

  • πŸ› Report Bugs - Found an issue? Open a bug report
  • ✨ Suggest Features - Have an idea? Request a feature
  • πŸ“– Improve Documentation - Help make our docs better
  • πŸ’» Submit Code - Fix bugs or implement new features
  • ⭐ Star the Repo - Show your support!

Development Setup

  1. Fork and Clone

    git clone https://github.com/YOUR-USERNAME/Spinner.git
    cd Spinner
  2. Build the Project

    cd src
    dotnet build
  3. Run Tests

    cd Spinner.Test
    dotnet test
  4. Run Benchmarks (optional)

    cd bench/Spinner.Benchmark
    dotnet run -c Release

Pull Request Guidelines

When submitting a PR, please follow these guidelines:

Before Creating a PR

  • βœ… Create an Issue First - Discuss your proposal before starting work
  • βœ… Fork the Repository - Work on your own fork
  • βœ… Create a Feature Branch - Use descriptive names (e.g., feature/add-new-padding-mode or fix/null-reference-bug)
  • βœ… Follow Code Style - Match the existing code style and conventions
  • βœ… Write Tests - Add or update tests for your changes
  • βœ… Update Documentation - If you change functionality, update the docs

PR Requirements

  • πŸ“ Clear Description - Explain what changes you made and why
  • πŸ”— Link Related Issues - Reference issues using Fixes #123 or Closes #456
  • βœ… All Tests Pass - Ensure dotnet test passes
  • πŸ“Š No Performance Regression - Run benchmarks for performance-critical changes
  • πŸ“š Documentation Updated - Update README.md or docs/ if needed
  • πŸ” Code Review Ready - Address all review comments promptly

PR Title Format

Use conventional commits format:

feat: Add support for custom date formats
fix: Resolve null reference in ReadFromSpan
docs: Update migration guide with examples
perf: Optimize StringBuilder allocation
test: Add unit tests for padding scenarios
refactor: Simplify property cache initialization

Example PR Description

## Description
This PR adds support for custom date format parsing using interceptors.

## Changes
- Added `DateFormatInterceptor` example to documentation
- Updated `mapping-string-into-type.md` with date parsing examples
- Added unit tests for date format validation

## Related Issues
Fixes #42

## Testing
- [x] All existing tests pass
- [x] Added new tests for date format parsing
- [x] Manually tested with multiple date formats

## Checklist
- [x] Code follows project style guidelines
- [x] Tests added/updated
- [x] Documentation updated
- [x] No breaking changes (or documented if breaking)

Code Standards

  • C# Version: Target .NET 5+
  • Code Style: Follow standard C# conventions
  • Naming: Use PascalCase for public members, camelCase for private
  • Performance: Consider memory allocations and performance impact
  • Thread Safety: Ensure code is thread-safe where applicable
  • Tests: Aim for high code coverage with meaningful tests

Running Mutation Tests

We use Stryker.NET for mutation testing:

cd src/Spinner.Test
dotnet stryker

Project Structure

Spinner/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ Spinner/           # Main library
β”‚   └── Spinner.Test/      # Unit tests
β”œβ”€β”€ bench/
β”‚   └── Spinner.Benchmark/ # Performance benchmarks
β”œβ”€β”€ docs/                  # Documentation (Docusaurus)
└── README.md

Community

Versioning

Spinner follows Semantic Versioning:

  • Major version (X.0.0) - Breaking changes
  • Minor version (0.X.0) - New features, backward compatible
  • Patch version (0.0.X) - Bug fixes, backward compatible

Supported .NET Versions

  • .NET 10.0
  • .NET 09.0
  • .NET 08.0

Roadmap

Planned features for future releases:

  • Source Generators for compile-time validation
  • Support for nested objects
  • Custom encoding support (EBCDIC, ASCII variants)
  • Async read/write operations for streams
  • Record type support
  • Enhanced error messages with detailed diagnostics

See our GitHub Issues for the full list of planned features and vote on what you'd like to see next!

Contributors

A huge thank you to all our contributors! πŸ™

Daniel-Profile

Want to see your name here? Check out our Contributing Guide and submit a PR!

Acknowledgments

  • BenchmarkDotNet - For excellent benchmarking tools
  • Stryker.NET - For mutation testing capabilities
  • All contributors - For making this project better

Support

If you find Spinner useful, consider:

  • ⭐ Star this repository - Help others discover the project
  • πŸ“’ Share with colleagues - Spread the word
  • πŸ’° Sponsor the project - Help maintain infrastructure (domain, SSL, CI/CD)
  • πŸ› Report issues - Help us improve quality
  • πŸ’» Contribute code - Make Spinner even better

Your support helps keep Spinner maintained and improved. All donations are used exclusively for project infrastructure (domain, SSL certificates, and CI/CD resources).

License

Spinner is licensed under the MIT License.

Copyright (c) 2025 Daniel-iel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

TL;DR - You can do whatever you want with this code as long as you include the original copyright and license notice.


πŸ“Š Project Stats

Repobeats analytics image


Made with ❀️ by the Daniel-Iel

⬆ Back to top

About

Elevate the maintainability and readability of your code by integrating Spinner. With its user-friendly features and intuitive design, Spinner streamlines development, making it easier to manage and comprehend intricate codebases.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages