Neon.Core.Persistence.Swagger.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. {******************************************************************************}
  2. { }
  3. { Neon: Serialization Library for Delphi }
  4. { Copyright (c) 2018-2019 Paolo Rossi }
  5. { https://github.com/paolo-rossi/neon-library }
  6. { }
  7. {******************************************************************************}
  8. { }
  9. { Licensed under the Apache License, Version 2.0 (the "License"); }
  10. { you may not use this file except in compliance with the License. }
  11. { You may obtain a copy of the License at }
  12. { }
  13. { http://www.apache.org/licenses/LICENSE-2.0 }
  14. { }
  15. { Unless required by applicable law or agreed to in writing, software }
  16. { distributed under the License is distributed on an "AS IS" BASIS, }
  17. { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
  18. { See the License for the specific language governing permissions and }
  19. { limitations under the License. }
  20. { }
  21. {******************************************************************************}
  22. unit Neon.Core.Persistence.Swagger;
  23. interface
  24. {$I Neon.inc}
  25. uses
  26. System.SysUtils, System.Classes, System.Rtti, System.SyncObjs,
  27. System.TypInfo, System.Generics.Collections, System.JSON, Data.DB,
  28. Neon.Core.Types,
  29. Neon.Core.Attributes,
  30. Neon.Core.Persistence,
  31. Neon.Core.TypeInfo,
  32. Neon.Core.Utils;
  33. type
  34. /// <summary>
  35. /// Swagger (OpenAPI 2.0) schema generator
  36. /// </summary>
  37. TNeonSchemaGenerator = class(TNeonBase)
  38. private
  39. /// <summary>
  40. /// Writer for members of objects and records
  41. /// </summary>
  42. procedure WriteMembers(AType: TRttiType; AResult: TJSONObject);
  43. private
  44. /// <summary>
  45. /// Writer for string types
  46. /// </summary>
  47. function WriteString(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  48. /// <summary>
  49. /// Writer for Boolean types
  50. /// </summary>
  51. function WriteBoolean(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  52. /// <summary>
  53. /// Writer for enums types <br />
  54. /// </summary>
  55. function WriteEnum(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  56. /// <summary>
  57. /// Writer for Integer types <br />
  58. /// </summary>
  59. function WriteInteger(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  60. /// <summary>
  61. /// Writer for Integer types <br />
  62. /// </summary>
  63. function WriteInt64(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  64. /// <summary>
  65. /// Writer for float types
  66. /// </summary>
  67. function WriteFloat(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  68. function WriteDouble(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  69. /// <summary>
  70. /// Writer for TDate* types
  71. /// </summary>
  72. function WriteDate(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  73. function WriteDateTime(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  74. /// <summary>
  75. /// Writer for Variant types
  76. /// </summary>
  77. /// <remarks>
  78. /// The variant will be written as string
  79. /// </remarks>
  80. function WriteVariant(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  81. /// <summary>
  82. /// Writer for static and dynamic arrays
  83. /// </summary>
  84. function WriteArray(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  85. function WriteDynArray(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  86. /// <summary>
  87. /// Writer for the set type
  88. /// </summary>
  89. /// <remarks>
  90. /// The output is a string with the values comma separated and enclosed by square brackets
  91. /// </remarks>
  92. /// <returns>[First,Second,Third]</returns>
  93. function WriteSet(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  94. /// <summary>
  95. /// Writer for a record type
  96. /// </summary>
  97. /// <remarks>
  98. /// For records the engine serialize the fields by default
  99. /// </remarks>
  100. function WriteRecord(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  101. /// <summary>
  102. /// Writer for a standard TObject (descendants) type (no list, stream or streamable)
  103. /// </summary>
  104. function WriteObject(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  105. /// <summary>
  106. /// Writer for an Interface type
  107. /// </summary>
  108. /// <remarks>
  109. /// The object that implements the interface is serialized
  110. /// </remarks>
  111. function WriteInterface(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  112. /// <summary>
  113. /// Writer for TStream (descendants) objects
  114. /// </summary>
  115. function WriteStream(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  116. /// <summary>
  117. /// Writer for TDataSet (descendants) objects
  118. /// </summary>
  119. function WriteDataSet(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  120. /// <summary>
  121. /// Writer for "Enumerable" objects (Lists, Generic Lists, TStrings, etc...)
  122. /// </summary>
  123. /// <remarks>
  124. /// Objects must have GetEnumerator, Clear, Add methods
  125. /// </remarks>
  126. function WriteEnumerable(AType: TRttiType; ANeonObject: TNeonRttiObject; AList: INeonTypeInfoList): TJSONObject;
  127. function IsEnumerable(AType: TRttiType; out AList: INeonTypeInfoList): Boolean;
  128. /// <summary>
  129. /// Writer for "Dictionary" objects (TDictionary, TObjectDictionary)
  130. /// </summary>
  131. /// <remarks>
  132. /// Objects must have Keys, Values, GetEnumerator, Clear, Add methods
  133. /// </remarks>
  134. function WriteEnumerableMap(AType: TRttiType; ANeonObject: TNeonRttiObject; AMap: INeonTypeInfoMap): TJSONObject;
  135. function IsEnumerableMap(AType: TRttiType; out AMap: INeonTypeInfoMap): Boolean;
  136. /// <summary>
  137. /// Writer for "Streamable" objects
  138. /// </summary>
  139. /// <remarks>
  140. /// Objects must have LoadFromStream and SaveToStream methods
  141. /// </remarks>
  142. function WriteStreamable(AType: TRttiType; ANeonObject: TNeonRttiObject; AStream: INeonTypeInfoStream): TJSONObject;
  143. function IsStreamable(AType: TRttiType; out AStream: INeonTypeInfoStream): Boolean;
  144. /// <summary>
  145. /// Writer for "Nullable" records
  146. /// </summary>
  147. /// <remarks>
  148. /// Record must have HasValue and GetValue methods
  149. /// </remarks>
  150. function WriteNullable(AType: TRttiType; ANeonObject: TNeonRttiObject; ANullable: INeonTypeInfoNullable): TJSONObject;
  151. function IsNullable(AType: TRttiType; out ANullable: INeonTypeInfoNullable): Boolean;
  152. protected
  153. /// <summary>
  154. /// Function to be called by a custom serializer method (ISerializeContext)
  155. /// </summary>
  156. function WriteDataMember(AType: TRttiType): TJSONObject; overload;
  157. /// <summary>
  158. /// This method chooses the right Writer based on the Kind of the AValue parameter
  159. /// </summary>
  160. function WriteDataMember(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject; overload;
  161. public
  162. constructor Create(const AConfig: INeonConfiguration);
  163. /// <summary>
  164. /// Serialize any Delphi type into a JSONValue, the Delphi type must be passed as a TRttiType
  165. /// </summary>
  166. class function TypeToJSONSchema(AType: TRttiType): TJSONObject; overload;
  167. class function TypeToJSONSchema(AType: TRttiType; AConfig: INeonConfiguration): TJSONObject; overload;
  168. /// <summary>
  169. /// Serialize any Delphi type into a JSONValue, the Delphi type must be passed as a TRttiType
  170. /// </summary>
  171. class function ClassToJSONSchema(AClass: TClass): TJSONObject; overload;
  172. class function ClassToJSONSchema(AClass: TClass; AConfig: INeonConfiguration): TJSONObject; overload;
  173. end;
  174. implementation
  175. uses
  176. System.Variants;
  177. { TNeonSchemaGenerator }
  178. class function TNeonSchemaGenerator.ClassToJSONSchema(AClass: TClass): TJSONObject;
  179. begin
  180. Result := TypeToJSONSchema(TRttiUtils.Context.GetType(AClass), TNeonConfiguration.Default);
  181. end;
  182. class function TNeonSchemaGenerator.ClassToJSONSchema(AClass: TClass; AConfig: INeonConfiguration): TJSONObject;
  183. begin
  184. Result := TypeToJSONSchema(TRttiUtils.Context.GetType(AClass), AConfig);
  185. end;
  186. constructor TNeonSchemaGenerator.Create(const AConfig: INeonConfiguration);
  187. begin
  188. inherited Create(AConfig);
  189. FOperation := TNeonOperation.Serialize;
  190. end;
  191. function TNeonSchemaGenerator.IsEnumerable(AType: TRttiType; out AList: INeonTypeInfoList): Boolean;
  192. begin
  193. AList := TNeonTypeInfoList.GuessType(AType);
  194. Result := Assigned(AList);
  195. end;
  196. function TNeonSchemaGenerator.IsEnumerableMap(AType: TRttiType; out AMap: INeonTypeInfoMap): Boolean;
  197. begin
  198. AMap := TNeonTypeInfoMap.GuessType(AType);
  199. Result := Assigned(AMap);
  200. end;
  201. function TNeonSchemaGenerator.IsNullable(AType: TRttiType; out ANullable: INeonTypeInfoNullable): Boolean;
  202. begin
  203. ANullable := TNeonTypeInfoNullable.GuessType(AType);
  204. Result := Assigned(ANullable);
  205. end;
  206. function TNeonSchemaGenerator.IsStreamable(AType: TRttiType; out AStream: INeonTypeInfoStream): Boolean;
  207. begin
  208. AStream := TNeonTypeInfoStream.GuessType(AType);
  209. Result := Assigned(AStream);
  210. end;
  211. class function TNeonSchemaGenerator.TypeToJSONSchema(AType: TRttiType; AConfig: INeonConfiguration): TJSONObject;
  212. var
  213. LGenerator: TNeonSchemaGenerator;
  214. begin
  215. LGenerator := TNeonSchemaGenerator.Create(AConfig);
  216. try
  217. Result := LGenerator.WriteDataMember(AType);
  218. finally
  219. LGenerator.Free;
  220. end;
  221. end;
  222. class function TNeonSchemaGenerator.TypeToJSONSchema(AType: TRttiType): TJSONObject;
  223. begin
  224. Result := TypeToJSONSchema(AType, TNeonConfiguration.Default);
  225. end;
  226. function TNeonSchemaGenerator.WriteArray(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  227. var
  228. LItems: TJSONObject;
  229. begin
  230. LItems := WriteDataMember((AType as TRttiArrayType).ElementType);
  231. Result := TJSONObject.Create
  232. .AddPair('type', 'array')
  233. .AddPair('items', LItems)
  234. end;
  235. function TNeonSchemaGenerator.WriteBoolean(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  236. begin
  237. Result := TJSONObject.Create
  238. .AddPair('type', 'boolean');
  239. end;
  240. function TNeonSchemaGenerator.WriteDataMember(AType: TRttiType): TJSONObject;
  241. var
  242. LNeonObject: TNeonRttiObject;
  243. begin
  244. LNeonObject := TNeonRttiObject.Create(AType, FOperation);
  245. LNeonObject.ParseAttributes;
  246. try
  247. Result := WriteDataMember(AType, LNeonObject);
  248. finally
  249. LNeonObject.Free;
  250. end;
  251. end;
  252. function TNeonSchemaGenerator.WriteDataMember(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  253. var
  254. LNeonTypeInfo: INeonTypeInfo;
  255. LNeonMap: INeonTypeInfoMap absolute LNeonTypeInfo;
  256. LNeonList: INeonTypeInfoList absolute LNeonTypeInfo;
  257. LNeonStream: INeonTypeInfoStream absolute LNeonTypeInfo;
  258. LNeonNullable: INeonTypeInfoNullable absolute LNeonTypeInfo;
  259. begin
  260. Result := nil;
  261. case AType.TypeKind of
  262. tkChar,
  263. tkWChar,
  264. tkString,
  265. tkLString,
  266. tkWString,
  267. tkUString:
  268. begin
  269. Result := WriteString(AType, ANeonObject);
  270. end;
  271. tkEnumeration:
  272. begin
  273. if AType.Handle = System.TypeInfo(Boolean) then
  274. Result := WriteBoolean(AType, ANeonObject)
  275. else
  276. Result := WriteEnum(AType, ANeonObject);
  277. end;
  278. tkInteger:
  279. begin
  280. Result := WriteInteger(AType, ANeonObject);
  281. end;
  282. tkInt64:
  283. begin
  284. Result := WriteInt64(AType, ANeonObject);
  285. end;
  286. tkFloat:
  287. begin
  288. if AType.Handle = TypeInfo(Single) then
  289. Result := WriteFloat(AType, ANeonObject)
  290. else if AType.Handle = TypeInfo(TDateTime) then
  291. Result := WriteDateTime(AType, ANeonObject)
  292. else if AType.Handle = TypeInfo(TTime) then
  293. Result := WriteDateTime(AType, ANeonObject)
  294. else if AType.Handle = TypeInfo(TDate) then
  295. Result := WriteDate(AType, ANeonObject)
  296. else
  297. Result := WriteDouble(AType, ANeonObject);
  298. end;
  299. tkClass:
  300. begin
  301. if AType.IsInstance and AType.AsInstance.MetaclassType.InheritsFrom(TDataSet) then
  302. Result := WriteDataSet(AType, ANeonObject)
  303. else if AType.IsInstance and AType.AsInstance.MetaclassType.InheritsFrom(TStream) then
  304. Result := WriteStream(AType, ANeonObject)
  305. else if IsEnumerableMap(AType, LNeonMap) then
  306. Result := WriteEnumerableMap(AType, ANeonObject, LNeonMap)
  307. else if IsEnumerable(AType, LNeonList) then
  308. Result := WriteEnumerable(AType, ANeonObject, LNeonList)
  309. else if IsStreamable(AType, LNeonStream) then
  310. Result := WriteStreamable(AType, ANeonObject, LNeonStream)
  311. else
  312. Result := WriteObject(AType, ANeonObject);
  313. end;
  314. tkArray:
  315. begin
  316. Result := WriteArray(AType, ANeonObject);
  317. end;
  318. tkDynArray:
  319. begin
  320. Result := WriteDynArray(AType, ANeonObject);
  321. end;
  322. tkSet:
  323. begin
  324. Result := WriteSet(AType, ANeonObject);
  325. end;
  326. tkRecord:
  327. begin
  328. if IsNullable(AType, LNeonNullable) then
  329. Result := WriteNullable(AType, ANeonObject, LNeonNullable)
  330. else
  331. Result := WriteRecord(AType, ANeonObject);
  332. end;
  333. tkInterface:
  334. begin
  335. Result := WriteInterface(AType, ANeonObject);
  336. end;
  337. tkVariant:
  338. begin
  339. Result := WriteVariant(AType, ANeonObject);
  340. end;
  341. end;
  342. end;
  343. function TNeonSchemaGenerator.WriteDataSet(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  344. var
  345. LJSONProps: TJSONObject;
  346. begin
  347. //Result := TDataSetUtils.RecordToJSONSchema(AValue.AsObject as TDataSet, FConfig);
  348. LJSONProps := TJSONObject.Create;
  349. Result := TJSONObject.Create
  350. .AddPair('type', 'object')
  351. .AddPair('properties', LJSONProps);
  352. end;
  353. function TNeonSchemaGenerator.WriteDate(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  354. begin
  355. Result := TJSONObject.Create
  356. .AddPair('type', 'string')
  357. .AddPair('format', 'date');
  358. end;
  359. function TNeonSchemaGenerator.WriteDateTime(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  360. begin
  361. Result := TJSONObject.Create
  362. .AddPair('type', 'string')
  363. .AddPair('format', 'date-time');
  364. end;
  365. function TNeonSchemaGenerator.WriteDouble(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  366. begin
  367. Result := TJSONObject.Create
  368. .AddPair('type', 'number')
  369. .AddPair('format', 'double');
  370. end;
  371. function TNeonSchemaGenerator.WriteDynArray(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  372. var
  373. LItems: TJSONObject;
  374. begin
  375. LItems := WriteDataMember((AType as TRttiDynamicArrayType).ElementType);
  376. Result := TJSONObject.Create
  377. .AddPair('type', 'array')
  378. .AddPair('items', LItems)
  379. end;
  380. function TNeonSchemaGenerator.WriteEnum(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  381. begin
  382. Result := TJSONObject.Create
  383. .AddPair('type', 'string');
  384. end;
  385. function TNeonSchemaGenerator.WriteFloat(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  386. begin
  387. Result := TJSONObject.Create
  388. .AddPair('type', 'number')
  389. .AddPair('format', 'float');
  390. end;
  391. function TNeonSchemaGenerator.WriteInt64(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  392. begin
  393. Result := TJSONObject.Create
  394. .AddPair('type', 'integer')
  395. .AddPair('format', 'int64');
  396. end;
  397. function TNeonSchemaGenerator.WriteInteger(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  398. begin
  399. Result := TJSONObject.Create
  400. .AddPair('type', 'integer')
  401. .AddPair('format', 'int32');
  402. end;
  403. function TNeonSchemaGenerator.WriteInterface(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  404. begin
  405. Result := nil;
  406. end;
  407. procedure TNeonSchemaGenerator.WriteMembers(AType: TRttiType; AResult: TJSONObject);
  408. var
  409. LJSONValue: TJSONObject;
  410. LMembers: TNeonRttiMembers;
  411. LNeonMember: TNeonRttiMember;
  412. begin
  413. LMembers := GetNeonMembers(nil, AType);
  414. LMembers.FilterSerialize;
  415. try
  416. for LNeonMember in LMembers do
  417. begin
  418. if LNeonMember.Serializable then
  419. begin
  420. try
  421. LJSONValue := WriteDataMember(LNeonMember.RttiType, LNeonMember);
  422. if Assigned(LJSONValue) then
  423. (AResult as TJSONObject).AddPair(GetNameFromMember(LNeonMember), LJSONValue);
  424. except
  425. LogError(Format('Error converting property [%s] of object [%s]',
  426. [LNeonMember.Name, AType.Name]));
  427. end;
  428. end;
  429. end;
  430. finally
  431. LMembers.Free;
  432. end;
  433. end;
  434. function TNeonSchemaGenerator.WriteNullable(AType: TRttiType; ANeonObject: TNeonRttiObject; ANullable: INeonTypeInfoNullable): TJSONObject;
  435. begin
  436. Result := nil;
  437. if Assigned(ANullable) then
  438. Result := WriteDataMember(ANullable.GetBaseType)
  439. end;
  440. function TNeonSchemaGenerator.WriteObject(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  441. var
  442. LProperties: TJSONObject;
  443. begin
  444. LProperties := TJSONObject.Create;
  445. WriteMembers(AType, LProperties);
  446. Result := TJSONObject.Create
  447. .AddPair('type', 'object')
  448. .AddPair('properties', LProperties);
  449. end;
  450. function TNeonSchemaGenerator.WriteEnumerable(AType: TRttiType; ANeonObject: TNeonRttiObject; AList: INeonTypeInfoList): TJSONObject;
  451. var
  452. LJSONItems: TJSONObject;
  453. begin
  454. // Is not an Enumerable compatible object
  455. if not Assigned(AList) then
  456. Exit(nil);
  457. LJSONItems := WriteDataMember(AList.GetItemType);
  458. Result := TJSONObject.Create
  459. .AddPair('type', 'array')
  460. .AddPair('items', LJSONItems);
  461. end;
  462. function TNeonSchemaGenerator.WriteEnumerableMap(AType: TRttiType; ANeonObject: TNeonRttiObject; AMap: INeonTypeInfoMap): TJSONObject;
  463. var
  464. LValueJSON: TJSONObject;
  465. begin
  466. // Is not an EnumerableMap-compatible object
  467. if not Assigned(AMap) then
  468. Exit(nil);
  469. LValueJSON := WriteDataMember(AMap.GetValueType);
  470. Result := TJSONObject.Create
  471. .AddPair('type', 'object')
  472. .AddPair('additionalProperties', LValueJSON);
  473. end;
  474. function TNeonSchemaGenerator.WriteRecord(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  475. var
  476. LProperties: TJSONObject;
  477. begin
  478. LProperties := TJSONObject.Create;
  479. WriteMembers(AType, LProperties);
  480. Result := TJSONObject.Create
  481. .AddPair('type', 'object')
  482. .AddPair('properties', LProperties);
  483. end;
  484. function TNeonSchemaGenerator.WriteSet(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  485. begin
  486. Result := TJSONObject.Create
  487. .AddPair('type', 'string');
  488. end;
  489. function TNeonSchemaGenerator.WriteStream(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  490. begin
  491. Result := TJSONObject.Create
  492. .AddPair('type', 'string')
  493. .AddPair('format', 'byte');
  494. end;
  495. function TNeonSchemaGenerator.WriteStreamable(AType: TRttiType; ANeonObject: TNeonRttiObject; AStream: INeonTypeInfoStream): TJSONObject;
  496. begin
  497. Result := TJSONObject.Create
  498. .AddPair('type', 'string')
  499. .AddPair('format', 'byte');
  500. end;
  501. function TNeonSchemaGenerator.WriteString(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  502. begin
  503. Result := TJSONObject.Create
  504. .AddPair('type', 'string');
  505. end;
  506. function TNeonSchemaGenerator.WriteVariant(AType: TRttiType; ANeonObject: TNeonRttiObject): TJSONObject;
  507. begin
  508. {
  509. case ANeonObject.NeonInclude.Value of
  510. Include.NotNull:
  511. begin
  512. if VarIsNull(AValue.AsVariant) then
  513. Exit(nil);
  514. end;
  515. Include.NotEmpty:
  516. begin
  517. if VarIsEmpty(AValue.AsVariant) then
  518. Exit(nil);
  519. end;
  520. end;
  521. }
  522. Result :=nil;
  523. //TJSONString.Create(AValue.AsVariant);
  524. end;
  525. end.