#[repr(transparent)]
pub struct DataStore(_);
Expand description

Storage for heterogenous expression-like data.

DataStore can be used to pass expression-like structures via LibraryLink functions.

DataStore can be used as an argument or return type in a LibraryLink function exposed via #[export].

Use DataStore::nodes() to get an iterator over the DataStoreNodes contained in this DataStore.

Example

The following DataStore expression:

Developer`DataStore[1, "hello", False]

can be created using the Rust code:

use wolfram_library_link::DataStore;

let mut data = DataStore::new();

data.add_i64(1);
data.add_str("hello");
data.add_bool(false);

Implementations§

source§

impl DataStore

source

pub fn new() -> Self

Create an empty DataStore.

LibraryLink C Function: createDataStore.

Examples found in repository?
examples/tests/test_data_store.rs (line 19)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_empty_data_store() -> DataStore {
    DataStore::new()
}

#[wll::export]
fn test_single_int_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);

    data
}

#[wll::export]
fn test_multiple_int_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_i64(2);
    data.add_i64(3);

    data
}

#[wll::export]
fn test_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_f64(2.0);
    data.add_str("hello");

    data
}

#[wll::export]
fn test_named_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_named_i64("an i64", 1);
    data.add_named_f64("an f64", 2.0);
    data.add_named_str("a str", "hello");

    data
}

#[wll::export]
fn test_named_and_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_named_f64("real", 2.0);
    data.add_named_str("hello", "world");

    data
}

//======================================
// Non-atomic types
//======================================

#[wll::export]
fn test_named_numeric_array_data_store() -> DataStore {
    let array = NumericArray::<i64>::from_slice(&[1, 2, 3]).into_generic();

    let mut data = DataStore::new();
    data.add_named_numeric_array("array", array);

    data
}

#[wll::export]
fn test_nested_data_store() -> DataStore {
    let mut inner = DataStore::new();
    inner.add_named_bool("is_inner", true);

    let mut outer = DataStore::new();
    outer.add_named_bool("is_inner", false);
    outer.add_data_store(inner);

    outer
}

#[wll::export]
fn test_iterated_nested_data_store() -> DataStore {
    let mut store = DataStore::new();

    for level in 0..3 {
        store.add_named_i64("level", level);
        let mut new = DataStore::new();
        new.add_data_store(store);
        store = new;
    }

    store
}

//======================================
// DataStore arguments
//======================================

#[wll::export]
fn test_data_store_arg(ds: DataStore) -> i64 {
    ds.len() as i64
}

//======================================
// DataStore nodes
//======================================

#[wll::export]
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
More examples
Hide additional examples
examples/tests/test_share_counts.rs (line 31)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn test_na_constant_are_ptr_eq(
    array1: &NumericArray<i64>,
    array2: &NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data
}

#[wll::export]
fn test_na_manual_are_not_ptr_eq(
    mut array1: NumericArray<i64>,
    array2: NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data.add_bool(array1.as_slice_mut().is_some());
    data
}

#[wll::export]
fn test_na_shared_are_ptr_eq(
    mut array1: NumericArray<i64>,
    array2: NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data.add_bool(array1.as_slice_mut().is_some());
    data
}
examples/async/async_file_watcher.rs (line 85)
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
fn file_watch_thread_function(
    task: AsyncTaskObject,
    pause_interval_ms: u64,
    path: &PathBuf,
) {
    let mut prev_changed: Option<SystemTime> = fs::metadata(path)
        .and_then(|metadata| metadata.modified())
        .ok();

    // Stateful closure which checks if the file at `path` has been modified since the
    // last time this closure was called (and `prev_changed was updated). Using a closure
    // simplifies the control flow in the main `loop` below, which should sleep on every
    // iteration regardless of how this function returns.
    let mut check_for_modification = || -> Option<_> {
        let changed: Option<fs::Metadata> = fs::metadata(path).ok();

        let notify: Option<SystemTime> = match (&prev_changed, changed) {
            (Some(prev), Some(latest)) => {
                let latest: SystemTime = match latest.modified() {
                    Ok(latest) => latest,
                    Err(_) => return None,
                };

                if *prev != latest {
                    prev_changed = Some(latest.clone());
                    Some(latest)
                } else {
                    None
                }
            },
            // TODO: Notify on file removal?
            (Some(_prev), None) => None,
            (None, Some(latest)) => latest.modified().ok(),
            (None, None) => None,
        };

        let time = notify?;

        let since_epoch = match time.duration_since(std::time::UNIX_EPOCH) {
            Ok(duration) => duration,
            Err(_) => return None,
        };

        let since_epoch = since_epoch.as_secs();

        Some(since_epoch)
    };

    loop {
        if !task.is_alive() {
            break;
        }

        // Check to see if the file has been modified. If it has, raise an async event
        // called "change", and attach the modification timestamp as event data.
        if let Some(modification) = check_for_modification() {
            let mut data = DataStore::new();
            data.add_i64(modification as i64);

            task.raise_async_event("change", data);
        }

        // Wait for a bit before polling again for any changes to the file.
        std::thread::sleep(Duration::from_millis(pause_interval_ms));
    }
}
source

pub fn len(&self) -> usize

Returns the number of elements in this data store.

LibraryLink C Function: DataStore_getLength.

Examples found in repository?
examples/tests/test_data_store.rs (line 116)
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_data_store_arg(ds: DataStore) -> i64 {
    ds.len() as i64
}

//======================================
// DataStore nodes
//======================================

#[wll::export]
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
source

pub unsafe fn from_raw(raw: DataStore) -> Self

Construct a DataStore from a raw wolfram_library_link_sys::DataStore pointer.

source

pub fn into_raw(self) -> DataStore

Convert this DataStore into a raw wolfram_library_link_sys::DataStore pointer.

source

pub fn add_bool(&mut self, value: bool)

Add a bool value to this DataStore.

LibraryLink C Function: DataStore_addBoolean.

Examples found in repository?
examples/tests/test_share_counts.rs (line 32)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn test_na_constant_are_ptr_eq(
    array1: &NumericArray<i64>,
    array2: &NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data
}

#[wll::export]
fn test_na_manual_are_not_ptr_eq(
    mut array1: NumericArray<i64>,
    array2: NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data.add_bool(array1.as_slice_mut().is_some());
    data
}

#[wll::export]
fn test_na_shared_are_ptr_eq(
    mut array1: NumericArray<i64>,
    array2: NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data.add_bool(array1.as_slice_mut().is_some());
    data
}
source

pub fn add_i64(&mut self, value: i64)

Add an i64 value to this DataStore.

LibraryLink C Function: DataStore_addInteger.

Examples found in repository?
examples/tests/test_data_store.rs (line 25)
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_single_int_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);

    data
}

#[wll::export]
fn test_multiple_int_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_i64(2);
    data.add_i64(3);

    data
}

#[wll::export]
fn test_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_f64(2.0);
    data.add_str("hello");

    data
}

#[wll::export]
fn test_named_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_named_i64("an i64", 1);
    data.add_named_f64("an f64", 2.0);
    data.add_named_str("a str", "hello");

    data
}

#[wll::export]
fn test_named_and_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_named_f64("real", 2.0);
    data.add_named_str("hello", "world");

    data
}

//======================================
// Non-atomic types
//======================================

#[wll::export]
fn test_named_numeric_array_data_store() -> DataStore {
    let array = NumericArray::<i64>::from_slice(&[1, 2, 3]).into_generic();

    let mut data = DataStore::new();
    data.add_named_numeric_array("array", array);

    data
}

#[wll::export]
fn test_nested_data_store() -> DataStore {
    let mut inner = DataStore::new();
    inner.add_named_bool("is_inner", true);

    let mut outer = DataStore::new();
    outer.add_named_bool("is_inner", false);
    outer.add_data_store(inner);

    outer
}

#[wll::export]
fn test_iterated_nested_data_store() -> DataStore {
    let mut store = DataStore::new();

    for level in 0..3 {
        store.add_named_i64("level", level);
        let mut new = DataStore::new();
        new.add_data_store(store);
        store = new;
    }

    store
}

//======================================
// DataStore arguments
//======================================

#[wll::export]
fn test_data_store_arg(ds: DataStore) -> i64 {
    ds.len() as i64
}

//======================================
// DataStore nodes
//======================================

#[wll::export]
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
More examples
Hide additional examples
examples/tests/test_share_counts.rs (line 33)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn test_na_constant_are_ptr_eq(
    array1: &NumericArray<i64>,
    array2: &NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data
}

#[wll::export]
fn test_na_manual_are_not_ptr_eq(
    mut array1: NumericArray<i64>,
    array2: NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data.add_bool(array1.as_slice_mut().is_some());
    data
}

#[wll::export]
fn test_na_shared_are_ptr_eq(
    mut array1: NumericArray<i64>,
    array2: NumericArray<i64>,
) -> DataStore {
    let mut data = DataStore::new();
    data.add_bool(array1.ptr_eq(&array2));
    data.add_i64(array1.share_count() as i64);
    data.add_bool(array1.as_slice_mut().is_some());
    data
}
examples/async/async_file_watcher.rs (line 86)
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
fn file_watch_thread_function(
    task: AsyncTaskObject,
    pause_interval_ms: u64,
    path: &PathBuf,
) {
    let mut prev_changed: Option<SystemTime> = fs::metadata(path)
        .and_then(|metadata| metadata.modified())
        .ok();

    // Stateful closure which checks if the file at `path` has been modified since the
    // last time this closure was called (and `prev_changed was updated). Using a closure
    // simplifies the control flow in the main `loop` below, which should sleep on every
    // iteration regardless of how this function returns.
    let mut check_for_modification = || -> Option<_> {
        let changed: Option<fs::Metadata> = fs::metadata(path).ok();

        let notify: Option<SystemTime> = match (&prev_changed, changed) {
            (Some(prev), Some(latest)) => {
                let latest: SystemTime = match latest.modified() {
                    Ok(latest) => latest,
                    Err(_) => return None,
                };

                if *prev != latest {
                    prev_changed = Some(latest.clone());
                    Some(latest)
                } else {
                    None
                }
            },
            // TODO: Notify on file removal?
            (Some(_prev), None) => None,
            (None, Some(latest)) => latest.modified().ok(),
            (None, None) => None,
        };

        let time = notify?;

        let since_epoch = match time.duration_since(std::time::UNIX_EPOCH) {
            Ok(duration) => duration,
            Err(_) => return None,
        };

        let since_epoch = since_epoch.as_secs();

        Some(since_epoch)
    };

    loop {
        if !task.is_alive() {
            break;
        }

        // Check to see if the file has been modified. If it has, raise an async event
        // called "change", and attach the modification timestamp as event data.
        if let Some(modification) = check_for_modification() {
            let mut data = DataStore::new();
            data.add_i64(modification as i64);

            task.raise_async_event("change", data);
        }

        // Wait for a bit before polling again for any changes to the file.
        std::thread::sleep(Duration::from_millis(pause_interval_ms));
    }
}
source

pub fn add_f64(&mut self, value: f64)

Add an f64 value to this DataStore.

LibraryLink C Function: DataStore_addReal.

Examples found in repository?
examples/tests/test_data_store.rs (line 44)
41
42
43
44
45
46
47
48
fn test_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_f64(2.0);
    data.add_str("hello");

    data
}
source

pub fn add_complex_f64(&mut self, value: mcomplex)

Add an mcomplex value to this DataStore.

LibraryLink C Function: DataStore_addComplex.

source

pub fn add_str(&mut self, value: &str)

Add a str value to this DataStore.

See also: DataStore::add_c_str().

LibraryLink C Function: DataStore_addString.

Examples found in repository?
examples/tests/test_data_store.rs (line 45)
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_f64(2.0);
    data.add_str("hello");

    data
}

#[wll::export]
fn test_named_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_named_i64("an i64", 1);
    data.add_named_f64("an f64", 2.0);
    data.add_named_str("a str", "hello");

    data
}

#[wll::export]
fn test_named_and_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_named_f64("real", 2.0);
    data.add_named_str("hello", "world");

    data
}

//======================================
// Non-atomic types
//======================================

#[wll::export]
fn test_named_numeric_array_data_store() -> DataStore {
    let array = NumericArray::<i64>::from_slice(&[1, 2, 3]).into_generic();

    let mut data = DataStore::new();
    data.add_named_numeric_array("array", array);

    data
}

#[wll::export]
fn test_nested_data_store() -> DataStore {
    let mut inner = DataStore::new();
    inner.add_named_bool("is_inner", true);

    let mut outer = DataStore::new();
    outer.add_named_bool("is_inner", false);
    outer.add_data_store(inner);

    outer
}

#[wll::export]
fn test_iterated_nested_data_store() -> DataStore {
    let mut store = DataStore::new();

    for level in 0..3 {
        store.add_named_i64("level", level);
        let mut new = DataStore::new();
        new.add_data_store(store);
        store = new;
    }

    store
}

//======================================
// DataStore arguments
//======================================

#[wll::export]
fn test_data_store_arg(ds: DataStore) -> i64 {
    ds.len() as i64
}

//======================================
// DataStore nodes
//======================================

#[wll::export]
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
source

pub fn add_c_str(&mut self, value: &CStr)

Add a CStr value to this DataStore.

See also: DataStore::add_str().

LibraryLink C Function: DataStore_addString.

source

pub fn add_data_store(&mut self, ds: DataStore)

Add a DataStore value to this DataStore.

LibraryLink C Function: DataStore_addDataStore.

Example

The DataStore value constructed by the following code:

use wolfram_library_link::DataStore;

let mut inner = DataStore::new();
inner.add_i64(0);
let mut outer = DataStore::new();
outer.add_data_store(inner);

will have this representation when passed via LibraryLink into Wolfram Language:

Developer`DataStore[Developer`DataStore[0]]
Examples found in repository?
examples/tests/test_data_store.rs (line 91)
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
fn test_nested_data_store() -> DataStore {
    let mut inner = DataStore::new();
    inner.add_named_bool("is_inner", true);

    let mut outer = DataStore::new();
    outer.add_named_bool("is_inner", false);
    outer.add_data_store(inner);

    outer
}

#[wll::export]
fn test_iterated_nested_data_store() -> DataStore {
    let mut store = DataStore::new();

    for level in 0..3 {
        store.add_named_i64("level", level);
        let mut new = DataStore::new();
        new.add_data_store(store);
        store = new;
    }

    store
}
source

pub fn add_numeric_array(&mut self, array: NumericArray)

Add a NumericArray value to this DataStore.

LibraryLink C Function: DataStore_addMNumericArray.

Example
use wolfram_library_link::{DataStore, NumericArray};

let array: NumericArray<i64> = NumericArray::from_slice(&[1, 2, 3]);

let mut store = DataStore::new();

// Erase the NumericArray data type.
store.add_numeric_array(array.into_generic());

See also: NumericArray::into_generic().

source

pub fn add_named_bool(&mut self, name: &str, value: bool)

Add a bool value to this DataStore.

LibraryLink C Function: DataStore_addNamedBoolean.

Examples found in repository?
examples/tests/test_data_store.rs (line 87)
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_nested_data_store() -> DataStore {
    let mut inner = DataStore::new();
    inner.add_named_bool("is_inner", true);

    let mut outer = DataStore::new();
    outer.add_named_bool("is_inner", false);
    outer.add_data_store(inner);

    outer
}

#[wll::export]
fn test_iterated_nested_data_store() -> DataStore {
    let mut store = DataStore::new();

    for level in 0..3 {
        store.add_named_i64("level", level);
        let mut new = DataStore::new();
        new.add_data_store(store);
        store = new;
    }

    store
}

//======================================
// DataStore arguments
//======================================

#[wll::export]
fn test_data_store_arg(ds: DataStore) -> i64 {
    ds.len() as i64
}

//======================================
// DataStore nodes
//======================================

#[wll::export]
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
source

pub fn add_named_i64(&mut self, name: &str, value: i64)

Add an i64 value to this DataStore.

LibraryLink C Function: DataStore_addNamedInteger.

Examples found in repository?
examples/tests/test_data_store.rs (line 53)
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_named_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_named_i64("an i64", 1);
    data.add_named_f64("an f64", 2.0);
    data.add_named_str("a str", "hello");

    data
}

#[wll::export]
fn test_named_and_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_named_f64("real", 2.0);
    data.add_named_str("hello", "world");

    data
}

//======================================
// Non-atomic types
//======================================

#[wll::export]
fn test_named_numeric_array_data_store() -> DataStore {
    let array = NumericArray::<i64>::from_slice(&[1, 2, 3]).into_generic();

    let mut data = DataStore::new();
    data.add_named_numeric_array("array", array);

    data
}

#[wll::export]
fn test_nested_data_store() -> DataStore {
    let mut inner = DataStore::new();
    inner.add_named_bool("is_inner", true);

    let mut outer = DataStore::new();
    outer.add_named_bool("is_inner", false);
    outer.add_data_store(inner);

    outer
}

#[wll::export]
fn test_iterated_nested_data_store() -> DataStore {
    let mut store = DataStore::new();

    for level in 0..3 {
        store.add_named_i64("level", level);
        let mut new = DataStore::new();
        new.add_data_store(store);
        store = new;
    }

    store
}

//======================================
// DataStore arguments
//======================================

#[wll::export]
fn test_data_store_arg(ds: DataStore) -> i64 {
    ds.len() as i64
}

//======================================
// DataStore nodes
//======================================

#[wll::export]
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
source

pub fn add_named_f64(&mut self, name: &str, value: f64)

Add an f64 value to this DataStore.

LibraryLink C Function: DataStore_addNamedReal.

Examples found in repository?
examples/tests/test_data_store.rs (line 54)
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
fn test_named_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_named_i64("an i64", 1);
    data.add_named_f64("an f64", 2.0);
    data.add_named_str("a str", "hello");

    data
}

#[wll::export]
fn test_named_and_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_named_f64("real", 2.0);
    data.add_named_str("hello", "world");

    data
}
source

pub fn add_named_complex_f64(&mut self, name: &str, value: mcomplex)

Add an mcomplex value to this DataStore.

LibraryLink C Function: DataStore_addNamedComplex.

source

pub fn add_named_str(&mut self, name: &str, value: &str)

Add a str value to this DataStore.

See also: DataStore::add_c_str().

LibraryLink C Function: DataStore_addNamedString.

Examples found in repository?
examples/tests/test_data_store.rs (line 55)
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
fn test_named_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_named_i64("an i64", 1);
    data.add_named_f64("an f64", 2.0);
    data.add_named_str("a str", "hello");

    data
}

#[wll::export]
fn test_named_and_unnamed_heterogenous_data_store() -> DataStore {
    let mut data = DataStore::new();
    data.add_i64(1);
    data.add_named_f64("real", 2.0);
    data.add_named_str("hello", "world");

    data
}
source

pub fn add_named_c_str(&mut self, name: &str, value: &CStr)

Add a CStr value to this DataStore.

See also: DataStore::add_str().

LibraryLink C Function: DataStore_addNamedString.

source

pub fn add_named_data_store(&mut self, name: &str, ds: DataStore)

Add a DataStore value to this DataStore.

LibraryLink C Function: DataStore_addNamedDataStore.

Example

The DataStore value constructed by the following code:

use wolfram_library_link::DataStore;

let mut inner = DataStore::new();
inner.add_i64(0);
let mut outer = DataStore::new();
outer.add_named_data_store("inner", inner);

will have this representation when passed via LibraryLink into Wolfram Language:

Developer`DataStore["inner" -> Developer`DataStore[0]]
source

pub fn add_named_numeric_array(&mut self, name: &str, array: NumericArray)

Add a NumericArray value to this DataStore.

See also DataStore::add_numeric_array().

LibraryLink C Function: DataStore_addNamedMNumericArray.

Examples found in repository?
examples/tests/test_data_store.rs (line 79)
75
76
77
78
79
80
81
82
fn test_named_numeric_array_data_store() -> DataStore {
    let array = NumericArray::<i64>::from_slice(&[1, 2, 3]).into_generic();

    let mut data = DataStore::new();
    data.add_named_numeric_array("array", array);

    data
}
source

pub fn nodes<'s>(&'s self) -> Nodes<'s>

Returns an iterator over the DataStoreNodes of this DataStore.

A DataStore is made up of a linked list of DataStoreNodes. The Nodes iterator will repeatedly call the DataStoreNode::next_node() method to iterate over the nodes.

Examples found in repository?
examples/data_store.rs (line 34)
31
32
33
34
35
36
37
38
39
40
41
42
43
fn string_join(store: DataStore) -> String {
    let mut buffer = String::new();

    for node in store.nodes() {
        // If `node.value()` is a string, append it to our string.
        // If `node.value()` is NOT a string, silently skip it.
        if let DataStoreNodeValue::Str(string) = node.value() {
            buffer.push_str(string);
        }
    }

    buffer
}
More examples
Hide additional examples
examples/tests/test_data_store.rs (line 159)
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}
source

pub fn first_node<'s>(&'s self) -> Option<DataStoreNode<'s>>

Get the first DataStoreNode of this DataStore.

Examples found in repository?
examples/tests/test_data_store.rs (line 131)
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
fn test_data_store_nodes() {
    {
        let mut data = DataStore::new();
        data.add_i64(5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        let ty: sys::type_t = node.data_type_raw();

        assert_eq!(ty, sys::MType_Integer as i32);
    }

    // Test DataStoreNode::name() method.
    {
        let mut data = DataStore::new();
        data.add_named_i64("hello", 5);

        assert_eq!(data.len(), 1);

        let node = data.first_node().expect("got first node");

        assert_eq!(node.data_type_raw(), sys::MType_Integer as i32);
        assert_eq!(node.name(), Some("hello".to_owned()))
    }

    // Test DataStore::nodes() method and Debug formatting of DataStoreNode.
    {
        let mut store = DataStore::new();

        store.add_i64(5);
        store.add_named_bool("condition", true);
        store.add_str("Hello, World!");

        let mut nodes = store.nodes();

        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: 5 }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: Some("condition"), value: true }"#
        );
        assert_eq!(
            format!("{:?}", nodes.next().unwrap()),
            r#"DataStoreNode { name: None, value: "Hello, World!" }"#
        );
        assert!(nodes.next().is_none());
    }
}

Trait Implementations§

source§

impl Clone for DataStore

source§

fn clone(&self) -> DataStore

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DataStore

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Drop for DataStore

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl FromArg<'_> for DataStore

source§

unsafe fn from_arg(arg: &MArgument) -> DataStore

source§

fn parameter_type() -> Expr

Return the LibraryLink parameter type as a Wolfram Language expression. Read more
source§

impl<'a> FromArg<'a> for &'a DataStore

source§

unsafe fn from_arg(arg: &MArgument) -> &'a DataStore

source§

fn parameter_type() -> Expr

Return the LibraryLink parameter type as a Wolfram Language expression. Read more
source§

impl IntoArg for DataStore

source§

unsafe fn into_arg(self, arg: MArgument)

Move self into arg. Read more
source§

fn return_type() -> Expr

Return the LibraryLink return type as a Wolfram Language expression. Read more
source§

impl RefCast for DataStore

§

type From = *mut st_DataStore

source§

fn ref_cast(_from: &Self::From) -> &Self

source§

fn ref_cast_mut(_from: &mut Self::From) -> &mut Self

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.