@@ -5,6 +5,7 @@ use crate::SizeType;
5
5
use crate :: Time ;
6
6
use crate :: { tsk_id_t, TskitError } ;
7
7
use crate :: { IndividualId , NodeId , PopulationId } ;
8
+ use ll_bindings:: { tsk_node_table_free, tsk_node_table_init} ;
8
9
9
10
/// Row of a [`NodeTable`]
10
11
pub struct NodeTableRow {
@@ -243,3 +244,121 @@ impl<'a> NodeTable<'a> {
243
244
samples
244
245
}
245
246
}
247
+
248
+ /// A standalone node table that owns its data.
249
+ ///
250
+ /// # Examples
251
+ ///
252
+ /// ```
253
+ /// use tskit::OwnedNodeTable;
254
+ ///
255
+ /// let mut nodes = OwnedNodeTable::default();
256
+ /// let rowid = nodes.add_row(0, 1.1, -1, -1).unwrap();
257
+ /// assert_eq!(rowid, 0);
258
+ /// assert_eq!(nodes.num_rows(), 1);
259
+ /// ```
260
+ ///
261
+ /// An example with metadata.
262
+ /// This requires the cargo feature `"derive"` for `tskit`.
263
+ ///
264
+ /// ```
265
+ /// # #[cfg(any(feature="doc", feature="derive"))] {
266
+ /// use tskit::OwnedNodeTable;
267
+ ///
268
+ /// #[derive(serde::Serialize,
269
+ /// serde::Deserialize,
270
+ /// tskit::metadata::NodeMetadata)]
271
+ /// #[serializer("serde_json")]
272
+ /// struct NodeMetadata {
273
+ /// value: i32,
274
+ /// }
275
+ ///
276
+ /// let metadata = NodeMetadata{value: 42};
277
+ ///
278
+ /// let mut nodes = OwnedNodeTable::default();
279
+ ///
280
+ /// let rowid = nodes.add_row_with_metadata(0, 1., -1, -1, &metadata).unwrap();
281
+ /// assert_eq!(rowid, 0);
282
+ ///
283
+ /// if let Some(decoded) = nodes.metadata::<NodeMetadata>(rowid).unwrap() {
284
+ /// assert_eq!(decoded.value, 42);
285
+ /// } else {
286
+ /// panic!("hmm...we expected some metadata!");
287
+ /// }
288
+ ///
289
+ /// # }
290
+ /// ```
291
+ pub struct OwnedNodeTable {
292
+ table : mbox:: MBox < ll_bindings:: tsk_node_table_t > ,
293
+ }
294
+
295
+ impl OwnedNodeTable {
296
+ pub fn add_row (
297
+ & mut self ,
298
+ flags : impl Into < NodeFlags > ,
299
+ time : impl Into < Time > ,
300
+ population : impl Into < PopulationId > ,
301
+ individual : impl Into < IndividualId > ,
302
+ ) -> Result < NodeId , TskitError > {
303
+ let rv = unsafe {
304
+ ll_bindings:: tsk_node_table_add_row (
305
+ & mut ( * self . table ) ,
306
+ flags. into ( ) . bits ( ) ,
307
+ time. into ( ) . 0 ,
308
+ population. into ( ) . 0 ,
309
+ individual. into ( ) . 0 ,
310
+ std:: ptr:: null ( ) ,
311
+ 0 ,
312
+ )
313
+ } ;
314
+
315
+ handle_tsk_return_value ! ( rv, rv. into( ) )
316
+ }
317
+
318
+ pub fn add_row_with_metadata < M > (
319
+ & mut self ,
320
+ flags : impl Into < NodeFlags > ,
321
+ time : impl Into < Time > ,
322
+ population : impl Into < PopulationId > ,
323
+ individual : impl Into < IndividualId > ,
324
+ metadata : & M ,
325
+ ) -> Result < NodeId , TskitError >
326
+ where
327
+ M : crate :: metadata:: NodeMetadata ,
328
+ {
329
+ let md = crate :: metadata:: EncodedMetadata :: new ( metadata) ?;
330
+ let rv = unsafe {
331
+ ll_bindings:: tsk_node_table_add_row (
332
+ & mut ( * self . table ) ,
333
+ flags. into ( ) . bits ( ) ,
334
+ time. into ( ) . 0 ,
335
+ population. into ( ) . 0 ,
336
+ individual. into ( ) . 0 ,
337
+ md. as_ptr ( ) ,
338
+ md. len ( ) . into ( ) ,
339
+ )
340
+ } ;
341
+ handle_tsk_return_value ! ( rv, rv. into( ) )
342
+ }
343
+ }
344
+
345
+ build_owned_tables ! (
346
+ OwnedNodeTable ,
347
+ NodeTable ,
348
+ ll_bindings:: tsk_node_table_t,
349
+ tsk_node_table_init,
350
+ tsk_node_table_free
351
+ ) ;
352
+
353
+ #[ cfg( test) ]
354
+ mod test_owned_node_table {
355
+ use super :: * ;
356
+
357
+ #[ test]
358
+ fn test_add_row ( ) {
359
+ let mut nodes = OwnedNodeTable :: default ( ) ;
360
+ let rowid = nodes. add_row ( 0 , 1.1 , -1 , -1 ) . unwrap ( ) ;
361
+ assert_eq ! ( rowid, 0 ) ;
362
+ assert_eq ! ( nodes. num_rows( ) , 1 ) ;
363
+ }
364
+ }
0 commit comments