Skip to content

Commit 71c6536

Browse files
committed
Merge branch '24-enhance-readme' into 'master'
Enhance the readme Closes #24 See merge request picodata/brod/tarantool-module!48
2 parents ca17412 + 6dd4b03 commit 71c6536

File tree

2 files changed

+58
-57
lines changed

2 files changed

+58
-57
lines changed

README.md

Lines changed: 52 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,14 @@ Check that these items exist on the computer:
8787
- Tarantool 2.2
8888
- A rustc compiler + cargo builder. Any modern version should work
8989

90-
Create cargo project:
91-
```shell script
90+
1. Create cargo project:
91+
92+
```console
9293
$ cargo init --lib
9394
```
9495

95-
Add the following lines to `Cargo.toml`:
96+
2. Add the following lines to `Cargo.toml`:
97+
9698
```toml
9799
[package]
98100
name = "easy"
@@ -101,37 +103,34 @@ edition = "2018"
101103
# author, license, etc
102104

103105
[dependencies]
104-
tarantool = "0.4.2" # (1)
105-
serde = "1.0" # (2)
106+
tarantool = "0.4.2"
107+
serde = "1.0"
106108

107109
[lib]
108-
crate-type = ["cdylib"] # (3)
110+
crate-type = ["cdylib"]
109111
```
110112

111-
1. add to dependencies `tarantool` library;
112-
1. add to dependencies [Serde](https://github.com/serde-rs/serde), this is optional and required if you want to use rust
113-
structures as a tuple values (see [this example](#harder));
114-
1. you need to compile dynamic library.
113+
3. Create the server entypoint named `init.lua` with the following script:
115114

116-
Requests will be done using Tarantool as a client. Start Tarantool, and enter these requests:
117115
```lua
118-
box.cfg{listen=3306}
119-
box.schema.space.create('capi_test')
120-
box.space.capi_test:create_index('primary')
121-
net_box = require('net.box')
122-
capi_connection = net_box:new(3306)
116+
require('easy')
117+
box.cfg({listen = 3301})
118+
box.schema.func.create('easy', {language = 'C', if_not_exists = true})
119+
box.schema.func.create('easy.easy2', {language = 'C', if_not_exists = true})
120+
box.schema.user.grant('guest', 'execute', 'function', 'easy', {if_not_exists = true})
121+
box.schema.user.grant('guest', 'execute', 'function', 'easy.easy2', {if_not_exists = true})
123122
```
124123

125-
In plain language: create a space named `capi_test`, and make a connection to self named `capi_connection`.
126-
127-
Leave the client running. It will be used to enter more requests later.
124+
If these commands appear unfamiliar, look at the Tarantool documentation:
125+
- [box.cfg()](https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_cfg/);
126+
- [box.schema.func.create()](https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_schema/func_create/);
127+
- [box.schema.user.grant()](https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_schema/user_grant/).
128128

129-
#### Easy
129+
4. Edit `lib.rs` file and add the following lines:
130130

131-
Edit `lib.rs` file and add the following lines:
132131
```rust
133132
use std::os::raw::c_int;
134-
use tarantool_module::tuple::{FunctionArgs, FunctionCtx};
133+
use tarantool::tuple::{FunctionArgs, FunctionCtx};
135134

136135
#[no_mangle]
137136
pub extern "C" fn easy(_: FunctionCtx, _: FunctionArgs) -> c_int {
@@ -144,55 +143,50 @@ pub extern "C" fn easy2(_: FunctionCtx, _: FunctionArgs) -> c_int {
144143
println!("hello world -- easy2");
145144
0
146145
}
146+
147+
#[no_mangle]
148+
pub extern "C" fn luaopen_easy(_l: std::ffi::c_void) -> c_int {
149+
// Tarantool calls this function upon require("easy")
150+
println!("easy module loaded");
151+
0
152+
}
147153
```
148154

149-
Compile the program:
150-
```shell script
155+
#### Running a demo
156+
157+
Compile the program and start the server:
158+
159+
```console
151160
$ cargo build
161+
$ LUA_CPATH=target/debug/lib?.so tarantool init.lua
152162
```
153163

154-
Start another shell. Change directory (`cd`) so that it is the same as the directory that the client is running in.
155-
Copy the compiled library (it is located in subfolder `target/debug` at you
156-
project sources folder) to the current folder and rename it to `easy.so`
164+
The [LUA_CPATH](https://www.lua.org/pil/8.1.html) is necessary because Rust layout conventions
165+
slightly differs from those in Lua. Fortunately, Lua is rater flexible.
166+
167+
Now you're ready to make some requests. Open separate console window and run tarantool, we'll use it
168+
as a client. In the tarantool console paste the following:
157169

158-
Now go back to the client and execute these requests:
159170
```lua
160-
box.schema.func.create('easy', {language = 'C'})
161-
box.schema.user.grant('guest', 'execute', 'function', 'easy')
162-
capi_connection:call('easy')
171+
conn = require('net.box').connect(3301)
172+
conn:call('easy')
163173
```
164174

165-
If these requests appear unfamiliar, read the descriptions of
166-
[box.schema.func.create()](https://www.tarantool.io/en/doc/2.2/reference/reference_lua/box_schema/#box-schema-func-create),
167-
[box.schema.user.grant()](https://www.tarantool.io/en/doc/2.2/reference/reference_lua/box_schema/#box-schema-user-grant)
168-
and [conn:call()](https://www.tarantool.io/en/doc/2.2/reference/reference_lua/net_box/#net-box-call).
175+
Again, check out [net.box](https://www.tarantool.io/en/doc/latest/reference/reference_lua/net_box/)
176+
module documentation, if necessary.
169177

170-
The function that matters is `capi_connection:call('easy')`.
178+
The code above connects to the server and calls the 'easy' function. Since the `easy()` function in
179+
`lib.rs` begins with `println!("hello world")`, the words "hello world" will appear in the server console.
171180

172-
Its first job is to find the 'easy' function, which should be easy because by default Tarantool looks on the current directory
173-
for a file named `easy.so`.
181+
Also, it checks that the call was successful. Since the `easy()` function in `lib.rs` ends
182+
with return 0, there is no error message to display and the request is over.
174183

175-
Its second job is to call the 'easy' function. Since the `easy()` function in `lib.rs` begins with `println!("hello world")`,
176-
the words "hello world" will appear on the screen.
177-
178-
Its third job is to check that the call was successful. Since the `easy()` function in `lib.rs` ends with return 0, there
179-
is no error message to display and the request is over.
180-
181-
The result should look like this:
182-
```
183-
tarantool> capi_connection:call('easy')
184-
hello world
185-
---
186-
- []
187-
...
188-
```
184+
Now let's call the other function in lib.rs - `easy2()`. This is almost the same as the `easy()`
185+
function, but there's a detail: when the file name is not the same as the function name, then we
186+
have to specify _{file-name}_._{function-name}_.
189187

190-
Now let's call the other function in lib.rs - `easy2()`. This is almost the same as the `easy()` function, but there's a
191-
detail: when the file name is not the same as the function name, then we have to specify _{file-name}_._{function-name}_
192188
```lua
193-
box.schema.func.create('easy.easy2', {language = 'C'})
194-
box.schema.user.grant('guest', 'execute', 'function', 'easy.easy2')
195-
capi_connection:call('easy.easy2')
189+
conn:call('easy.easy2')
196190
```
197191

198192
... and this time the result will be `hello world -- easy2`.
@@ -202,6 +196,7 @@ Conclusion: calling a Rust function is easy.
202196
#### Harder
203197

204198
Create a new crate "harder". Put these lines to `lib.rs`:
199+
205200
```rust
206201
use serde::{Deserialize, Serialize};
207202
use std::os::raw::c_int;

examples/easy/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ pub extern "C" fn easy2(_: FunctionCtx, _: FunctionArgs) -> c_int {
1212
println!("hello world -- easy2");
1313
0
1414
}
15+
16+
pub extern "C" fn luaopen_easy(_l: std::ffi::c_void) -> c_int {
17+
// Tarantool calls this function upon require("easy")
18+
println!("easy module loaded");
19+
0
20+
}

0 commit comments

Comments
 (0)