Spinner 2.0.4-Preview
dotnet add package Spinner --version 2.0.4-Preview
NuGet\Install-Package Spinner -Version 2.0.4-Preview
<PackageReference Include="Spinner" Version="2.0.4-Preview" />
<PackageVersion Include="Spinner" Version="2.0.4-Preview" />
<PackageReference Include="Spinner" />
paket add Spinner --version 2.0.4-Preview
#r "nuget: Spinner, 2.0.4-Preview"
#:package Spinner@2.0.4-Preview
#addin nuget:?package=Spinner&version=2.0.4-Preview&prerelease
#tool nuget:?package=Spinner&version=2.0.4-Preview&prerelease
<div align="center"> <img src="./assets/logo.png?raw=true"> </div>
<div align="center">
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
Quick Links
- Getting Started - Installation and basic usage
- Writing Objects - Convert objects to positional strings
- Reading Strings - Parse positional strings to objects
- Interceptors - Custom value transformations
- Advanced Features - Thread-safety, padding, and optimizations
- Migration Guide - Upgrading from v1.x to v2.0
- Performance Benchmarks - Detailed performance analysis
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
Fork and Clone
git clone https://github.com/YOUR-USERNAME/Spinner.git cd SpinnerBuild the Project
cd src dotnet buildRun Tests
cd Spinner.Test dotnet testRun 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-modeorfix/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 #123orCloses #456 - β
All Tests Pass - Ensure
dotnet testpasses - π 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
- π¬ Discussions - GitHub Discussions
- π Issues - GitHub Issues
- π§ Contact - For security issues, contact the maintainers privately
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! π
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
Made with β€οΈ by the Daniel-Iel
</div>
| Product | Versions 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. |
-
net10.0
- ClrHeapAllocationAnalyzer (>= 3.0.0)
- Microsoft.CodeAnalysis (>= 5.0.0)
- Microsoft.CodeAnalysis.Common (>= 5.0.0)
- Microsoft.CodeAnalysis.CSharp (>= 5.0.0)
- Microsoft.VisualStudio.CoreUtility (>= 17.14.275)
- NoAlloq (>= 0.2.0)
-
net8.0
- ClrHeapAllocationAnalyzer (>= 3.0.0)
- Microsoft.CodeAnalysis (>= 5.0.0)
- Microsoft.CodeAnalysis.Common (>= 5.0.0)
- Microsoft.CodeAnalysis.CSharp (>= 5.0.0)
- Microsoft.VisualStudio.CoreUtility (>= 17.14.275)
- NoAlloq (>= 0.2.0)
-
net9.0
- ClrHeapAllocationAnalyzer (>= 3.0.0)
- Microsoft.CodeAnalysis (>= 5.0.0)
- Microsoft.CodeAnalysis.Common (>= 5.0.0)
- Microsoft.CodeAnalysis.CSharp (>= 5.0.0)
- Microsoft.VisualStudio.CoreUtility (>= 17.14.275)
- NoAlloq (>= 0.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 2.0.4-Preview | 113 | 12/25/2025 | |
| 2.0.3-Preview | 188 | 11/20/2023 | |
| 2.0.1-Preview | 211 | 2/6/2023 | |
| 2.0.0-Preview | 243 | 8/10/2022 | |
| 2.0.0-Pre-Realease | 119 | 12/25/2025 | |
| 1.1.20 | 818 | 9/24/2024 | |
| 1.1.9 | 117 | 9/24/2024 | |
| 1.1.8 | 1,483 | 11/9/2022 | |
| 1.1.7 | 429 | 11/5/2022 | |
| 1.1.6 | 1,879 | 3/6/2022 | |
| 1.1.5 | 517 | 3/6/2022 | |
| 1.1.4 | 361 | 1/5/2022 | |
| 1.1.3 | 4,890 | 12/20/2021 | |
| 1.1.2 | 385 | 12/18/2021 | |
| 1.1.1 | 1,294 | 11/28/2021 | |
| 1.1.0 | 988 | 11/21/2021 | |
| 1.0.0 | 601 | 10/30/2021 | |
| 1.0.0-RC1 | 1,052 | 11/14/2021 | |
| 1.0.0-Preview7 | 1,083 | 11/14/2021 | |
| 1.0.0-Preview6 | 1,031 | 11/14/2021 | |
| 1.0.0-Preview5 | 1,199 | 11/6/2021 | |
| 1.0.0-Preview4 | 1,130 | 10/31/2021 | |
| 1.0.0-Preview3 | 551 | 10/31/2021 | |
| 1.0.0-Preview2 | 556 | 10/31/2021 |