summary refs log tree commit diff stats
path: root/doc/manual
diff options
context:
space:
mode:
authorcooldome <cdome@bk.ru>2018-01-09 14:25:22 +0000
committerAndreas Rumpf <rumpf_a@web.de>2018-01-09 15:25:22 +0100
commit2c9e56a783e36b0f9db3f2f73d76c910f36a9ffd (patch)
tree3c0ed82169d0cb36a1f0e6c63bc4ce43718471bf /doc/manual
parentaff787db69ed67f54d72e9caa43e556a9d0e2674 (diff)
downloadNim-2c9e56a783e36b0f9db3f2f73d76c910f36a9ffd.tar.gz
Implement custom annotations (#6987)
Diffstat (limited to 'doc/manual')
-rw-r--r--doc/manual/pragmas.txt67
1 files changed, 67 insertions, 0 deletions
diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt
index 835b6909d..cd26a9448 100644
--- a/doc/manual/pragmas.txt
+++ b/doc/manual/pragmas.txt
@@ -1087,3 +1087,70 @@ In the above example, providing the -d flag causes the symbol
 ``FooBar`` to be overwritten at compile time, printing out 42. If the
 ``-d:FooBar=42`` were to be omitted, the default value of 5 would be
 used.
+
+
+Custom annotations 
+------------------
+It is possible to define custom typed pragmas. Custom pragmas do not effect 
+code generation directly, but their presence can be detected by macros.
+Custom pragmas are defined using templates annotated with pragma ``pragma``:
+
+.. code-block:: nim
+  template dbTable(name: string, table_space: string = nil) {.pragma.}
+  template dbKey(name: string = nil, primary_key: bool = false) {.pragma.}
+  template dbForeignKey(t: typedesc) {.pragma.}
+  template dbIgnore {.pragma.}
+
+
+Consider stylized example of possible Object Relation Mapping (ORM) implementation:
+
+.. code-block:: nim
+  const tblspace {.strdefine.} = "dev" # switch for dev, test and prod environments 
+
+  type
+    User {.dbTable("users", tblspace).} = object
+      id {.dbKey(primary_key = true).}: int
+      name {.dbKey"full_name".}: string
+      is_cached {.dbIgnore.}: bool
+      age: int
+
+    UserProfile {.dbTable("profiles", tblspace).} = object
+      id {.dbKey(primary_key = true).}: int
+      user_id {.dbForeignKey: User.}: int
+      read_access: bool
+      write_access: bool
+      admin_acess: bool
+
+In this example custom pragmas are used to describe how Nim objects are 
+mapped to the schema of the relational database. Custom pragmas can have 
+zero or more arguments. In order to pass multiple arguments use one of 
+template call syntaxes. All arguments are typed and follow standard 
+overload resolution rules for templates. Therefore, it is possible to have 
+default values for arguments, pass by name, varargs, etc. 
+
+Custom pragmas can be used in all locations where ordinary pragmas can be
+specified. It is possible to annotate procs, templates, type and variable 
+definitions, statements, etc.
+
+Macros module includes helpers which can be used to simplify custom pragma 
+access `hasCustomPragma`, `getCustomPragmaVal`. Please consult macros module 
+documentation for details. These macros are no magic, they don't do anything 
+you cannot do yourself by walking AST object representation.
+
+More examples with custom pragmas:
+  - Better serialization/deserialization control:
+
+  .. code-block:: nim
+    type MyObj = object
+      a {.dontSerialize.}: int
+      b {.defaultDeserialize: 5.}: int
+      c {.serializationKey: "_c".}: string
+
+  - Adopting type for gui inspector in a game engine:
+
+  .. code-block:: nim
+    type MyComponent = object
+      position {.editable, animatable.}: Vector3
+      alpha {.editRange: [0.0..1.0], animatable.}: float32
+
+