From 380956f4788de15299697567a2aed33721e62eb5 Mon Sep 17 00:00:00 2001
From: Gleb Kashkin <g.kashkin@tarantool.org>
Date: Thu, 6 Jul 2023 08:50:53 +0000
Subject: [PATCH] compat: add is_new and is_old to options

It used to be somewhat complicated to check the effective value
of a compat option, because `<option_name>.current` could contain
'default' state.
This patch introduces helper functions that take care of that.

The following alternatives were considered:
* `compat.<option_name>.effective` - it is excessive in the presence
  if `current` and `default`, and is visible in serialization
* `compat.<option_name>.get()` - while it is a function, it does only
  half of the work required, user still has to compare result to 'new'

Closes #8807

@TarantoolBot document
Title: Add `:is_new/old()` helpers to tarantool.compat options

`compat.<option_name>.current` can be 'new', 'old' or 'default',
thus when it is default there must be an additional check if
`compat.<option_name>.default` is 'new'. It is handier to have a
helper to deal with that instead of complicated `if`:
* check if effective value is 'new' before the patch:
  ```lua
  if compat.<option_name>.current == 'new' or
          (compat.<option_name>.current == 'default' and
           compat.<option_name>.default == 'new') then
      ...
  end
  ```
* after the patch:
  ```lua
  if compat.<option_name>:is_new() then
      ...
  end
  ```

Please update [tutorial on using compat], maybe add an example to
[Listing options details].

[tutorial on using compat]: https://www.tarantool.io/en/doc/latest/reference/reference_lua/compat/compat_tutorial/
[Listing options details]: https://www.tarantool.io/en/doc/latest/reference/reference_lua/compat/compat_tutorial/#listing-options-details

(cherry picked from commit 5f6d367c51f7545a940119e7a393baf982b80f3f)
---
 .../unreleased/gh-8807-compat-is-new-old.md   |  4 ++++
 src/lua/compat.lua                            | 22 +++++++++++++++++++
 .../gh_7000_compat_module_test.lua            | 20 +++++++++++++++++
 3 files changed, 46 insertions(+)
 create mode 100644 changelogs/unreleased/gh-8807-compat-is-new-old.md

diff --git a/changelogs/unreleased/gh-8807-compat-is-new-old.md b/changelogs/unreleased/gh-8807-compat-is-new-old.md
new file mode 100644
index 0000000000..e10a4a2247
--- /dev/null
+++ b/changelogs/unreleased/gh-8807-compat-is-new-old.md
@@ -0,0 +1,4 @@
+## feature/lua
+
+* Added the `:is_new()` and `:is_old()` helpers to `tarantool.compat`
+  options to simplify effective value checks (gh-8807).
diff --git a/src/lua/compat.lua b/src/lua/compat.lua
index ef2d69d189..ed06a0eb83 100644
--- a/src/lua/compat.lua
+++ b/src/lua/compat.lua
@@ -403,6 +403,28 @@ function compat_mt.__index(_, key)
         result.current = 'old'
     end
 
+    -- Whether the effective value of the option is `new`.
+    function result.is_new(option)
+        if type(option) ~= 'table' then
+            error('usage: compat.<option_name>:is_new()')
+        end
+        if option.current == 'new' then
+            return true
+        end
+        if option.current == 'old' then
+            return false
+        end
+        return option.default == 'new'
+    end
+
+    -- Whether the effective value of the option is `old`.
+    function result.is_old(option)
+        if type(option) ~= 'table' then
+            error(('usage: compat.%s:is_old()'):format(key))
+        end
+        return not option:is_new()
+    end
+
     return result
 end
 
diff --git a/test/app-luatest/gh_7000_compat_module_test.lua b/test/app-luatest/gh_7000_compat_module_test.lua
index 356ed3a5da..01d27a4b85 100644
--- a/test/app-luatest/gh_7000_compat_module_test.lua
+++ b/test/app-luatest/gh_7000_compat_module_test.lua
@@ -216,6 +216,26 @@ g.test_help = function()
     t.assert(compat.help())
 end
 
+g.test_is_new_is_old = function()
+    for _, option_def in pairs(definitions) do
+        local name = option_def.name
+        t.assert(compat[name])
+
+        compat[name] = 'new'
+        t.assert(compat[name]:is_new())
+        t.assert_not(compat[name]:is_old())
+
+        compat[name] = 'old'
+        t.assert_not(compat[name]:is_new())
+        t.assert(compat[name]:is_old())
+
+        compat[name] = 'default'
+        local is_new = option_def.default == 'new'
+        t.assert_equals(compat[name]:is_new(), is_new)
+        t.assert_equals(compat[name]:is_old(), not is_new)
+    end
+end
+
 g.test_hot_reload = function()
     local hot_reload_option_def_1 = {
         name = 'hot_reload_option',
-- 
GitLab