diff --git a/.gitignore b/.gitignore index fae9570..92063d8 100644 --- a/.gitignore +++ b/.gitignore @@ -269,10 +269,10 @@ Temporary Items .apdisk /.claude -# TONfile.Spec.Web - Static website specific +# DevPossible.Ton - Static website specific # The website should not generate any build artifacts -TONfile.Spec.Web/bin/ -TONfile.Spec.Web/obj/ +DevPossible.Ton.Spec.Web/bin/ +DevPossible.Ton.Spec.Web/obj/ # NuGet packages *.nupkg diff --git a/README.md b/README.md index a14e8ab..e1ceae7 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,10 @@ Install-Package DevPossible.Ton ## Quick Start -### Reading a TON File +### Example 1: Basic Parsing and Creating TON Files + +
+C# / .NET ```csharp using DevPossible.Ton; @@ -89,57 +92,271 @@ var document = parser.ParseFile("config.ton"); // Access properties string name = document.RootObject.GetProperty("name")?.ToString(); int port = document.RootObject.GetProperty("port")?.ToInt32() ?? 8080; -bool enabled = document.RootObject.GetProperty("enabled")?.ToBoolean() ?? false; -// Access nested objects -var database = document.RootObject.GetChild("database"); -string dbHost = database?.GetProperty("host")?.ToString(); +// Create a new document +var newDoc = new TonDocument(); +newDoc.RootObject.SetProperty("name", TonValue.From("My App")); +newDoc.RootObject.SetProperty("port", TonValue.From(8080)); + +// Add nested object +var database = new TonObject { ClassName = "database" }; +database.SetProperty("host", TonValue.From("localhost")); +newDoc.RootObject.AddChild(database); + +// Serialize and save +var serializer = new TonSerializer(); +string tonContent = serializer.SerializeDocument(newDoc, TonSerializeOptions.Pretty); +await serializer.SerializeToFileAsync(newDoc, "config.ton", TonSerializeOptions.Pretty); ``` +
+ +
+JavaScript / TypeScript + +```javascript +import { TonParser, TonDocument, TonObject, TonValue, TonSerializer, TonSerializeOptions } from 'devpossible-ton'; + +// Parse a TON file +const parser = new TonParser(); +const document = parser.parseFile('config.ton'); + +// Access properties +const name = document.rootObject.getProperty('name')?.toString(); +const port = document.rootObject.getProperty('port')?.toInt32() ?? 8080; + +// Create a new document +const newDoc = new TonDocument(); +newDoc.rootObject.setProperty('name', TonValue.from('My App')); +newDoc.rootObject.setProperty('port', TonValue.from(8080)); + +// Add nested object +const database = new TonObject('database'); +database.setProperty('host', TonValue.from('localhost')); +newDoc.rootObject.addChild(database); + +// Serialize and save +const serializer = new TonSerializer(); +const tonContent = serializer.serializeDocument(newDoc, TonSerializeOptions.Pretty); +await serializer.serializeToFile(newDoc, 'config.ton', TonSerializeOptions.Pretty); +``` +
+ +
+Python + +```python +from devpossible_ton import TonParser, TonDocument, TonObject, TonValue, TonSerializer, TonSerializeOptions + +# Parse a TON file +parser = TonParser() +document = parser.parse_file('config.ton') + +# Access properties +name = document.root_object.get_property('name').to_string() if document.root_object.get_property('name') else None +port = document.root_object.get_property('port').to_int32() if document.root_object.get_property('port') else 8080 + +# Create a new document +new_doc = TonDocument() +new_doc.root_object.set_property('name', TonValue.from_value('My App')) +new_doc.root_object.set_property('port', TonValue.from_value(8080)) -### Writing a TON File +# Add nested object +database = TonObject(class_name='database') +database.set_property('host', TonValue.from_value('localhost')) +new_doc.root_object.add_child(database) + +# Serialize and save +serializer = TonSerializer() +ton_content = serializer.serialize_document(new_doc, TonSerializeOptions.Pretty) +await serializer.serialize_to_file(new_doc, 'config.ton', TonSerializeOptions.Pretty) +``` +
+ +### Example 2: Schema Validation + +
+C# / .NET ```csharp using DevPossible.Ton; -// Create a new document -var document = new TonDocument(); -document.Header = new TonHeader { TonVersion = "1" }; +// Define schema +var schemas = new TonSchemaCollection(); +var userSchema = new TonSchemaDefinition("user"); + +// Add property validations +var nameSchema = new TonPropertySchema("/name", "string"); +nameSchema.AddValidation(new TonValidationRule(ValidationRuleType.Required)); +nameSchema.AddValidation(new TonValidationRule(ValidationRuleType.MaxLength, 100)); +userSchema.AddProperty("/name", nameSchema); -// Add properties -document.RootObject.SetProperty("name", TonValue.From("My Application")); -document.RootObject.SetProperty("version", TonValue.From(1.0)); -document.RootObject.SetProperty("enabled", TonValue.From(true)); +var emailSchema = new TonPropertySchema("/email", "string"); +emailSchema.AddValidation(new TonValidationRule(ValidationRuleType.Format, "email")); +userSchema.AddProperty("/email", emailSchema); -// Add a nested object -var database = new TonObject { ClassName = "database" }; -database.SetProperty("host", TonValue.From("localhost")); -database.SetProperty("port", TonValue.From(5432)); -document.RootObject.AddChild(database); +schemas.AddSchema(userSchema); -// Serialize to string -var serializer = new TonSerializer(); -string tonContent = serializer.SerializeDocument(document, TonSerializeOptions.Pretty); +// Validate document +var validator = new TonValidator(); +var document = parser.Parse("{ (user) name = 'John', email = 'john@example.com' }"); +document.Schemas = schemas; -// Save to file -await serializer.SerializeToFileAsync(document, "config.ton", TonSerializeOptions.Pretty); +var results = validator.Validate(document); +if (!results.IsValid) +{ + foreach (var error in results.Errors) + Console.WriteLine($"Error at {error.Path}: {error.Message}"); +} +``` +
+ +
+JavaScript / TypeScript + +```javascript +import { TonParser, TonSchemaCollection, TonSchemaDefinition, TonPropertySchema, TonValidationRule, TonValidator, ValidationRuleType } from 'devpossible-ton'; + +// Define schema +const schemas = new TonSchemaCollection(); +const userSchema = new TonSchemaDefinition('user'); + +// Add property validations +const nameSchema = new TonPropertySchema('/name', 'string'); +nameSchema.addValidation(new TonValidationRule(ValidationRuleType.Required)); +nameSchema.addValidation(new TonValidationRule(ValidationRuleType.MaxLength, 100)); +userSchema.addProperty('/name', nameSchema); + +const emailSchema = new TonPropertySchema('/email', 'string'); +emailSchema.addValidation(new TonValidationRule(ValidationRuleType.Format, 'email')); +userSchema.addProperty('/email', emailSchema); + +schemas.addSchema(userSchema); + +// Validate document +const validator = new TonValidator(); +const parser = new TonParser(); +const document = parser.parse("{ (user) name = 'John', email = 'john@example.com' }"); +document.schemas = schemas; + +const results = validator.validate(document); +if (!results.isValid) { + results.errors.forEach(error => + console.log(`Error at ${error.path}: ${error.message}`) + ); +} ``` +
+ +
+Python + +```python +from devpossible_ton import (TonParser, TonSchemaCollection, TonSchemaDefinition, + TonPropertySchema, TonValidationRule, TonValidator, + ValidationRuleType) + +# Define schema +schemas = TonSchemaCollection() +user_schema = TonSchemaDefinition('user') + +# Add property validations +name_schema = TonPropertySchema('/name', 'string') +name_schema.add_validation(TonValidationRule(ValidationRuleType.Required)) +name_schema.add_validation(TonValidationRule(ValidationRuleType.MaxLength, 100)) +user_schema.add_property('/name', name_schema) + +email_schema = TonPropertySchema('/email', 'string') +email_schema.add_validation(TonValidationRule(ValidationRuleType.Format, 'email')) +user_schema.add_property('/email', email_schema) + +schemas.add_schema(user_schema) + +# Validate document +validator = TonValidator() +parser = TonParser() +document = parser.parse("{ (user) name = 'John', email = 'john@example.com' }") +document.schemas = schemas + +results = validator.validate(document) +if not results.is_valid: + for error in results.errors: + print(f"Error at {error.path}: {error.message}") +``` +
+ +### Example 3: Working with Arrays and Formatting -### Formatting an Existing TON File +
+C# / .NET ```csharp using DevPossible.Ton; -// Format an existing TON file with pretty formatting -string formatted = TonFormatter.FormatFile("messy-config.ton", TonFormatStyle.Pretty); -Console.WriteLine(formatted); +// Create document with arrays +var document = new TonDocument(); +var tags = new List { "production", "web", "api" }; +var scores = new List { 98.5, 87.2, 95.0 }; -// Or format it in place -TonFormatter.FormatFileInPlace("messy-config.ton", TonFormatStyle.Pretty); +document.RootObject.SetProperty("tags", TonValue.From(tags)); +document.RootObject.SetProperty("scores", TonValue.From(scores)); -// Format a TON string -string unformattedTon = "{name='MyApp',version=1.0,enabled=true}"; -string prettyTon = TonFormatter.FormatString(unformattedTon, TonFormatStyle.Pretty); +// Format with different styles +var serializer = new TonSerializer(); +string compact = serializer.SerializeDocument(document, TonSerializeOptions.Compact); +string pretty = serializer.SerializeDocument(document, TonSerializeOptions.Pretty); + +// Or use the formatter directly +string formatted = TonFormatter.FormatString(compact, TonFormatStyle.Pretty); +``` + + +
+JavaScript / TypeScript + +```javascript +import { TonDocument, TonValue, TonSerializer, TonSerializeOptions, TonFormatter, TonFormatStyle } from 'devpossible-ton'; + +// Create document with arrays +const document = new TonDocument(); +const tags = ['production', 'web', 'api']; +const scores = [98.5, 87.2, 95.0]; + +document.rootObject.setProperty('tags', TonValue.from(tags)); +document.rootObject.setProperty('scores', TonValue.from(scores)); + +// Format with different styles +const serializer = new TonSerializer(); +const compact = serializer.serializeDocument(document, TonSerializeOptions.Compact); +const pretty = serializer.serializeDocument(document, TonSerializeOptions.Pretty); + +// Or use the formatter directly +const formatted = TonFormatter.formatString(compact, TonFormatStyle.Pretty); +``` +
+ +
+Python + +```python +from devpossible_ton import TonDocument, TonValue, TonSerializer, TonSerializeOptions, TonFormatter, TonFormatStyle + +# Create document with arrays +document = TonDocument() +tags = ['production', 'web', 'api'] +scores = [98.5, 87.2, 95.0] + +document.root_object.set_property('tags', TonValue.from_value(tags)) +document.root_object.set_property('scores', TonValue.from_value(scores)) + +# Format with different styles +serializer = TonSerializer() +compact = serializer.serialize_document(document, TonSerializeOptions.Compact) +pretty = serializer.serialize_document(document, TonSerializeOptions.Pretty) + +# Or use the formatter directly +formatted = TonFormatter.format_string(compact, TonFormatStyle.Pretty) ``` +
## TON Format Overview @@ -273,148 +490,19 @@ TON supports multi-line string literals using triple quotes (`"""` or `'''`). Mu ## Usage Guide -### Parsing TON Files +For detailed usage information and additional examples, please refer to: +- **[Quick Start Examples](#quick-start)** above for basic usage in all three languages +- **Sample Projects** in `src/CSharp/DevPossible.Ton.Samples/`, `src/JavaScript/devpossible-ton-samples/`, and `src/Python/devpossible_ton_samples/` +- **Full API Documentation** at the [project wiki](https://github.com/DevPossible/DevPossible.Ton/wiki) +- **TON Specification** at [tonspec.com](https://tonspec.com) -#### From File +### Key Capabilities -```csharp -var parser = new TonParser(); +All three library implementations (C#, JavaScript, and Python) support: -// Parse with default options -var document = parser.ParseFile("config.ton"); - -// Parse with custom options -var options = new TonParseOptions -{ - ValidateSchema = true, - StrictMode = true, - AllowComments = true -}; -var document = parser.ParseFile("config.ton", options); -``` - -#### From String - -```csharp -string tonContent = @"{ - name = 'Test', - value = 42 -}"; - -var document = parser.Parse(tonContent); -``` - -#### From Stream - -```csharp -using var stream = File.OpenRead("config.ton"); -var document = parser.ParseStream(stream); -``` - -#### Async Operations - -```csharp -// Async file parsing -var document = await parser.ParseFileAsync("config.ton"); - -// Async stream parsing -using var stream = File.OpenRead("config.ton"); -var document = await parser.ParseStreamAsync(stream); -``` - -### Creating TON Documents - -#### Building Documents Programmatically - -```csharp -// Create document with header -var document = new TonDocument(); -document.Header = new TonHeader -{ - TonVersion = "1", - SchemaFile = "schema.ton" -}; -document.Header["customAttribute"] = "value"; - -// Set root object properties -var root = document.RootObject; -root.ClassName = "configuration"; -root.InstanceCountHint = 1; - -// Add simple properties -root.SetProperty("appName", TonValue.From("MyApp")); -root.SetProperty("version", TonValue.From(2.1)); -root.SetProperty("debugMode", TonValue.From(false)); - -// Add arrays -var features = new List { "feature1", "feature2", "feature3" }; -root.SetProperty("features", TonValue.From(features)); - -// Add enums -root.SetProperty("logLevel", TonValue.From(new TonEnum("debug"))); -root.SetProperty("permissions", TonValue.From(new TonEnumSet("read", "write"))); - -// Add nested objects -var database = new TonObject { ClassName = "database" }; -database.SetProperty("host", TonValue.From("localhost")); -database.SetProperty("port", TonValue.From(5432)); -database.SetProperty("connectionString", TonValue.From("Server=localhost;Database=mydb")); -root.AddChild(database); - -// Add multiple child objects of the same type -for (int i = 0; i < 3; i++) -{ - var server = new TonObject { ClassName = "server" }; - server.SetProperty("id", TonValue.From(i + 1)); - server.SetProperty("address", TonValue.From($"192.168.1.{100 + i}")); - root.AddChild(server); -} -``` - -#### Converting from C# Objects - -```csharp -// Define your classes -public class AppConfig -{ - public string Name { get; set; } - public string Version { get; set; } - public int MaxConnections { get; set; } - public bool EnableLogging { get; set; } - public string[] AllowedHosts { get; set; } - public DatabaseConfig Database { get; set; } -} - -public class DatabaseConfig -{ - public string Host { get; set; } - public int Port { get; set; } - public string Username { get; set; } -} - -// Create and populate object -var config = new AppConfig -{ - Name = "MyApplication", - Version = "2.0.0", - MaxConnections = 100, - EnableLogging = true, - AllowedHosts = new[] { "localhost", "*.example.com" }, - Database = new DatabaseConfig - { - Host = "db.example.com", - Port = 5432, - Username = "admin" - } -}; - -// Convert to TON document -var document = TonDocument.FromObject(config); - -// Serialize -var serializer = new TonSerializer(); -string tonContent = serializer.SerializeDocument(document, TonSerializeOptions.Pretty); -``` +- **Parsing**: From files, strings, and streams (with async support) +- **Document Creation**: Programmatically build TON documents with headers, properties, and nested objects +- **Object Conversion**: Convert between TON and native objects (C# classes, JavaScript objects, Python dicts) ### Serialization @@ -896,81 +984,26 @@ var document = new TonDocument(tonObject); ## Advanced Features ### Custom Value Types - -```csharp -// Create custom enum -var customEnum = new TonEnum("customValue"); -root.SetProperty("customType", TonValue.From(customEnum)); - -// Create enum set -var permissions = new TonEnumSet("read", "write", "execute"); -root.SetProperty("permissions", TonValue.From(permissions)); - -// Add values with type hints -var value = TonValue.From("example"); -root.SetProperty("annotated", value); -``` +- **Enums**: Single value enumerations (`|value|`) +- **EnumSets**: Multiple value enumerations (`|value1|value2|value3|`) +- **Type Hints**: Optional type indicators (`$` for string, `%` for number, `&` for GUID, `^` for array) ### Property Paths - -```csharp -// Set nested values using paths -document.SetValue("/database/host", "localhost"); -document.SetValue("/database/credentials/username", "admin"); -document.SetValue("/servers/0/address", "192.168.1.1"); - -// Get nested values using paths -var dbHost = document.GetValue("/database/host"); -var username = document.GetValue("/database/credentials/username"); -var firstServer = document.GetValue("/servers/0/address"); -``` +- Access nested properties using path syntax: `/parent/child/property` +- Support for numeric property names: `/user/123/data` +- Array index access: `/items/0/name` ### Error Handling - -```csharp -try -{ - var document = parser.Parse(tonContent); -} -catch (TonParseException ex) -{ - Console.WriteLine($"Parse error at line {ex.Line}, column {ex.Column}: {ex.Message}"); - Console.WriteLine($"Near: {ex.NearText}"); -} -catch (TonValidationException ex) -{ - Console.WriteLine($"Validation error: {ex.Message}"); - foreach (var error in ex.ValidationErrors) - { - Console.WriteLine($" - {error.Path}: {error.Message}"); - } -} -``` +All implementations provide detailed error information including: +- **Parse Errors**: Line and column numbers with context +- **Validation Errors**: Property paths and validation rule details +- **Type Errors**: Expected vs. actual type information ### Performance Optimization - -```csharp -// Use streaming for large files -using var stream = new FileStream("large.ton", FileMode.Open, FileAccess.Read, - FileShare.Read, 4096, FileOptions.SequentialScan); -var document = await parser.ParseStreamAsync(stream); - -// Use compact serialization for network transmission -var compactOptions = new TonSerializeOptions -{ - Indentation = null, - IncludeHeader = false, - IncludeSchema = false, - OmitNullValues = true, - OmitUndefinedValues = true, - OmitEmptyCollections = true -}; -string compact = serializer.Serialize(document.RootObject, compactOptions); - -// Reuse parser and serializer instances -private static readonly TonParser Parser = new TonParser(); -private static readonly TonSerializer Serializer = new TonSerializer(); -``` +- **Streaming Support**: Parse large files with minimal memory usage +- **Async Operations**: Non-blocking I/O for all file operations +- **Compact Serialization**: Minimal output size for network transmission +- **Instance Reuse**: Reuse parser and serializer instances for better performance ## API Reference diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/AdvancedSerialization.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/AdvancedSerialization.cs index cd195f9..25d58eb 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/AdvancedSerialization.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/AdvancedSerialization.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class AdvancedSerialization { diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/ArrayOperations.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/ArrayOperations.cs index 64a8d30..ad9524f 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/ArrayOperations.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/ArrayOperations.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class ArrayOperations { diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/BasicParsing.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/BasicParsing.cs index 9260304..4afa5bf 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/BasicParsing.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/BasicParsing.cs @@ -1,8 +1,8 @@ using System; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class BasicParsing { diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/ComplexDocument.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/ComplexDocument.cs index c5e196e..41bf4bd 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/ComplexDocument.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/ComplexDocument.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class ComplexDocument { diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/ErrorHandling.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/ErrorHandling.cs index fc9bce4..5d8c034 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/ErrorHandling.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/ErrorHandling.cs @@ -1,9 +1,9 @@ using System; using System.IO; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class ErrorHandling { diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/FileOperations.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/FileOperations.cs index c50be4c..4a1fc09 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/FileOperations.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/FileOperations.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class FileOperations { @@ -13,7 +13,7 @@ public static async Task RunAsync() Console.WriteLine("=== File Operations Example ===\n"); // Create a temporary directory for our samples - var tempDir = Path.Combine(Path.GetTempPath(), "TONfile_Samples"); + var tempDir = Path.Combine(Path.GetTempPath(), "DevPossible.Ton_Samples"); Directory.CreateDirectory(tempDir); Console.WriteLine($"Working directory: {tempDir}\n"); @@ -29,7 +29,7 @@ public static async Task RunAsync() { Properties = new Dictionary { - ["application"] = TonValue.From("TONfile Demo"), + ["application"] = TonValue.From("DevPossible.Ton Demo"), ["version"] = TonValue.From(1.0), ["database"] = TonValue.From(new TonObject { @@ -131,4 +131,4 @@ public static async Task RunAsync() } } } -} \ No newline at end of file +} diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/ObjectConversion.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/ObjectConversion.cs index b6ccab6..ab1878b 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/ObjectConversion.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/ObjectConversion.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class ObjectConversion { diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/PerformanceTest.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/PerformanceTest.cs index 150bf89..813719c 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/PerformanceTest.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/PerformanceTest.cs @@ -5,9 +5,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class PerformanceTest { @@ -290,7 +290,7 @@ await Task.Run(() => private static async Task TestFileIOPerformance() { - var tempDir = Path.Combine(Path.GetTempPath(), "TONfile_PerfTest"); + var tempDir = Path.Combine(Path.GetTempPath(), "DevPossible.Ton_PerfTest"); Directory.CreateDirectory(tempDir); try @@ -450,4 +450,4 @@ private static TonDocument GenerateLargeDocument(int propertyCount) }; } } -} \ No newline at end of file +} diff --git a/src/CSharp/DevPossible.Ton.Samples/Examples/SchemaValidation.cs b/src/CSharp/DevPossible.Ton.Samples/Examples/SchemaValidation.cs index 2bdaa8e..243219f 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Examples/SchemaValidation.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Examples/SchemaValidation.cs @@ -1,16 +1,16 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Samples.Examples +namespace DevPossible.Ton.Samples.Examples { public static class SchemaValidation { public static async Task RunAsync() { Console.WriteLine("=== Schema Validation Example ===\n"); - Console.WriteLine("Note: Schema validation is not yet implemented in the TONfile library."); + Console.WriteLine("Note: Schema validation is not yet implemented in the DevPossible.Ton library."); Console.WriteLine("This example demonstrates the intended API design for future implementation.\n"); // Example 1: Basic schema validation (simulated) @@ -143,4 +143,4 @@ public static async Task RunAsync() await Task.CompletedTask; } } -} \ No newline at end of file +} diff --git a/src/CSharp/DevPossible.Ton.Samples/Program.cs b/src/CSharp/DevPossible.Ton.Samples/Program.cs index aa2f0ae..c032227 100644 --- a/src/CSharp/DevPossible.Ton.Samples/Program.cs +++ b/src/CSharp/DevPossible.Ton.Samples/Program.cs @@ -1,16 +1,16 @@ using System; using System.IO; using System.Threading.Tasks; -using TONfile.Samples.Examples; +using DevPossible.Ton.Samples.Examples; -namespace TONfile.Samples +namespace DevPossible.Ton.Samples { class Program { static async Task Main(string[] args) { Console.WriteLine("============================================"); - Console.WriteLine(" TONfile Library Sample Programs "); + Console.WriteLine(" DevPossible.Ton Library Sample Programs "); Console.WriteLine("============================================\n"); bool exit = false; @@ -87,4 +87,4 @@ static async Task Main(string[] args) } } } -} \ No newline at end of file +} diff --git a/src/CSharp/DevPossible.Ton.Samples/SampleData/config.ton b/src/CSharp/DevPossible.Ton.Samples/SampleData/config.ton index 690cd29..c2ea83d 100644 --- a/src/CSharp/DevPossible.Ton.Samples/SampleData/config.ton +++ b/src/CSharp/DevPossible.Ton.Samples/SampleData/config.ton @@ -1,6 +1,6 @@ // Application configuration file {(AppConfig) - application = 'TONfile Demo', + application = 'DevPossible.Ton Demo', version = 1.5, environment = |production|, @@ -41,4 +41,4 @@ ttl = 3600, maxSize = 1000 } -} \ No newline at end of file +} diff --git a/src/CSharp/DevPossible.Ton.Tests/ArrayTests.cs b/src/CSharp/DevPossible.Ton.Tests/ArrayTests.cs index 9185ac0..2ed5db9 100644 --- a/src/CSharp/DevPossible.Ton.Tests/ArrayTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/ArrayTests.cs @@ -3,7 +3,7 @@ using FluentAssertions; using Xunit; -namespace TONfile.Tests +namespace DevPossible.Ton.Tests { public class ArrayTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/EdgeCases/EdgeCaseTests.cs b/src/CSharp/DevPossible.Ton.Tests/EdgeCases/EdgeCaseTests.cs index 133ccf1..e63d633 100644 --- a/src/CSharp/DevPossible.Ton.Tests/EdgeCases/EdgeCaseTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/EdgeCases/EdgeCaseTests.cs @@ -1,10 +1,10 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System; using System.Linq; -namespace TONfile.Tests.EdgeCases +namespace DevPossible.Ton.Tests.EdgeCases { public class EdgeCaseTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Formatter/TonFormatterTests.cs b/src/CSharp/DevPossible.Ton.Tests/Formatter/TonFormatterTests.cs index 3022802..bf753dc 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Formatter/TonFormatterTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Formatter/TonFormatterTests.cs @@ -3,9 +3,9 @@ using System.Threading.Tasks; using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Tests.Formatter +namespace DevPossible.Ton.Tests.Formatter { public class TonFormatterTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Integration/IntegrationTests.cs b/src/CSharp/DevPossible.Ton.Tests/Integration/IntegrationTests.cs index f712709..2a809b4 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Integration/IntegrationTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Integration/IntegrationTests.cs @@ -1,12 +1,12 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System; using System.IO; using System.Text; using System.Threading.Tasks; -namespace TONfile.Tests.Integration +namespace DevPossible.Ton.Tests.Integration { public class IntegrationTests : IDisposable { diff --git a/src/CSharp/DevPossible.Ton.Tests/Integration/MultiLineStringIntegrationTests.cs b/src/CSharp/DevPossible.Ton.Tests/Integration/MultiLineStringIntegrationTests.cs index 307d842..3723d4b 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Integration/MultiLineStringIntegrationTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Integration/MultiLineStringIntegrationTests.cs @@ -1,8 +1,8 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Tests.Integration +namespace DevPossible.Ton.Tests.Integration { public class MultiLineStringIntegrationTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Lexer/MultiLineStringTests.cs b/src/CSharp/DevPossible.Ton.Tests/Lexer/MultiLineStringTests.cs index 5a8e00e..a065f16 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Lexer/MultiLineStringTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Lexer/MultiLineStringTests.cs @@ -1,8 +1,8 @@ using Xunit; using FluentAssertions; -using TONfile.Lexer; +using DevPossible.Ton.Lexer; -namespace TONfile.Tests.Lexer +namespace DevPossible.Ton.Tests.Lexer { public class MultiLineStringTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Lexer/TonLexerTests.cs b/src/CSharp/DevPossible.Ton.Tests/Lexer/TonLexerTests.cs index 98369d5..a572a72 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Lexer/TonLexerTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Lexer/TonLexerTests.cs @@ -1,9 +1,9 @@ using Xunit; using FluentAssertions; -using TONfile.Lexer; +using DevPossible.Ton.Lexer; using System.Linq; -namespace TONfile.Tests.Lexer +namespace DevPossible.Ton.Tests.Lexer { public class TonLexerTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/NumericPropertyTests.cs b/src/CSharp/DevPossible.Ton.Tests/NumericPropertyTests.cs index 8ac0bbb..3367f38 100644 --- a/src/CSharp/DevPossible.Ton.Tests/NumericPropertyTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/NumericPropertyTests.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; -namespace TONfile.Tests +namespace DevPossible.Ton.Tests { public class NumericPropertyTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Parser/TonParserTests.cs b/src/CSharp/DevPossible.Ton.Tests/Parser/TonParserTests.cs index 38a34ee..ca3a5ad 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Parser/TonParserTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Parser/TonParserTests.cs @@ -1,10 +1,10 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System; using System.Linq; -namespace TONfile.Tests.Parser +namespace DevPossible.Ton.Tests.Parser { public class TonParserTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Performance/PerformanceTests.cs b/src/CSharp/DevPossible.Ton.Tests/Performance/PerformanceTests.cs index 7ef5151..273ff33 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Performance/PerformanceTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Performance/PerformanceTests.cs @@ -1,11 +1,11 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System; using System.Diagnostics; using System.Text; -namespace TONfile.Tests.Performance +namespace DevPossible.Ton.Tests.Performance { public class PerformanceTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Serializer/TonSerializerTests.cs b/src/CSharp/DevPossible.Ton.Tests/Serializer/TonSerializerTests.cs index 607694d..72e9c2c 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Serializer/TonSerializerTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Serializer/TonSerializerTests.cs @@ -1,10 +1,10 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System; using System.Collections.Generic; -namespace TONfile.Tests.Serializer +namespace DevPossible.Ton.Tests.Serializer { public class TonSerializerTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Validation/PathBasedSchemaTests.cs b/src/CSharp/DevPossible.Ton.Tests/Validation/PathBasedSchemaTests.cs index 1c15ceb..440e3cc 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Validation/PathBasedSchemaTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Validation/PathBasedSchemaTests.cs @@ -1,9 +1,9 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System.Linq; -namespace TONfile.Tests.Validation +namespace DevPossible.Ton.Tests.Validation { public class PathBasedSchemaTests { diff --git a/src/CSharp/DevPossible.Ton.Tests/Validation/TonValidatorTests.cs b/src/CSharp/DevPossible.Ton.Tests/Validation/TonValidatorTests.cs index 8a276fc..3760889 100644 --- a/src/CSharp/DevPossible.Ton.Tests/Validation/TonValidatorTests.cs +++ b/src/CSharp/DevPossible.Ton.Tests/Validation/TonValidatorTests.cs @@ -1,9 +1,9 @@ using Xunit; using FluentAssertions; -using TONfile; +using DevPossible.Ton; using System.Linq; -namespace TONfile.Tests.Validation +namespace DevPossible.Ton.Tests.Validation { public class TonValidatorTests { diff --git a/src/CSharp/DevPossible.Ton/DevPossible.Ton.csproj b/src/CSharp/DevPossible.Ton/DevPossible.Ton.csproj index 8571e53..d4befdf 100644 --- a/src/CSharp/DevPossible.Ton/DevPossible.Ton.csproj +++ b/src/CSharp/DevPossible.Ton/DevPossible.Ton.csproj @@ -5,7 +5,7 @@ enable true DevPossible.Ton - 0.1.5 + 0.1.6 DevPossible, LLC DevPossible, LLC DevPossible.Ton @@ -27,7 +27,7 @@ Copyright © 2024 DevPossible, LLC 1.0.0.0 1.0.0.0 - 0.1.5 + 0.1.6 DevPossible, LLC @@ -35,7 +35,7 @@ - + diff --git a/src/CSharp/DevPossible.Ton/README.md b/src/CSharp/DevPossible.Ton/README.md new file mode 100644 index 0000000..8e53dbd --- /dev/null +++ b/src/CSharp/DevPossible.Ton/README.md @@ -0,0 +1,237 @@ +# DevPossible.Ton - C# / .NET Library + +**Developed by DevPossible, LLC** +**Contact: support@devpossible.com** + +.NET Standard 2.1 implementation of the TON (Text Object Notation) parser, serializer, formatter, and validator. + +## Installation + +### Via NuGet Package Manager + +```bash +dotnet add package DevPossible.Ton +``` + +### Via Package Manager Console + +```powershell +Install-Package DevPossible.Ton +``` + +### Via PackageReference + +```xml + +``` + +## Quick Start + +```csharp +using DevPossible.Ton; + +// Parse a TON file +var parser = new TonParser(); +var document = parser.ParseFile("config.ton"); + +// Access properties +string name = document.RootObject.GetProperty("name")?.ToString(); +int port = document.RootObject.GetProperty("port")?.ToInt32() ?? 8080; + +// Create a new document +var newDoc = new TonDocument(); +newDoc.RootObject.SetProperty("name", TonValue.From("My App")); +newDoc.RootObject.SetProperty("port", TonValue.From(8080)); + +// Add nested object +var database = new TonObject { ClassName = "database" }; +database.SetProperty("host", TonValue.From("localhost")); +newDoc.RootObject.AddChild(database); + +// Serialize and save +var serializer = new TonSerializer(); +string tonContent = serializer.SerializeDocument(newDoc, TonSerializeOptions.Pretty); +await serializer.SerializeToFileAsync(newDoc, "config.ton", TonSerializeOptions.Pretty); +``` + +## Features + +- ✅ Full TON specification parser with async support +- ✅ Comprehensive schema validation with 30+ validation rule types +- ✅ Code formatter with compact and pretty styles +- ✅ Type annotations and hints +- ✅ Enum and EnumSet support +- ✅ Array support with mixed types +- ✅ Pretty and compact serialization +- ✅ Async file operations +- ✅ Schema collections and definitions +- ✅ Path-based schema validation +- ✅ Object conversion (C# ↔ TON) + +## Advanced Usage + +### Schema Validation + +```csharp +using DevPossible.Ton; + +// Define schema +var schemas = new TonSchemaCollection(); +var userSchema = new TonSchemaDefinition("user"); + +// Add property validations +var nameSchema = new TonPropertySchema("/name", "string"); +nameSchema.AddValidation(new TonValidationRule(ValidationRuleType.Required)); +nameSchema.AddValidation(new TonValidationRule(ValidationRuleType.MaxLength, 100)); +userSchema.AddProperty("/name", nameSchema); + +var emailSchema = new TonPropertySchema("/email", "string"); +emailSchema.AddValidation(new TonValidationRule(ValidationRuleType.Format, "email")); +userSchema.AddProperty("/email", emailSchema); + +schemas.AddSchema(userSchema); + +// Validate document +var validator = new TonValidator(); +var document = parser.Parse("{ (user) name = 'John', email = 'john@example.com' }"); +document.Schemas = schemas; + +var results = validator.Validate(document); +if (!results.IsValid) +{ + foreach (var error in results.Errors) + Console.WriteLine($"Error at {error.Path}: {error.Message}"); +} +``` + +### Formatting + +```csharp +using DevPossible.Ton; + +// Format a TON string with pretty formatting (default) +string unformattedTon = "{name='MyApp',version=1.0,enabled=true}"; +string prettyFormatted = TonFormatter.FormatString(unformattedTon); + +// Format with compact formatting +string compactFormatted = TonFormatter.FormatString(unformattedTon, TonFormatStyle.Compact); + +// Format files +TonFormatter.FormatFileInPlace("config.ton", TonFormatStyle.Pretty); + +// Async formatting +string formatted = await TonFormatter.FormatStringAsync(unformattedTon, TonFormatStyle.Pretty); +``` + +### Serialization Options + +```csharp +// Compact format - minimal size +var compact = TonSerializeOptions.Compact; + +// Pretty format - human readable with all features +var pretty = TonSerializeOptions.Pretty; + +// Custom options +var custom = new TonSerializeOptions +{ + // Formatting + Indentation = " ", // Two spaces + Pretty = true, // Enable formatting + SortProperties = true, // Alphabetical property order + + // Content control + IncludeHeader = true, // Include #@ header + IncludeSchema = true, // Include #! schema + IncludeTypeHints = true, // Add type hints ($, %, etc.) + + // Value handling + OmitNullValues = false, // Include null values + OmitUndefinedValues = true, // Skip undefined values + OmitEmptyCollections = false, // Include empty arrays + + // Formatting preferences + UseAtPrefix = true, // Use @ for properties + QuoteChar = '\'', // Use single quotes + UseMultiLineStrings = true, // Enable multi-line string format + MultiLineStringThreshold = 2, // Min lines to use multi-line format + LowercaseHex = true, // 0xff instead of 0xFF + LowercaseGuids = true, // Lowercase GUID format + PreferEnumNames = true // Use names over indices +}; + +var serializer = new TonSerializer(); +string output = serializer.SerializeDocument(document, custom); +``` + +### Object Conversion + +```csharp +// Convert C# object to TON +public class Configuration +{ + public string Name { get; set; } + public int Port { get; set; } + public bool Enabled { get; set; } + public string[] Tags { get; set; } +} + +var config = new Configuration +{ + Name = "MyApp", + Port = 8080, + Enabled = true, + Tags = new[] { "production", "web" } +}; + +var tonObject = TonObject.FromObject(config); +var document = new TonDocument(tonObject); + +// Convert TON to C# object +var parsedConfig = document.RootObject.ToObject(); +``` + +## API Reference + +### Core Classes + +- **`TonDocument`** - Represents a complete TON document with header, root object, and schemas +- **`TonObject`** - Represents an object with properties and child objects +- **`TonValue`** - Represents a typed value with conversion methods +- **`TonParser`** - Parses TON content from various sources +- **`TonSerializer`** - Serializes TON objects to string format +- **`TonFormatter`** - Formats existing TON content with different styles +- **`TonValidator`** - Validates TON documents against schemas + +### Key Interfaces + +- **`ITonValue`** - Interface for TON values +- **`ITonSerializable`** - Interface for serializable TON elements + +### Enumerations + +- **`TonValueType`** - Types of TON values (String, Integer, Float, Boolean, etc.) +- **`TonTokenType`** - Token types used by the lexer +- **`TonValidationRuleType`** - Types of validation rules +- **`TonFormatStyle`** - Formatting styles (Compact, Pretty) + +## Requirements + +- .NET Standard 2.1 or later +- Compatible with .NET Core 3.0+, .NET 5+, .NET 6+, .NET 7+, .NET 8+, .NET 9+ + +## License + +MIT License - Copyright © 2024 DevPossible, LLC + +## Support + +**DevPossible, LLC** +Website: [devpossible.com](https://www.devpossible.com) +Email: support@devpossible.com +TON Specification: [tonspec.com](https://tonspec.com) + +--- + +**© 2024 DevPossible, LLC. All rights reserved.** + diff --git a/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatStyle.cs b/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatStyle.cs index cf7d65b..217ff65 100644 --- a/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatStyle.cs +++ b/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatStyle.cs @@ -1,4 +1,4 @@ -namespace TONfile +namespace DevPossible.Ton { /// /// Defines the formatting styles available for TON file formatting diff --git a/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatter.cs b/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatter.cs index 3a5c43d..daa7633 100644 --- a/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatter.cs +++ b/src/CSharp/DevPossible.Ton/src/Formatter/TonFormatter.cs @@ -2,7 +2,7 @@ using System.IO; using System.Threading.Tasks; -namespace TONfile +namespace DevPossible.Ton { /// /// Provides utility methods for formatting TON file content diff --git a/src/CSharp/DevPossible.Ton/src/Interfaces/ITonParser.cs b/src/CSharp/DevPossible.Ton/src/Interfaces/ITonParser.cs index a6898c5..7640834 100644 --- a/src/CSharp/DevPossible.Ton/src/Interfaces/ITonParser.cs +++ b/src/CSharp/DevPossible.Ton/src/Interfaces/ITonParser.cs @@ -1,7 +1,7 @@ using System.IO; using System.Threading.Tasks; -namespace TONfile +namespace DevPossible.Ton { /// /// Interface for parsing TON (Text Object Notation) files and strings diff --git a/src/CSharp/DevPossible.Ton/src/Interfaces/ITonSerializer.cs b/src/CSharp/DevPossible.Ton/src/Interfaces/ITonSerializer.cs index bc3e588..a3fbaca 100644 --- a/src/CSharp/DevPossible.Ton/src/Interfaces/ITonSerializer.cs +++ b/src/CSharp/DevPossible.Ton/src/Interfaces/ITonSerializer.cs @@ -1,7 +1,7 @@ using System.IO; using System.Threading.Tasks; -namespace TONfile +namespace DevPossible.Ton { /// /// Interface for serializing objects to TON format diff --git a/src/CSharp/DevPossible.Ton/src/Lexer/TonLexer.cs b/src/CSharp/DevPossible.Ton/src/Lexer/TonLexer.cs index ee4904c..b8e90f7 100644 --- a/src/CSharp/DevPossible.Ton/src/Lexer/TonLexer.cs +++ b/src/CSharp/DevPossible.Ton/src/Lexer/TonLexer.cs @@ -3,7 +3,7 @@ using System.Text; using System.Text.RegularExpressions; -namespace TONfile.Lexer +namespace DevPossible.Ton.Lexer { /// /// Lexer for tokenizing TON syntax diff --git a/src/CSharp/DevPossible.Ton/src/Lexer/TonToken.cs b/src/CSharp/DevPossible.Ton/src/Lexer/TonToken.cs index 7fad7f2..40d5829 100644 --- a/src/CSharp/DevPossible.Ton/src/Lexer/TonToken.cs +++ b/src/CSharp/DevPossible.Ton/src/Lexer/TonToken.cs @@ -1,4 +1,4 @@ -namespace TONfile.Lexer +namespace DevPossible.Ton.Lexer { /// /// Represents a token in the TON syntax diff --git a/src/CSharp/DevPossible.Ton/src/Models/TonDocument.cs b/src/CSharp/DevPossible.Ton/src/Models/TonDocument.cs index 30799c6..185f0c1 100644 --- a/src/CSharp/DevPossible.Ton/src/Models/TonDocument.cs +++ b/src/CSharp/DevPossible.Ton/src/Models/TonDocument.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; -namespace TONfile +namespace DevPossible.Ton { /// /// Represents a TON document containing the parsed content and metadata diff --git a/src/CSharp/DevPossible.Ton/src/Models/TonEnum.cs b/src/CSharp/DevPossible.Ton/src/Models/TonEnum.cs index a98eb1a..057087c 100644 --- a/src/CSharp/DevPossible.Ton/src/Models/TonEnum.cs +++ b/src/CSharp/DevPossible.Ton/src/Models/TonEnum.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; -namespace TONfile +namespace DevPossible.Ton { /// /// Represents a single enum value in TON format diff --git a/src/CSharp/DevPossible.Ton/src/Models/TonObject.cs b/src/CSharp/DevPossible.Ton/src/Models/TonObject.cs index 7722c3d..fb1b112 100644 --- a/src/CSharp/DevPossible.Ton/src/Models/TonObject.cs +++ b/src/CSharp/DevPossible.Ton/src/Models/TonObject.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Reflection; -namespace TONfile +namespace DevPossible.Ton { /// /// Represents a TON object with properties and child objects diff --git a/src/CSharp/DevPossible.Ton/src/Models/TonValue.cs b/src/CSharp/DevPossible.Ton/src/Models/TonValue.cs index 6465241..daa3a9a 100644 --- a/src/CSharp/DevPossible.Ton/src/Models/TonValue.cs +++ b/src/CSharp/DevPossible.Ton/src/Models/TonValue.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text.RegularExpressions; -namespace TONfile +namespace DevPossible.Ton { /// /// Represents a value in a TON document with type information diff --git a/src/CSharp/DevPossible.Ton/src/Parser/TonParseOptions.cs b/src/CSharp/DevPossible.Ton/src/Parser/TonParseOptions.cs index f2b4379..0d7a112 100644 --- a/src/CSharp/DevPossible.Ton/src/Parser/TonParseOptions.cs +++ b/src/CSharp/DevPossible.Ton/src/Parser/TonParseOptions.cs @@ -1,4 +1,4 @@ -namespace TONfile +namespace DevPossible.Ton { /// /// Options for parsing TON documents diff --git a/src/CSharp/DevPossible.Ton/src/Parser/TonParser.cs b/src/CSharp/DevPossible.Ton/src/Parser/TonParser.cs index 48ed11c..5251534 100644 --- a/src/CSharp/DevPossible.Ton/src/Parser/TonParser.cs +++ b/src/CSharp/DevPossible.Ton/src/Parser/TonParser.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using TONfile.Lexer; +using DevPossible.Ton.Lexer; -namespace TONfile +namespace DevPossible.Ton { /// /// Parser for TON documents diff --git a/src/CSharp/DevPossible.Ton/src/Schema/TonSchemaDefinition.cs b/src/CSharp/DevPossible.Ton/src/Schema/TonSchemaDefinition.cs index 3dc62de..b1d1111 100644 --- a/src/CSharp/DevPossible.Ton/src/Schema/TonSchemaDefinition.cs +++ b/src/CSharp/DevPossible.Ton/src/Schema/TonSchemaDefinition.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; -namespace TONfile +namespace DevPossible.Ton { /// /// Represents a schema definition for a TON class diff --git a/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializeOptions.cs b/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializeOptions.cs index a1b32dc..f232704 100644 --- a/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializeOptions.cs +++ b/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializeOptions.cs @@ -1,4 +1,4 @@ -namespace TONfile +namespace DevPossible.Ton { /// /// Options for serializing objects to TON format diff --git a/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializer.cs b/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializer.cs index abdda56..bf7cde8 100644 --- a/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializer.cs +++ b/src/CSharp/DevPossible.Ton/src/Serializer/TonSerializer.cs @@ -8,7 +8,7 @@ using System.Text; using System.Threading.Tasks; -namespace TONfile +namespace DevPossible.Ton { /// /// Serializer for converting objects to TON format diff --git a/src/CSharp/DevPossible.Ton/src/Validator/TonValidator.cs b/src/CSharp/DevPossible.Ton/src/Validator/TonValidator.cs index 6a4fee7..ad357e1 100644 --- a/src/CSharp/DevPossible.Ton/src/Validator/TonValidator.cs +++ b/src/CSharp/DevPossible.Ton/src/Validator/TonValidator.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text.RegularExpressions; -namespace TONfile +namespace DevPossible.Ton { /// /// Validator for TON documents and objects diff --git a/src/JavaScript/devpossible-ton-samples/SampleData/config.ton b/src/JavaScript/devpossible-ton-samples/SampleData/config.ton index 690cd29..c2ea83d 100644 --- a/src/JavaScript/devpossible-ton-samples/SampleData/config.ton +++ b/src/JavaScript/devpossible-ton-samples/SampleData/config.ton @@ -1,6 +1,6 @@ // Application configuration file {(AppConfig) - application = 'TONfile Demo', + application = 'DevPossible.Ton Demo', version = 1.5, environment = |production|, @@ -41,4 +41,4 @@ ttl = 3600, maxSize = 1000 } -} \ No newline at end of file +} diff --git a/src/JavaScript/devpossible-ton/README.md b/src/JavaScript/devpossible-ton/README.md new file mode 100644 index 0000000..9353fa6 --- /dev/null +++ b/src/JavaScript/devpossible-ton/README.md @@ -0,0 +1,237 @@ +# DevPossible.Ton - JavaScript / TypeScript Library + +**Developed by DevPossible, LLC** +**Contact: support@devpossible.com** + +JavaScript/TypeScript implementation of the TON (Text Object Notation) parser, serializer, formatter, and validator. + +## Installation + +```bash +npm install @devpossible/ton +``` + +or + +```bash +yarn add @devpossible/ton +``` + +## Quick Start + +```javascript +import { TonParser, TonDocument, TonObject, TonValue, TonSerializer, TonSerializeOptions } from '@devpossible/ton'; + +// Parse a TON file +const parser = new TonParser(); +const document = parser.parseFile('config.ton'); + +// Access properties +const name = document.rootObject.getProperty('name')?.toString(); +const port = document.rootObject.getProperty('port')?.toInt32() ?? 8080; + +// Create a new document +const newDoc = new TonDocument(); +newDoc.rootObject.setProperty('name', TonValue.from('My App')); +newDoc.rootObject.setProperty('port', TonValue.from(8080)); + +// Add nested object +const database = new TonObject('database'); +database.setProperty('host', TonValue.from('localhost')); +newDoc.rootObject.addChild(database); + +// Serialize and save +const serializer = new TonSerializer(); +const tonContent = serializer.serializeDocument(newDoc, TonSerializeOptions.Pretty); +await serializer.serializeToFile(newDoc, 'config.ton', TonSerializeOptions.Pretty); +``` + +## Features + +- ✅ Full TON specification parser with async support +- ✅ Comprehensive schema validation with 30+ validation rule types +- ✅ Code formatter with compact and pretty styles +- ✅ Type annotations and hints +- ✅ Enum and EnumSet support +- ✅ Array support with mixed types +- ✅ Pretty and compact serialization +- ✅ Async file operations +- ✅ Schema collections and definitions +- ✅ Path-based schema validation +- ✅ TypeScript type definitions included +- ✅ ESM and CommonJS support + +## Advanced Usage + +### Schema Validation + +```javascript +import { TonParser, TonSchemaCollection, TonSchemaDefinition, TonPropertySchema, TonValidationRule, TonValidator, ValidationRuleType } from '@devpossible/ton'; + +// Define schema +const schemas = new TonSchemaCollection(); +const userSchema = new TonSchemaDefinition('user'); + +// Add property validations +const nameSchema = new TonPropertySchema('/name', 'string'); +nameSchema.addValidation(new TonValidationRule(ValidationRuleType.Required)); +nameSchema.addValidation(new TonValidationRule(ValidationRuleType.MaxLength, 100)); +userSchema.addProperty('/name', nameSchema); + +const emailSchema = new TonPropertySchema('/email', 'string'); +emailSchema.addValidation(new TonValidationRule(ValidationRuleType.Format, 'email')); +userSchema.addProperty('/email', emailSchema); + +schemas.addSchema(userSchema); + +// Validate document +const validator = new TonValidator(); +const parser = new TonParser(); +const document = parser.parse("{ (user) name = 'John', email = 'john@example.com' }"); +document.schemas = schemas; + +const results = validator.validate(document); +if (!results.isValid) { + results.errors.forEach(error => + console.log(`Error at ${error.path}: ${error.message}`) + ); +} +``` + +### Formatting + +```javascript +import { TonFormatter, TonFormatStyle } from '@devpossible/ton'; + +// Format a TON string with pretty formatting (default) +const unformattedTon = "{name='MyApp',version=1.0,enabled=true}"; +const prettyFormatted = TonFormatter.formatString(unformattedTon); + +// Format with compact formatting +const compactFormatted = TonFormatter.formatString(unformattedTon, TonFormatStyle.Compact); + +// Format files +TonFormatter.formatFileInPlace('config.ton', TonFormatStyle.Pretty); + +// Async formatting +const formatted = await TonFormatter.formatStringAsync(unformattedTon, TonFormatStyle.Pretty); +``` + +### Serialization Options + +```javascript +import { TonSerializeOptions } from '@devpossible/ton'; + +// Compact format - minimal size +const compact = TonSerializeOptions.Compact; + +// Pretty format - human readable with all features +const pretty = TonSerializeOptions.Pretty; + +// Custom options +const custom = new TonSerializeOptions({ + // Formatting + indentation: ' ', // Two spaces + pretty: true, // Enable formatting + sortProperties: true, // Alphabetical property order + + // Content control + includeHeader: true, // Include #@ header + includeSchema: true, // Include #! schema + includeTypeHints: true, // Add type hints ($, %, etc.) + + // Value handling + omitNullValues: false, // Include null values + omitUndefinedValues: true, // Skip undefined values + omitEmptyCollections: false, // Include empty arrays + + // Formatting preferences + useAtPrefix: true, // Use @ for properties + quoteChar: "'", // Use single quotes + useMultiLineStrings: true, // Enable multi-line string format + multiLineStringThreshold: 2, // Min lines to use multi-line format + lowercaseHex: true, // 0xff instead of 0xFF + lowercaseGuids: true, // Lowercase GUID format + preferEnumNames: true // Use names over indices +}); + +const serializer = new TonSerializer(); +const output = serializer.serializeDocument(document, custom); +``` + +### Working with Arrays + +```javascript +import { TonDocument, TonValue } from '@devpossible/ton'; + +// Create document with arrays +const document = new TonDocument(); +const tags = ['production', 'web', 'api']; +const scores = [98.5, 87.2, 95.0]; + +document.rootObject.setProperty('tags', TonValue.from(tags)); +document.rootObject.setProperty('scores', TonValue.from(scores)); + +// Format with different styles +const serializer = new TonSerializer(); +const compact = serializer.serializeDocument(document, TonSerializeOptions.Compact); +const pretty = serializer.serializeDocument(document, TonSerializeOptions.Pretty); + +// Or use the formatter directly +const formatted = TonFormatter.formatString(compact, TonFormatStyle.Pretty); +``` + +## TypeScript Support + +The library includes full TypeScript type definitions: + +```typescript +import { TonParser, TonDocument, TonValue, TonValueType } from '@devpossible/ton'; + +const parser: TonParser = new TonParser(); +const document: TonDocument = parser.parseFile('config.ton'); + +const value: TonValue | undefined = document.rootObject.getProperty('name'); +if (value?.type === TonValueType.String) { + const name: string = value.toString(); +} +``` + +## API Reference + +### Core Classes + +- **`TonDocument`** - Represents a complete TON document with header, root object, and schemas +- **`TonObject`** - Represents an object with properties and child objects +- **`TonValue`** - Represents a typed value with conversion methods +- **`TonParser`** - Parses TON content from various sources +- **`TonSerializer`** - Serializes TON objects to string format +- **`TonFormatter`** - Formats existing TON content with different styles +- **`TonValidator`** - Validates TON documents against schemas + +### Key Enumerations + +- **`TonValueType`** - Types of TON values (String, Integer, Float, Boolean, etc.) +- **`TonTokenType`** - Token types used by the lexer +- **`ValidationRuleType`** - Types of validation rules +- **`TonFormatStyle`** - Formatting styles (Compact, Pretty) + +## Requirements + +- Node.js 14.0.0 or later +- Modern browsers with ES2015+ support + +## License + +MIT License - Copyright © 2024 DevPossible, LLC + +## Support + +**DevPossible, LLC** +Website: [devpossible.com](https://www.devpossible.com) +Email: support@devpossible.com +TON Specification: [tonspec.com](https://tonspec.com) + +--- + +**© 2024 DevPossible, LLC. All rights reserved.** diff --git a/src/JavaScript/devpossible-ton/package.json b/src/JavaScript/devpossible-ton/package.json index 0921b1d..15983b9 100644 --- a/src/JavaScript/devpossible-ton/package.json +++ b/src/JavaScript/devpossible-ton/package.json @@ -1,6 +1,6 @@ { "name": "@devpossible/ton", - "version": "0.1.5", + "version": "0.1.6", "description": "JavaScript library for parsing, validating, and serializing TON (Text Object Notation) files. Full specification at https://tonspec.com. ALPHA RELEASE: Core functionality is complete but API may change before stable 1.0 release.", "type": "module", "main": "dist/index.js", @@ -8,7 +8,8 @@ "types": "dist/index.d.ts", "files": [ "dist", - "src" + "src", + "README.md" ], "scripts": { "build": "rollup -c", diff --git a/src/Python/devpossible_ton/setup.py b/src/Python/devpossible_ton/setup.py index 908049c..c9b4494 100644 --- a/src/Python/devpossible_ton/setup.py +++ b/src/Python/devpossible_ton/setup.py @@ -10,7 +10,7 @@ setup( name="devpossible-ton", - version="0.1.5", + version="0.1.6", author="DevPossible, LLC", author_email="support@devpossible.com", description="Python library for parsing, validating, and serializing TON (Text Object Notation) files. Full specification at https://tonspec.com. ALPHA RELEASE: Core functionality is complete but API may change before stable 1.0 release.", @@ -65,3 +65,4 @@ + diff --git a/src/Python/devpossible_ton_samples/SampleData/config.ton b/src/Python/devpossible_ton_samples/SampleData/config.ton index 690cd29..c2ea83d 100644 --- a/src/Python/devpossible_ton_samples/SampleData/config.ton +++ b/src/Python/devpossible_ton_samples/SampleData/config.ton @@ -1,6 +1,6 @@ // Application configuration file {(AppConfig) - application = 'TONfile Demo', + application = 'DevPossible.Ton Demo', version = 1.5, environment = |production|, @@ -41,4 +41,4 @@ ttl = 3600, maxSize = 1000 } -} \ No newline at end of file +} diff --git a/update-version.ps1 b/update-version.ps1 index 0646f50..4434f66 100644 --- a/update-version.ps1 +++ b/update-version.ps1 @@ -71,10 +71,17 @@ Write-Host "✓ Updated $packageJsonPath" -ForegroundColor Green # Update Python setup.py $setupPyPath = "src/Python/devpossible_ton/setup.py" $setupPyContent = Get-Content $setupPyPath -Raw -$setupPyContent = $setupPyContent -replace 'version="[^"]*"', "version=`"$pythonVersion`"" +$setupPyContent = $setupPyContent -replace 'version=\"[^\"]*\"', "version=`"$pythonVersion`"" $setupPyContent | Set-Content $setupPyPath Write-Host "✓ Updated $setupPyPath" -ForegroundColor Green +# Update C# README.md +$csharpReadmePath = "src/CSharp/DevPossible.Ton/README.md" +$csharpReadmeContent = Get-Content $csharpReadmePath -Raw +$csharpReadmeContent = $csharpReadmeContent -replace 'Version=\"[^\"]*\"', "Version=`"$Version`"" +$csharpReadmeContent | Set-Content $csharpReadmePath +Write-Host "✓ Updated $csharpReadmePath (PackageReference version)" -ForegroundColor Green + Write-Host "`nVersion update complete!" -ForegroundColor Green Write-Host "`nNext steps:" -ForegroundColor Yellow Write-Host "1. Review the changes" -ForegroundColor Yellow diff --git a/version.json b/version.json index 0afbad2..438a445 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "library_version": "0.1.5", + "library_version": "0.1.6", "ton_spec_version": "1.0", "description": "Centralized version file for all DevPossible.Ton packages. library_version is for the package, ton_spec_version is for the TON file format specification." }