Skip to content

Commit f2e917a

Browse files
committed
- v1.1.0 - Includes sync and async parsing methods
1 parent 41066b2 commit f2e917a

File tree

7 files changed

+425
-13
lines changed

7 files changed

+425
-13
lines changed

GitVersion.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
next-version: 1.0.1
1+
next-version: 1.1.0
22
tag-prefix: '[vV]'
33
mode: ContinuousDeployment
44
branches:

Parsley.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ Please see below.
1515
```
1616
public interface IParser
1717
{
18-
public T[] Parse<T>(string filepath) where T : IFileLine, new();
19-
public T[] Parse<T>(string[] lines) where T : IFileLine, new();
18+
T[] Parse<T>(string filepath) where T : IFileLine, new();
19+
T[] Parse<T>(string[] lines) where T : IFileLine, new();
20+
T[] Parse<T>(Stream stream) where T : IFileLine, new();
21+
T[] Parse<T>(byte[] bytes) where T : IFileLine, new();
22+
23+
T[] ParseAsync<T>(string filepath) where T : IFileLine, new();
24+
T[] ParseAsync<T>(string[] lines) where T : IFileLine, new();
25+
T[] ParseAsync<T>(Stream stream) where T : IFileLine, new();
26+
T[] ParseAsync<T>(byte[] bytes) where T : IFileLine, new();
2027
}
2128
```
2229
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.

README.md

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# <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
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
22
[![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)
33
[![GitHub Release](https://img.shields.io/github/v/release/CodeShayk/Parsley.Net?logo=github&sort=semver)](https://github.com/CodeShayk/Parsley.Net/releases/latest)
44
[![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)
@@ -36,16 +36,78 @@ NuGet\Install-Package Parsley.Net
3636
```
3737
### ii. Implementation: Using Parsley.Net
3838
#### <ins>Step 1<ins>. Initialise and use Parser class.
39-
`Parser` is an implementation of `IParser` interface that provides methods for
39+
`Parser` is an implementation of `IParser` interface that provides sync and async methods for
4040
- parsing content of a file by specifying the file path
4141
- parsing an array of delimiter separated strings
42+
- parsing a stream of delimiter separated strings
43+
- parsing byte array of delimiter separated strings
4244

4345
Please see below.
4446
```
4547
public interface IParser
4648
{
47-
public T[] Parse<T>(string filepath) where T : IFileLine, new();
48-
public T[] Parse<T>(string[] lines) where T : IFileLine, new();
49+
/// <summary>
50+
/// Parses a file at the specified filepath into an array of objects of type T.
51+
/// </summary>
52+
/// <typeparam name="T"></typeparam>
53+
/// <param name="filepath"></param>
54+
/// <returns></returns>
55+
T[] Parse<T>(string filepath) where T : IFileLine, new();
56+
57+
/// <summary>
58+
/// Parses an array of delimiter seperated strings into an array of objects of type T.
59+
/// </summary>
60+
/// <typeparam name="T"></typeparam>
61+
/// <param name="lines"></param>
62+
/// <returns></returns>
63+
T[] Parse<T>(string[] lines) where T : IFileLine, new();
64+
65+
/// <summary>
66+
/// Parses a stream of delimiter separated records into an array of objects of type T.
67+
/// </summary>
68+
/// <typeparam name="T"></typeparam>
69+
/// <param name="stream"></param>
70+
/// <returns></returns>
71+
T[] Parse<T>(Stream stream) where T : IFileLine, new();
72+
73+
/// <summary>
74+
/// Parses an array of bytes of delimiter separated records into an array of objects of type T.
75+
/// </summary>
76+
/// <typeparam name="T"></typeparam>
77+
/// <param name="bytes"></param>
78+
/// <returns></returns>
79+
T[] Parse<T>(byte[] bytes) where T : IFileLine, new();
80+
81+
/// <summary>
82+
/// Asynchronously parses a file at the specified filepath into an array of objects of type T.
83+
/// </summary>
84+
/// <typeparam name="T"></typeparam>
85+
/// <param name="filepath"></param>
86+
/// <returns></returns>
87+
Task<T[]> ParseAsync<T>(string filepath) where T : IFileLine, new();
88+
89+
/// <summary>
90+
/// Asynchronously parses an array of delimiter separated strings into an array of objects of type T.
91+
/// </summary>
92+
/// <typeparam name="T"></typeparam>
93+
/// <param name="lines"></param>
94+
/// <returns></returns>
95+
Task<T[]> ParseAsync<T>(string[] lines) where T : IFileLine, new();
96+
97+
/// <summary>
98+
/// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
99+
/// </summary>
100+
/// <typeparam name="T"></typeparam>
101+
/// <param name="stream"></param>
102+
/// <returns></returns>
103+
Task<T[]> ParseAsync<T>(Stream stream) where T : IFileLine, new();
104+
/// <summary>
105+
/// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
106+
/// </summary>
107+
/// <typeparam name="T"></typeparam>
108+
/// <param name="bytes"></param>
109+
/// <returns></returns>
110+
Task<T[]> ParseAsync<T>(byte[] bytes) where T : IFileLine, new();
49111
}
50112
```
51113
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.

src/Parsley/IParser.cs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,72 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
14
namespace parsley
25
{
36
public interface IParser
47
{
8+
/// <summary>
9+
/// Parses a file at the specified filepath into an array of objects of type T.
10+
/// </summary>
11+
/// <typeparam name="T"></typeparam>
12+
/// <param name="filepath"></param>
13+
/// <returns></returns>
514
T[] Parse<T>(string filepath) where T : IFileLine, new();
615

7-
T[] Parse<T>(string[] lines) where T : IFileLine, new();
16+
/// <summary>
17+
/// Parses an array of delimiter seperated strings into an array of objects of type T.
18+
/// </summary>
19+
/// <typeparam name="T"></typeparam>
20+
/// <param name="lines"></param>
21+
/// <returns></returns>
22+
T[] Parse<T>(string[] lines) where T : IFileLine, new();
23+
24+
/// <summary>
25+
/// Parses a stream of delimiter separated records into an array of objects of type T.
26+
/// </summary>
27+
/// <typeparam name="T"></typeparam>
28+
/// <param name="stream"></param>
29+
/// <returns></returns>
30+
T[] Parse<T>(Stream stream) where T : IFileLine, new();
31+
32+
/// <summary>
33+
/// Parses an array of bytes of delimiter separated records into an array of objects of type T.
34+
/// </summary>
35+
/// <typeparam name="T"></typeparam>
36+
/// <param name="bytes"></param>
37+
/// <returns></returns>
38+
T[] Parse<T>(byte[] bytes) where T : IFileLine, new();
39+
40+
/// <summary>
41+
/// Asynchronously parses a file at the specified filepath into an array of objects of type T.
42+
/// </summary>
43+
/// <typeparam name="T"></typeparam>
44+
/// <param name="filepath"></param>
45+
/// <returns></returns>
46+
Task<T[]> ParseAsync<T>(string filepath) where T : IFileLine, new();
47+
48+
/// <summary>
49+
/// Asynchronously parses an array of delimiter separated strings into an array of objects of type T.
50+
/// </summary>
51+
/// <typeparam name="T"></typeparam>
52+
/// <param name="lines"></param>
53+
/// <returns></returns>
54+
Task<T[]> ParseAsync<T>(string[] lines) where T : IFileLine, new();
55+
56+
/// <summary>
57+
/// Asynchronously parses a stream of delimiter separated strings into an array of objects of type T.
58+
/// </summary>
59+
/// <typeparam name="T"></typeparam>
60+
/// <param name="stream"></param>
61+
/// <returns></returns>
62+
Task<T[]> ParseAsync<T>(Stream stream) where T : IFileLine, new();
63+
64+
/// <summary>
65+
/// Asynchronously parses an array of bytes of delimiter separated records into an array of objects of type T.
66+
/// </summary>
67+
/// <typeparam name="T"></typeparam>
68+
/// <param name="bytes"></param>
69+
/// <returns></returns>
70+
Task<T[]> ParseAsync<T>(byte[] bytes) where T : IFileLine, new();
871
}
972
}

src/Parsley/Parser.cs

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Linq;
66
using System.Reflection;
7+
using System.Text;
78
using System.Threading.Tasks;
89

910
namespace parsley
@@ -77,7 +78,7 @@ private string[] ReadToLines(string path)
7778
}
7879

7980
return lines.ToArray<string>();
80-
}
81+
}
8182

8283
private T ParseLine<T>(string line) where T : IFileLine, new()
8384
{
@@ -163,5 +164,94 @@ private string[] GetDelimiterSeparatedValues(string line)
163164
.ToArray();
164165
return values;
165166
}
167+
168+
public T[] Parse<T>(Stream stream) where T : IFileLine, new()
169+
{
170+
if (stream == null || stream.Length == 0)
171+
return Array.Empty<T>();
172+
173+
var lines = new List<string>();
174+
using (var reader = new StreamReader(stream, Encoding.UTF8))
175+
{
176+
string line;
177+
while ((line = reader.ReadLine()) != null)
178+
{
179+
var trimmedLine = line.Trim();
180+
if (!string.IsNullOrWhiteSpace(trimmedLine))
181+
lines.Add(trimmedLine);
182+
line = null;
183+
}
184+
}
185+
186+
return lines.Any() ? Parse<T>(lines.ToArray()) : Array.Empty<T>();
187+
}
188+
189+
public T[] Parse<T>(byte[] bytes) where T : IFileLine, new()
190+
{
191+
if (bytes == null || bytes.Length == 0)
192+
return Array.Empty<T>();
193+
194+
return Parse<T>(new MemoryStream(bytes));
195+
}
196+
197+
public async Task<T[]> ParseAsync<T>(string filepath) where T : IFileLine, new()
198+
{
199+
if (string.IsNullOrEmpty(filepath) || !File.Exists(filepath))
200+
return Array.Empty<T>();
201+
202+
var lines = await Task.Run(() => ReadToLines(filepath));
203+
204+
return await ParseAsync<T>(lines);
205+
}
206+
207+
public async Task<T[]> ParseAsync<T>(string[] lines) where T : IFileLine, new()
208+
{
209+
if (lines == null || lines.Length == 0)
210+
return Array.Empty<T>();
211+
212+
var list = new T[lines.Length];
213+
var index = 0;
214+
var inputs = lines.Select(line => new { Line = line, Index = index++ });
215+
216+
foreach (var input in inputs)
217+
{
218+
if (string.IsNullOrWhiteSpace(input.Line))
219+
continue;
220+
221+
var parsedLine = await Task.Run(() => ParseLine<T>(input.Line));
222+
223+
if (parsedLine != null)
224+
{
225+
parsedLine.Index = input.Index;
226+
list[parsedLine.Index] = parsedLine;
227+
}
228+
}
229+
return list;
230+
}
231+
232+
public async Task<T[]> ParseAsync<T>(Stream stream) where T : IFileLine, new()
233+
{
234+
var lines = new List<string>();
235+
using (var reader = new StreamReader(stream, Encoding.UTF8))
236+
{
237+
string line;
238+
while ((line = await reader.ReadLineAsync()) != null)
239+
{
240+
var trimmedLine = line.Trim();
241+
if (!string.IsNullOrWhiteSpace(trimmedLine))
242+
lines.Add(trimmedLine);
243+
}
244+
}
245+
246+
return lines.Any() ? await ParseAsync<T>(lines.ToArray()) : Array.Empty<T>();
247+
}
248+
249+
public async Task<T[]> ParseAsync<T>(byte[] bytes) where T : IFileLine, new()
250+
{
251+
if (bytes == null || bytes.Length == 0)
252+
return Array.Empty<T>();
253+
254+
return await ParseAsync<T>(new MemoryStream(bytes));
255+
}
166256
}
167257
}

src/Parsley/Parsley.csproj

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net462; netstandard2.0;netstandard2.1; net9.0</TargetFrameworks>
4+
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net9.0</TargetFrameworks>
55
<ImplicitUsings>disable</ImplicitUsings>
66
<Title>Parsley.Net</Title>
77
<Authors>CodeShayk</Authors>
@@ -20,9 +20,10 @@
2020
<PackageProjectUrl>https://github.com/CodeShayk/Parsley.Net/wiki</PackageProjectUrl>
2121
<RepositoryUrl>https://github.com/CodeShayk/Parsley.Net</RepositoryUrl>
2222
<PackageReleaseNotes>
23-
v1.0.1 - Targets .Net9.0, .NetStandard2.1, .NetStandard2.0, and .NetFramework4.6.4. <br/>
24-
* Includes core functionality for parsing delimiter separated files.</PackageReleaseNotes>
25-
<Version>1.0.1</Version>
23+
v1.1.0 - Targets .Net9.0, .NetStandard2.1, .NetStandard2.0, and .NetFramework4.6.4. <br/>
24+
* Includes core functionality for parsing delimiter separated files.
25+
* Provided Sync and Async parsing methods</PackageReleaseNotes>
26+
<Version>1.1.0</Version>
2627
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
2728
<AssemblyName>Parsley.Net</AssemblyName>
2829
</PropertyGroup>

0 commit comments

Comments
 (0)