Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
next-version: 1.0.1
next-version: 1.1.0
tag-prefix: '[vV]'
mode: ContinuousDeployment
branches:
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2025 Code Shayk
Copyright (c) 2025 CØDE SHΔYK

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
11 changes: 9 additions & 2 deletions Parsley.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ Please see below.
```
public interface IParser
{
public T[] Parse<T>(string filepath) where T : IFileLine, new();
public T[] Parse<T>(string[] lines) where T : IFileLine, new();
T[] Parse<T>(string filepath) where T : IFileLine, new();
T[] Parse<T>(string[] lines) where T : IFileLine, new();
T[] Parse<T>(Stream stream) where T : IFileLine, new();
T[] Parse<T>(byte[] bytes) where T : IFileLine, new();

T[] ParseAsync<T>(string filepath) where T : IFileLine, new();
T[] ParseAsync<T>(string[] lines) where T : IFileLine, new();
T[] ParseAsync<T>(Stream stream) where T : IFileLine, new();
T[] ParseAsync<T>(byte[] bytes) where T : IFileLine, new();
}
```
To initialise `Parser` class you could do it manually or use dependency injection as shown below. The parser class has parameterised constructor that takes the delimiter character to initialise the instance. Default character is ',' (comma) to initialise the parser for a CSV file parsing.
Expand Down
70 changes: 66 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# <img src="https://github.com/CodeShayk/parsley.net/blob/master/Images/ninja-icon-16.png" alt="ninja" style="width:30px;"/> Parsley.Net v1.0.1
# <img src="https://github.com/CodeShayk/parsley.net/blob/master/Images/ninja-icon-16.png" alt="ninja" style="width:30px;"/> Parsley.Net v1.1.0
[![NuGet version](https://badge.fury.io/nu/Parsley.Net.svg)](https://badge.fury.io/nu/Parsley.Net) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/CodeShayk/Parsley.Net/blob/master/LICENSE.md)
[![GitHub Release](https://img.shields.io/github/v/release/CodeShayk/Parsley.Net?logo=github&sort=semver)](https://github.com/CodeShayk/Parsley.Net/releases/latest)
[![master-build](https://github.com/CodeShayk/parsley.net/actions/workflows/Master-Build.yml/badge.svg)](https://github.com/CodeShayk/parsley.net/actions/workflows/Master-Build.yml)
Expand Down Expand Up @@ -36,16 +36,78 @@ NuGet\Install-Package Parsley.Net
```
### ii. Implementation: Using Parsley.Net
#### <ins>Step 1<ins>. Initialise and use Parser class.
`Parser` is an implementation of `IParser` interface that provides methods for
`Parser` is an implementation of `IParser` interface that provides sync and async methods for
- parsing content of a file by specifying the file path
- parsing an array of delimiter separated strings
- parsing a stream of delimiter separated strings
- parsing byte array of delimiter separated strings

Please see below.
```
public interface IParser
{
public T[] Parse<T>(string filepath) where T : IFileLine, new();
public T[] Parse<T>(string[] lines) where T : IFileLine, new();
/// <summary>
/// Parses a file at the specified filepath into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filepath"></param>
/// <returns></returns>
T[] Parse<T>(string filepath) where T : IFileLine, new();

/// <summary>
/// Parses an array of delimiter seperated strings into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="lines"></param>
/// <returns></returns>
T[] Parse<T>(string[] lines) where T : IFileLine, new();

/// <summary>
/// Parses a stream of delimiter separated records into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <returns></returns>
T[] Parse<T>(Stream stream) where T : IFileLine, new();

/// <summary>
/// Parses an array of bytes of delimiter separated records into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bytes"></param>
/// <returns></returns>
T[] Parse<T>(byte[] bytes) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses a file at the specified filepath into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filepath"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(string filepath) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses an array of delimiter separated strings into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="lines"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(string[] lines) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(Stream stream) where T : IFileLine, new();
/// <summary>
/// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bytes"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(byte[] bytes) where T : IFileLine, new();
}
```
To initialise `Parser` class you could do it manually or use dependency injection as shown below. The parser class has parameterised constructor that takes the delimiter character to initialise the instance. Default character is ',' (comma) to initialise the parser for a CSV file parsing.
Expand Down
65 changes: 64 additions & 1 deletion src/Parsley/IParser.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,72 @@
using System.IO;
using System.Threading.Tasks;

namespace parsley
{
public interface IParser
{
/// <summary>
/// Parses a file at the specified filepath into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filepath"></param>
/// <returns></returns>
T[] Parse<T>(string filepath) where T : IFileLine, new();

T[] Parse<T>(string[] lines) where T : IFileLine, new();
/// <summary>
/// Parses an array of delimiter seperated strings into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="lines"></param>
/// <returns></returns>
T[] Parse<T>(string[] lines) where T : IFileLine, new();

/// <summary>
/// Parses a stream of delimiter separated records into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <returns></returns>
T[] Parse<T>(Stream stream) where T : IFileLine, new();

/// <summary>
/// Parses an array of bytes of delimiter separated records into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bytes"></param>
/// <returns></returns>
T[] Parse<T>(byte[] bytes) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses a file at the specified filepath into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filepath"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(string filepath) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses an array of delimiter separated strings into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="lines"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(string[] lines) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(Stream stream) where T : IFileLine, new();

/// <summary>
/// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bytes"></param>
/// <returns></returns>
Task<T[]> ParseAsync<T>(byte[] bytes) where T : IFileLine, new();
}
}
92 changes: 91 additions & 1 deletion src/Parsley/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace parsley
Expand Down Expand Up @@ -77,7 +78,7 @@ private string[] ReadToLines(string path)
}

return lines.ToArray<string>();
}
}

private T ParseLine<T>(string line) where T : IFileLine, new()
{
Expand Down Expand Up @@ -163,5 +164,94 @@ private string[] GetDelimiterSeparatedValues(string line)
.ToArray();
return values;
}

public T[] Parse<T>(Stream stream) where T : IFileLine, new()
{
if (stream == null || stream.Length == 0)
return Array.Empty<T>();

var lines = new List<string>();
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var trimmedLine = line.Trim();
if (!string.IsNullOrWhiteSpace(trimmedLine))
lines.Add(trimmedLine);
line = null;
}
}

return lines.Any() ? Parse<T>(lines.ToArray()) : Array.Empty<T>();
}

public T[] Parse<T>(byte[] bytes) where T : IFileLine, new()
{
if (bytes == null || bytes.Length == 0)
return Array.Empty<T>();

return Parse<T>(new MemoryStream(bytes));
}

public async Task<T[]> ParseAsync<T>(string filepath) where T : IFileLine, new()
{
if (string.IsNullOrEmpty(filepath) || !File.Exists(filepath))
return Array.Empty<T>();

var lines = await Task.Run(() => ReadToLines(filepath));

return await ParseAsync<T>(lines);
}

public async Task<T[]> ParseAsync<T>(string[] lines) where T : IFileLine, new()
{
if (lines == null || lines.Length == 0)
return Array.Empty<T>();

var list = new T[lines.Length];
var index = 0;
var inputs = lines.Select(line => new { Line = line, Index = index++ });

foreach (var input in inputs)
{
if (string.IsNullOrWhiteSpace(input.Line))
continue;

var parsedLine = await Task.Run(() => ParseLine<T>(input.Line));

if (parsedLine != null)
{
parsedLine.Index = input.Index;
list[parsedLine.Index] = parsedLine;
}
}
return list;
}

public async Task<T[]> ParseAsync<T>(Stream stream) where T : IFileLine, new()
{
var lines = new List<string>();
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
var trimmedLine = line.Trim();
if (!string.IsNullOrWhiteSpace(trimmedLine))
lines.Add(trimmedLine);
}
}

return lines.Any() ? await ParseAsync<T>(lines.ToArray()) : Array.Empty<T>();
}

public async Task<T[]> ParseAsync<T>(byte[] bytes) where T : IFileLine, new()
{
if (bytes == null || bytes.Length == 0)
return Array.Empty<T>();

return await ParseAsync<T>(new MemoryStream(bytes));
}
}
}
9 changes: 5 additions & 4 deletions src/Parsley/Parsley.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net462; netstandard2.0;netstandard2.1; net9.0</TargetFrameworks>
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net9.0</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings>
<Title>Parsley.Net</Title>
<Authors>CodeShayk</Authors>
Expand All @@ -20,9 +20,10 @@
<PackageProjectUrl>https://github.com/CodeShayk/Parsley.Net/wiki</PackageProjectUrl>
<RepositoryUrl>https://github.com/CodeShayk/Parsley.Net</RepositoryUrl>
<PackageReleaseNotes>
v1.0.1 - Targets .Net9.0, .NetStandard2.1, .NetStandard2.0, and .NetFramework4.6.4. <br/>
* Includes core functionality for parsing delimiter separated files.</PackageReleaseNotes>
<Version>1.0.1</Version>
v1.1.0 - Targets .Net9.0, .NetStandard2.1, .NetStandard2.0, and .NetFramework4.6.4. <br/>
* Includes core functionality for parsing delimiter separated files.
* Provided Sync and Async parsing methods</PackageReleaseNotes>
<Version>1.1.0</Version>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<AssemblyName>Parsley.Net</AssemblyName>
</PropertyGroup>
Expand Down
Loading
Loading