Spinner 2.0.4-Preview

This is a prerelease version of Spinner.
dotnet add package Spinner --version 2.0.4-Preview
                    
NuGet\Install-Package Spinner -Version 2.0.4-Preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Spinner" Version="2.0.4-Preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Spinner" Version="2.0.4-Preview" />
                    
Directory.Packages.props
<PackageReference Include="Spinner" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Spinner --version 2.0.4-Preview
                    
#r "nuget: Spinner, 2.0.4-Preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Spinner@2.0.4-Preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Spinner&version=2.0.4-Preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Spinner&version=2.0.4-Preview&prerelease
                    
Install as a Cake Tool

<div align="center"> <img src="./assets/logo.png?raw=true"> </div>

<div align="center">

Contributors Activity CI Documentation Benchmarks OpenSSF Best Practices

NuGet Downloads License Code Factor DeepSource codecov Known Vulnerabilities Buy Me A Coffee

Documentation | Getting Started | API Reference

</div>


🎯 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

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.


<div align="center">

πŸ“Š Project Stats

Repobeats analytics image


Made with ❀️ by the Daniel-Iel

⬆ Back to top

</div>

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.