Skip to content

Commit 08296ad

Browse files
author
aafent
committed
Refactor of the RequestForObject handler
1 parent 1bbef38 commit 08296ad

16 files changed

Lines changed: 651 additions & 26 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using System.Text.Json;
2+
3+
namespace FAST.FBasic.InteractiveConsole.DemoObjects
4+
{
5+
// ----------------------------------------------------------------------
6+
// 1. Root Class (Mapping to the main JSON object)
7+
// Properties are now camelCase to match the JSON keys exactly,
8+
// and JsonPropertyName attributes have been removed.
9+
// ----------------------------------------------------------------------
10+
public record EmployeeProfile
11+
{
12+
// Basic types
13+
public string name { get; init; } = string.Empty;
14+
public int age { get; init; }
15+
public decimal salary { get; init; }
16+
public bool isActive { get; init; }
17+
public string email { get; init; } = string.Empty;
18+
19+
// Nested Object
20+
public Address address { get; init; } = new Address();
21+
22+
// Array of strings
23+
public List<string> hobbies { get; init; } = new List<string>();
24+
25+
// Array of integers
26+
public List<int> scores { get; init; } = new List<int>();
27+
28+
// Array of nested objects
29+
public List<Project> projects { get; init; } = new List<Project>();
30+
}
31+
32+
// ----------------------------------------------------------------------
33+
// 2. Nested Class for the 'address' object
34+
// Properties are now camelCase.
35+
// ----------------------------------------------------------------------
36+
public record Address
37+
{
38+
public string street { get; init; } = string.Empty;
39+
public string city { get; init; } = string.Empty;
40+
public string zipCode { get; init; } = string.Empty;
41+
}
42+
43+
// ----------------------------------------------------------------------
44+
// 3. Nested Class for items within the 'projects' array
45+
// Properties are now camelCase.
46+
// ----------------------------------------------------------------------
47+
public record Project
48+
{
49+
public string name { get; init; } = string.Empty;
50+
public string status { get; init; } = string.Empty;
51+
}
52+
53+
// ----------------------------------------------------------------------
54+
// Example usage (Demonstrates how to actually deserialize the data)
55+
// Note: The example usage now accesses properties using their new camelCase names.
56+
// ----------------------------------------------------------------------
57+
public class EmployeeProfileExample
58+
{
59+
public EmployeeProfile GetEmployeeProfile()
60+
{
61+
// NOTE: JsonPropertyName is no longer needed because the C# properties
62+
// are named exactly like the JSON keys (camelCase).
63+
string json = @"{
64+
""name"": ""John Doe"",
65+
""age"": 30,
66+
""salary"": 75000.50,
67+
""isActive"": true,
68+
""email"": ""john@example.com"",
69+
""address"": {
70+
""street"": ""123 Main St"",
71+
""city"": ""New York"",
72+
""zipCode"": ""10001""
73+
},
74+
""hobbies"": [""reading"", ""gaming"", ""coding""],
75+
""scores"": [95, 87, 92, 88],
76+
""projects"": [
77+
{
78+
""name"": ""Project A"",
79+
""status"": ""completed""
80+
},
81+
{
82+
""name"": ""Project B"",
83+
""status"": ""in-progress""
84+
}
85+
]
86+
}";
87+
88+
// Deserialize the JSON string into the C# object
89+
var profile = JsonSerializer.Deserialize<EmployeeProfile>(json);
90+
91+
return profile;
92+
}
93+
94+
95+
public void TestPrint(EmployeeProfile profile)
96+
{
97+
98+
if (profile != null)
99+
{
100+
Console.WriteLine($"Name: {profile.name}, Age: {profile.age}");
101+
Console.WriteLine($"City: {profile.address.city}");
102+
Console.WriteLine($"First Hobby: {profile.hobbies[0]}");
103+
Console.WriteLine($"Project Count: {profile.projects.Count}");
104+
}
105+
}
106+
}
107+
108+
}

FAST.FBasic.InteractiveConsole/FBasicIC_Setup.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,16 @@ private void setupEnvironment()
1111
{
1212
this.env = new();
1313
env.DefaultEnvironment(programsFolder);
14-
env.callHandler = (name) => { var filepath = Path.Combine(programsFolder, name); return File.ReadAllText(filepath); };
15-
env.requestForObjectHandler = (context, group, name) =>
14+
env.requestForObjectHandler = (request) =>
1615
{
17-
18-
19-
if ($"{context}.{group}.{name}" == "SQL.CONNECTION.MyCursor1")
16+
if ( request.Level3Request() == "SQL.CONNECTION.MyCursor1")
2017
{
2118
string cs = "<replace with your CS hear>";
2219
var connection = new SqliteConnection(cs);
2320
return connection;
2421
}
2522

26-
if ($"{context}.{group}" == "SQL.CONNECTION")
23+
if ( request.Level2Request() == "SQL.CONNECTION")
2724
{
2825
var demoDBcs = $"Data Source={getProgramsFolder()}\\Other\\demo.db";
2926
if (!File.Exists($"{getProgramsFolder()}\\Other\\demo.db"))
@@ -34,13 +31,28 @@ private void setupEnvironment()
3431
return connection;
3532
}
3633

37-
if ($"{context}.{group}.{name}" == "IN.TEST.NAME") return "THIS IS AN IN TEST!";
38-
if ($"{context}.{group}.{name}" == "IN.DB.DEMO")
34+
if (request.Level3Request() == "IN.TEST.NAME") return "THIS IS AN IN TEST!";
35+
if (request.Level3Request() == "IN.DB.DEMO")
3936
{
4037
var demoDBcs = $"Data Source={getProgramsFolder()}\\Other\\demo.db";
4138
new DemoDatabase().QueryData(demoDBcs);
4239
return true;
4340
}
41+
42+
43+
if (request.Level3Request() == "IN.OBJECT.EMPLOYPROFILE")
44+
{
45+
return new DemoObjects.EmployeeProfileExample().GetEmployeeProfile();
46+
}
47+
48+
if (request.Level3Request() == "IN.OBJECT.SHOWEMPLOYPROFILE")
49+
{
50+
return new DemoObjects.EmployeeProfileExample().GetEmployeeProfile();
51+
}
52+
53+
54+
Console.WriteLine($"Interactive: THE REQUEST FOR OBJECT NOT FOUND. Context:{request.Context}, Group:{request.Group}, Name:{request.Name}");
55+
4456
return null;
4557
};
4658
env.AddLibrary(new FBasicStringFunctions());
@@ -53,6 +65,7 @@ private void setupEnvironment()
5365
env.AddLibrary(new FBasicDecisionTables());
5466
env.AddLibrary(new FBasic2DArrays());
5567
env.AddLibrary(new FBasicStreams());
68+
env.AddLibrary(new FBasicJsonLibrary());
5669
env.AddLibrary(new FBasicTemplatingLibrary());
5770
env.AddVariable("table.column", "myColumn1");
5871

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
REM Test program for CALL and GOTO statements
2+
REM
3+
REM (v) request for an object that will be used into this program
4+
rinput OBJECT,EMPLOYPROFILE, emp ' load the external object into variable: emp
5+
6+
json text FROM emp
7+
json text2 dynamic from emp
8+
9+
print emp
10+
print ""
11+
print ""
12+
print ""
13+
print text
14+
print ""
15+
print ""
16+
print text2
17+
18+
Halt
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
namespace FAST.FBasicInterpreter
2+
{
3+
/// <summary>
4+
/// Request For Object Descriptor
5+
/// </summary>
6+
public class FBasicRequestForObjectDescriptor : IFBasicRequestForObjectDescriptor
7+
{
8+
#region (+) Constructors
9+
10+
public FBasicRequestForObjectDescriptor()
11+
{
12+
}
13+
14+
public FBasicRequestForObjectDescriptor(IInterpreter interpreter):this()
15+
{
16+
this.Interpreter= interpreter;
17+
}
18+
19+
public FBasicRequestForObjectDescriptor(IInterpreter interpreter, string context) : this(interpreter)
20+
{
21+
this.Context= context;
22+
}
23+
24+
public FBasicRequestForObjectDescriptor(IInterpreter interpreter, string context,string group) : this(interpreter,context)
25+
{
26+
this.Group= group;
27+
}
28+
29+
public FBasicRequestForObjectDescriptor(IInterpreter interpreter, string context, string group, string name) : this(interpreter, context, group)
30+
{
31+
this.Name = name;
32+
}
33+
#endregion (+) Constructors
34+
35+
/// <summary>
36+
/// The requestor interpreter
37+
/// </summary>
38+
public IInterpreter Interpreter { get; set; }
39+
40+
/// <summary>
41+
/// The context of the request
42+
/// </summary>
43+
public string Context { get; set; }
44+
45+
/// <summary>
46+
/// The Group of the request
47+
/// </summary>
48+
public string Group { get; set; }
49+
50+
/// <summary>
51+
/// The name of the Request
52+
/// </summary>
53+
public string Name { get; set; }
54+
55+
/// <summary>
56+
/// Optional, the variable name that will store the request
57+
/// </summary>
58+
public string VariableName { get; set; } = null;
59+
}
60+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace FAST.FBasicInterpreter
2+
{
3+
/// <summary>
4+
/// Extensions to class FBasicRequestForObjectDescriptor
5+
/// </summary>
6+
public static class FBasicRequestForObjectDescriptor_Extensions
7+
{
8+
9+
/// <summary>
10+
/// Get the "Context.Group.Name"
11+
/// </summary>
12+
/// <param name="descriptor"></param>
13+
/// <returns></returns>
14+
public static string Level3Request(this IFBasicRequestForObjectDescriptor descriptor)
15+
{
16+
return $"{descriptor.Context}.{descriptor.Group}.{descriptor.Name}";
17+
}
18+
19+
/// <summary>
20+
/// Get the "Context.Group"
21+
/// </summary>
22+
/// <param name="descriptor"></param>
23+
/// <returns></returns>
24+
public static string Level2Request(this IFBasicRequestForObjectDescriptor descriptor)
25+
{
26+
return $"{descriptor.Context}.{descriptor.Group}";
27+
}
28+
}
29+
}

FAST.FBasic.LibraryToolkit/Core/FBasic_Delegates.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,9 @@ namespace FAST.FBasicInterpreter
3333
/// <summary>
3434
/// The delegation of object requesting
3535
/// </summary>
36-
/// <param name="context">The Context</param>
37-
/// <param name="group">The group of names</param>
38-
/// <param name="name">The name</param>
36+
/// <param name="descriptor">The request descriptor</param>
3937
/// <returns>object</returns>
40-
public delegate object FBasicRequestForObject(string context, string group, string name);
38+
public delegate object FBasicRequestForObject(IFBasicRequestForObjectDescriptor descriptor);
4139

4240

4341
/// <summary>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace FAST.FBasicInterpreter
2+
{
3+
/// <summary>
4+
/// Request For Object Descriptor
5+
/// </summary>
6+
public interface IFBasicRequestForObjectDescriptor
7+
{
8+
/// <summary>
9+
/// The requestor interpreter
10+
/// </summary>
11+
IInterpreter Interpreter { get; set; }
12+
13+
/// <summary>
14+
/// The context of the request
15+
/// </summary>
16+
string Context { get; set; }
17+
18+
/// <summary>
19+
/// The Group of the request
20+
/// </summary>
21+
string Group { get; set; }
22+
23+
/// <summary>
24+
/// The name of the Request
25+
/// </summary>
26+
string Name { get; set; }
27+
28+
/// <summary>
29+
/// Optional, the variable name that will store the request
30+
/// </summary>
31+
string VariableName { get; set; }
32+
}
33+
}

FAST.FBasic.LibraryToolkit/Interfaces/IInterpreter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public interface IInterpreter
7777
void Exec();
7878
#endregion (+) Program execution methods
7979

80-
object RequestForObject(string context, string group, string name, bool errorIfNull = true);
80+
object RequestForObject(IFBasicRequestForObjectDescriptor request, bool errorIfNull = true);
8181

8282
void dumpInterpreter(bool interactive = false);
8383
bool TryParseSourceCode(out ProgramContainer program);

FAST.FBasicInterpreter/Core/Interpreter_Methods.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,13 @@ public void AddCollection(string name, IBasicCollection collection)
224224
/// <param name="group">The group</param>
225225
/// <param name="name">The name</param>
226226
/// <returns>The requested object or null</returns>
227-
public object RequestForObject(string context, string group, string name, bool errorIfNull = true)
227+
public object RequestForObject(IFBasicRequestForObjectDescriptor descriptor, bool errorIfNull = true)
228228
{
229229
if (this.RequestForObjectHandler == null)
230-
Error(context, $"The Request For Object Handler is not installed ({context},{group},{name}) [E100]");
231-
var returnObject = this.RequestForObjectHandler(context, group, name);
230+
Error(descriptor.Context, $"The Request For Object Handler is not installed ({descriptor.Context},{descriptor.Group},{descriptor.Name}) [E100]");
231+
var returnObject = this.RequestForObjectHandler(descriptor);
232232
if (errorIfNull & (returnObject == null))
233-
Error(context, $"Cannot get object for: ({context},{group},{name}) [E101]");
233+
Error(descriptor.Context, $"Cannot get object for: ({descriptor.Context},{descriptor.Group},{descriptor.Name}) [E101]");
234234
return returnObject;
235235
}
236236

FAST.FBasicInterpreter/Core/Interpreter_Statements.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,32 @@ void RInputStatement()
610610
string vname = this.lex.Identifier;
611611

612612
GetNextToken();
613-
614-
var value=RequestForObject(context: "IN", group: group, name: name);
615-
616-
SetVar(vname, new Value(value.ToString()) );
613+
var request = new FBasicRequestForObjectDescriptor(this,"IN");
614+
request.Group=group;
615+
request.Name=name;
616+
request.VariableName=vname;
617+
var value=RequestForObject(request);
618+
619+
if (value is Value)
620+
{
621+
SetVar(vname,(Value)value);
622+
return;
623+
}
624+
if (value is string)
625+
{
626+
SetVar(vname, new Value(value.ToString()));
627+
return;
628+
}
629+
else if ((value is Double) | (value is int))
630+
{
631+
SetVar(vname, new Value((double)value));
632+
return;
633+
}
634+
else
635+
{
636+
SetVar(vname,new Value(value,value.GetType().ToString()));
637+
return;
638+
}
617639

618640
}
619641

0 commit comments

Comments
 (0)