block_graph/
graph.rs

1fn set_bit(x: u64, idx: u8, b: bool) -> u64{(x & !(1 << idx)) | ((b as u64) << idx)}
2impl BuildHasher for H{
3	fn build_hasher(&self)->Self::Hasher{*self}
4	type Hasher=H;
5}
6impl Decompose for Label{
7	fn compose(label:Self::Decomposition)->Self{label.into()}
8	fn decompose(self)->Self::Decomposition{self.to_string()}
9	fn decompose_cloned(&self)->Self::Decomposition{self.clone().decompose()}
10	type Decomposition=String;
11}
12impl Default for Label{
13	fn default()->Self{
14		Self{id:rand::random(),name:None}
15	}
16}
17impl Display for Label{
18	fn fmt(&self,f:&mut Formatter<'_>)->FmtResult{
19		if self.id!=0{UpperHex::fmt(&self.id,f)?}
20		if let Some(text)=&self.name{
21			write!(f,"{}{text}",if self.id==0{""}else{": "})?;
22		}
23		Ok(())
24	}
25}
26impl From<Option<String>> for Label{
27	fn from(value:Option<String>)->Self{
28		if let Some(v)=value{v.into()}else{Self::new()}
29	}
30}
31impl From<String> for Label{
32	fn from(value:String)->Self{Self::from_str(&value).unwrap()}
33}
34impl From<i32> for Label{
35	fn from(value:i32)->Self{(value as u64).into()}
36}
37impl From<u64> for Label{
38	fn from(value:u64)->Self{
39		Self{id:value,name:None}
40	}
41}
42impl From<usize> for Label{
43	fn from(value:usize)->Self{Self::from(value as u64)}
44}
45impl FromStr for Label{
46	fn from_str(s:&str)->Result<Self,Self::Err>{
47		let parsewithid:Option<Self>=(||{
48			let idstop=s.find(": ").unwrap_or(s.len());
49			let id=u64::from_str_radix(&s[..idstop],16).ok()?;
50			let name=(idstop<s.len()).then(||Arc::from(&s[idstop+2..]));
51			Some(Self{id,name})
52		})();
53		Ok(if let Some(l)=parsewithid{l}else{Self::from(0_u64).with_name(s)})
54	}
55	type Err=();
56}
57impl Hasher for H{
58	#[inline]
59	fn finish(&self)->u64{self.0}
60	#[inline]
61	fn write(&mut self,bytes:&[u8]){
62		let H(h)=self;
63		for &byte in bytes.iter(){*h=h.rotate_left(8)^byte as u64}
64	}
65    #[inline]
66    fn write_u64(&mut self,n:u64){self.0^=n}
67}
68impl Label{
69	/// creates a new label
70	pub fn new()->Self{
71		Self{id:rand::random(),name:None}
72	}
73	/// sets the label id
74	pub fn with_id(mut self,id:u64)->Self{
75		self.id=id;
76		self
77	}
78	/// names the label
79	pub fn with_name<S:AsRef<str>>(mut self,name:S)->Self{
80		let name=name.as_ref();
81		self.name=if name.len()==0{None}else{Some(name.into())};
82		self
83	}
84	/// sets the label id
85	pub fn with_random_id(mut self)->Self{
86		self.id=rand::random();
87		self
88	}
89}
90impl<'a,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> ConnectionEditor<'a,C,V>{
91	/// gets the index, or usize::MAX to insert at the end of the order regardless of the number of connections
92	pub fn get_index(&self)->usize{self.index}
93	/// references the input label
94	pub fn input(&self)->&Label{&self.input}
95	/// adds a layer to the associated graph if there is one, returning the layer if not or the previous layer associated with the layer id
96	pub fn insert_layer<L:Into<C>>(&mut self,layer:L)->Option<C>{self.graph.as_mut().and_then(|g|g.layers.insert(self.layer.clone(),layer.into()))}
97	/// checks if clear
98	pub fn is_clear(&self)->bool{self.clear}
99	/// references the connection label
100	pub fn label(&self)->&Label{&self.connection}
101	/// references the layer label
102	pub fn layer(&self)->&Label{&self.layer}
103	/// references the input label
104	pub fn output(&self)->&Label{&self.output}
105	/// inserts the layer into the graph using the current layer id
106	pub fn with<L:Into<C>>(mut self,layer:L)->Self{
107		self.insert_layer(layer);
108		self
109	}
110	/// sets the flag for whether the input should be cleared after use
111	pub fn with_clear(mut self,clear:bool)->Self{
112		self.clear=clear;
113		self
114	}
115	/// sets the index to insert in the run order, or usize::MAX to insert at the end of the order regardless of the number of connections
116	pub fn with_index(mut self,index:usize)->Self{
117		self.index=index;
118		self
119	}
120	/// sets the input label
121	pub fn with_input<L:Into<Label>>(mut self,label:L)->Self{
122		self.input=label.into();
123		self
124	}
125	/// sets the connection label
126	pub fn with_label<L:Into<Label>>(mut self,label:L)->Self{
127		self.connection=label.into();
128		self
129	}
130	/// sets the layer label
131	pub fn with_layer<L:Into<Label>>(mut self,label:L)->Self{
132		self.layer=label.into();
133		self
134	}
135	/// sets the output label
136	pub fn with_output<L:Into<Label>>(mut self,label:L)->Self{
137		self.output=label.into();
138		self
139	}
140}
141impl<'a,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge>ConnectionInfo<'a,C,V>{
142	/// gets the index in the connection processing order
143	pub fn get_index(&self)->usize{
144		let connection=self.connection;
145		self.graph.order.iter().position(|label|connection==label).expect("order should contain all connection labels")
146	}
147	/// gets the underlying layer associated with the layer label
148	pub fn get_layer(&self)->Option<&C>{self.graph.layers.get(&self.layer)}
149	/// references the input label
150	pub fn input(&self)->&Label{&self.input}
151	/// checks if clear
152	pub fn is_clear(&self)->bool{self.clear}
153	/// references the connection label
154	pub fn label(&self)->&Label{self.connection}
155	/// references the layer label
156	pub fn layer(&self)->&Label{self.layer}
157	/// references the input label
158	pub fn output(&self)->&Label{self.output}
159}
160impl<'a,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> Default for ConnectionEditor<'a,C,V>{
161	fn default()->Self{
162		Self{clear:false,connection:Label::new(),graph:None,index:usize::MAX,input:Label::new(),layer:Label::new(),output:Label::new()}
163	}
164}
165impl<'a,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> Drop for ConnectionEditor<'a,C,V>{
166	fn drop(&mut self){
167		if let Some(g)=self.graph.take(){g.add_connection(self)}
168	}
169}
170impl<A:AI<Vec<X>,Vec<Y>>,X,Y> AI<X,Y> for Unvec<A>{
171	fn forward(&self,input:X)->Y{self.0.forward(vec![input]).into_iter().next().unwrap()}
172	fn forward_mut(&mut self,input:X)->Y{self.0.forward_mut(vec![input]).into_iter().next().unwrap()}
173}
174impl<A:Decompose> Decompose for Unvec<A>{
175	fn compose(decomposition:Self::Decomposition)->Self{Self(A::compose(decomposition))}
176	fn decompose(self)->Self::Decomposition{self.0.decompose()}
177	fn decompose_cloned(&self)->Self::Decomposition{self.0.decompose_cloned()}
178	type Decomposition=A::Decomposition;
179}
180impl<A:Into<C>,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> Extend<Graph<A>> for Graph<C>{
181	fn extend<I:IntoIterator<Item=Graph<A>>>(&mut self,iter:I){iter.into_iter().for_each(|graph|self.merge(graph))}
182}
183impl<A:Into<C>,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> FromIterator<Graph<A>> for Graph<C>{
184	fn from_iter<I:IntoIterator<Item=Graph<A>>>(iter:I)->Self{
185		let mut graph=Graph::default();
186		graph.extend(iter);
187		graph
188	}
189}
190impl<A:Op<Output=Vec<Y>>,Y> Op for Unvec<A>{
191	type Output=Y;
192}
193impl<C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> AI<Vec<V>,Vec<V>> for Graph<C>{
194	fn forward(&self,mut values:Vec<V>)->Vec<V>{
195		let mut map=HashMap::with_capacity_and_hasher(values.len(),H(0));
196		values.reverse();
197		for (_clear,input,_layer,_output) in self.order.iter().filter_map(|c|self.connections.get(c)){
198			if values.len()==0{break}
199			map.entry(input.clone()).or_insert_with(||values.pop().unwrap());
200		}
201		map=self.forward(map);
202		for (_clear,_input,_layer,output) in self.order.iter().rev().filter_map(|c|self.connections.get(c)){
203			if map.len()==0{break}
204			if let Some(y)=map.remove(output){values.push(y)}
205		}
206		values.reverse();
207		values
208	}
209	fn forward_mut(&mut self,mut values:Vec<V>)->Vec<V>{
210		let mut map=HashMap::with_capacity_and_hasher(values.len(),H(0));
211		values.reverse();
212		for (_clear,input,_layer,_output) in self.order.iter().filter_map(|c|self.connections.get(c)){
213			if values.len()==0{break}
214			map.entry(input.clone()).or_insert_with(||values.pop().unwrap());
215		}
216		map=self.forward_mut(map);
217		for (_clear,_input,_layer,output) in self.order.iter().rev().filter_map(|c|self.connections.get(c)){
218			if map.len()==0{break}
219			if let Some(y)=map.remove(output){values.push(y)}
220		}
221		values.reverse();
222		values
223	}
224}
225impl<C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge,S:BuildHasher> AI<HashMap<Label,V,S>,HashMap<Label,V,S>> for Graph<C>{
226	fn forward(&self,mut map:HashMap<Label,V,S>)->HashMap<Label,V,S>{
227		let (connections,order)=(&self.connections,&self.order);
228		let layers=&self.layers;
229
230		order.iter().filter_map(|c|connections.get(c)).for_each(|(clear,input,layer,output)|{
231			let x=if *clear>0{map.remove(input)}else{map.get(input).cloned()}.unwrap_or_default();
232			let y=if let Some(f)=layers.get(layer){f.forward(x)}else{x};
233			map.entry(output.clone()).or_default().merge(y);
234		});
235		map
236	}
237	fn forward_mut(&mut self,mut map:HashMap<Label,V,S>)->HashMap<Label,V,S>{
238		let (connections,order)=(&self.connections,&self.order);
239		let layers=&mut self.layers;
240
241		order.iter().filter_map(|c|connections.get(c)).for_each(|(clear,input,layer,output)|{
242			let x=if *clear>0{map.remove(input)}else{map.get(input).cloned()}.unwrap_or_default();
243			let y=if let Some(f)=layers.get_mut(layer){f.forward_mut(x)}else{x};
244			map.entry(output.clone()).or_default().merge(y);
245		});
246		map
247	}
248}
249impl<C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> Default for Graph<C>{
250	fn default()->Self{Self::new()}
251}
252impl<C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge> Graph<C>{
253	/// creates a new empty graph
254	pub fn new()->Self{
255		Self{connections:HashMap::with_hasher(H(0)),layers:HashMap::with_hasher(H(0)),order:Vec::new()}
256	}
257	/// adds a connection between two vertices
258	pub fn add_connection<'a>(&mut self,config:&ConnectionEditor<'a,C,V>){
259		let (connections,order)=(&mut self.connections,&mut self.order);
260		let (connection,input,layer,output)=(config.connection.clone(),config.input.clone(),config.layer.clone(),config.output.clone());
261		let (clear,index)=(config.clear,config.index);
262
263		connections.insert(connection.clone(),(clear as u64,input,layer,output));
264		if index<order.len(){order.insert(index,connection)}else{order.push(connection)}
265	}
266	/// adds a layer without connecting it
267	pub fn add_layer<X:Into<C>,L:Into<Label>>(&mut self,label:L,layer:X){
268		self.layers.insert(label.into(),layer.into());
269	}
270	/// adds a connection between vertices
271	pub fn connect<I:Into<Label>,O:Into<Label>>(&mut self,input:I,output:O)->ConnectionEditor<'_,C,V>{
272		let (connection,layer)=(Label::new(),Label::new());
273		let (input,output)=(input.into(),output.into());
274		let clear=false;
275		let index=self.order.len();
276
277		let graph=Some(self);
278		ConnectionEditor{clear,connection,graph,index,input,layer,output}
279	}
280	/// returns an iterator over the connections in an arbitrary order
281	pub fn connections<'a>(&'a self)->impl Iterator<Item=ConnectionInfo<'a,C,V>>{self.connections.keys().filter_map(move|k|self.get_connection(k))}
282	/// gets connection information by label
283	pub fn get_connection<'a>(&'a self,label:&Label)->Option<ConnectionInfo<'a,C,V>>{
284		let (connection,(clear,input,layer,output))=self.connections.get_key_value(label)?;
285		let clear=*clear>0;
286		let graph=self;
287
288		Some(ConnectionInfo{clear,connection,graph,input,layer,output})
289	}
290	/// gets the layer information by label
291	pub fn get_layer(&self,label:&Label)->Option<&C>{self.layers.get(label)}
292	/// another graphs into this one
293	pub fn merge<A:Into<C>>(&mut self,graph:Graph<A>){
294		self.connections.extend(graph.connections);
295		self.layers.extend(graph.layers.into_iter().map(|(l,a)|(l,a.into())));
296		self.order.extend(graph.order);
297	}
298	/// gets the connection order
299	pub fn order(&self)->&[Label]{&self.order}
300	/// splits the graph according to the predicate(clear, connectionlabel, inputlabel, layer, layerlabel, outputlabel). true will be sent to the returned graph. the resulting graphs will only have the layers they use
301	pub fn split<F:FnMut(bool,&Label,&Label,&C,&Label,&Label)->bool>(&mut self,mut predicate:F)->Self where C:Clone{
302		let (connections,layers,order)=(&mut self.connections,&mut self.layers,&mut self.order);
303
304		let newconnections:HashMap<_,_,H>=connections.extract_if(|connectionlabel,(clear,inputlabel,layerlabel,outputlabel)|if let Some(layer)=layers.get_mut(layerlabel){
305			predicate(*clear>0,connectionlabel,inputlabel,layer,layerlabel,outputlabel)
306		}else{
307			false
308		}).collect();
309
310		let mut oldlayers=mem::take(layers);
311		let newlayers=newconnections.iter().filter_map(|(_connectionlabel,(_clear,_inputlabel,layerlabel,_outputlabel))|if let Some(layer)=oldlayers.get(layerlabel){
312			Some((layerlabel.clone(),layer.clone()))
313		}else{
314			None
315		}).collect();
316		connections.iter().for_each(|(_connectionlabel,(_clear,_inputlabel,layerlabel,_outputlabel))|if let Some(layer)=oldlayers.remove(layerlabel){
317			layers.insert(layerlabel.clone(),layer);
318		});
319
320		let neworder=order.extract_if(..,|label|newconnections.contains_key(label)).collect();
321		order.retain(|label|connections.contains_key(label));
322
323		Self{connections:newconnections,layers:newlayers,order:neworder}
324	}
325	/// topologically sorts the graph. Inputs to the same node will retain their relative order.
326	pub fn sort(&mut self){
327		let connections=&mut self.connections;
328		let mut dedup=HashSet::with_capacity(connections.len());
329		let mut nodes:HashMap<Label,(Vec<Label>,usize)>=HashMap::with_capacity(connections.len());
330		let order=&mut self.order;
331		order.drain(..).for_each(|label|if let Some((_clear,input,_layer,output))=connections.get(&label){
332			let (_inputinputs,inputoutputs)=nodes.entry(input.clone()).or_default();
333			*inputoutputs+=1;
334			let (outputinputs,_outputoutputs)=nodes.entry(output.clone()).or_default();
335			outputinputs.push(label);
336		});
337
338		while nodes.len()>0{
339			let mut cycle=true;
340			let mut n=order.len();
341			nodes.retain(|_node,(inputs,outputs)|{
342				if *outputs==0{
343					cycle=false;
344					order.extend(inputs.drain(..).filter(|i|dedup.insert(i.clone())).rev());
345				}
346				inputs.len()>0
347			});
348			if cycle{order.extend(nodes.iter_mut().filter_map(|(_node,(inputs,_outputs))|inputs.pop()).filter(|i|dedup.insert(i.clone())))}
349			while n<order.len(){
350				if let Some((inputs,outputs))=nodes.get_mut(&connections.get(&order[n]).unwrap().1){
351					*outputs-=1;
352					if inputs.len()==1&&*outputs==0{order.push(inputs.pop().unwrap())}
353				}
354				n+=1;
355			}
356		}
357		order.iter().for_each(|label|if let Some((clear,input,_layer,_output))=connections.get_mut(label){*clear=set_bit(*clear,1,!nodes.contains_key(input))});
358		order.reverse();
359	}
360}
361impl<C:Decompose> Decompose for Graph<C>{// TODO ideally this would preserve unconnected layers too
362	fn compose((connections,layers):Self::Decomposition)->Self{
363		let mut order=Vec::with_capacity(connections.len());
364		let connections=connections.into_iter().map(|decomposed|{
365			let (label,(clear,input,layer,output)):(Label,(u64,Label,Label,Label))=Decompose::compose(decomposed);
366			order.push(label.clone());
367			(label,(clear,input,layer,output))
368		}).collect();
369		let layers=layers.into_iter().map(Decompose::compose).collect();
370		Self{connections,layers,order}
371	}
372	fn decompose(self)->Self::Decomposition{
373		let (mut connections,mut layers,order)=(self.connections,self.layers,self.order);
374
375		let (mut decomposedconnections,mut decomposedlayers)=(Vec::new(),Vec::new());
376		order.iter().filter_map(|label|connections.remove_entry(label)).for_each(|(label,(clear,input,layer,output))|{
377			decomposedlayers.extend(layers.remove_entry(&layer).map(|(label,layer)|(label.decompose(),layer.decompose())));
378			decomposedconnections.push((label.decompose(),(clear,input.decompose(),layer.decompose(),output.decompose())));
379		});
380		(decomposedconnections,decomposedlayers)
381	}
382	fn decompose_cloned(&self)->Self::Decomposition{
383		let (connections,layers,order)=(&self.connections,&self.layers,&self.order);
384		let mut layersfound=HashSet::new();
385
386		let (mut decomposedconnections,mut decomposedlayers)=(Vec::new(),Vec::new());
387		order.iter().filter_map(|label|connections.get_key_value(label)).for_each(|(label,(clear,input,layer,output))|{
388			if layersfound.insert(layer.clone()){decomposedlayers.extend(layers.get_key_value(layer).map(|(label,layer)|(label.decompose_cloned(),layer.decompose_cloned())))}
389			decomposedconnections.push((label.decompose_cloned(),(*clear,input.decompose_cloned(),layer.decompose_cloned(),output.decompose_cloned())));
390		});
391		(decomposedconnections,decomposedlayers)
392	}
393	type Decomposition=(Vec<(String,(u64,String,String,String))>,Vec<(String,C::Decomposition)>);
394}
395impl<C:Op> Op for Graph<C>{
396	type Output=Vec<C::Output>;
397}
398impl<E,V:Extend<E>+IntoIterator<Item=E>> Merge for Extendable<V>{
399	fn merge(&mut self,other:Self){self.0.extend(other.0)}
400}
401impl<E:Merge> Merge for Option<E>{
402	fn merge(&mut self,other:Self){
403		match (self,other){(Some(this),Some(other))=>this.merge(other),(this,Some(other))=>*this=Some(other),_=>()}
404	}
405}
406impl<E> Merge for Vec<E>{
407	fn merge(&mut self,other:Self){self.extend(other)}
408}
409impl<S:?Sized+AsRef<str>> From<&S> for Label{
410	fn from(value:&S)->Self{Self::from_str(value.as_ref()).unwrap()}
411}
412#[cfg(test)]
413mod tests{
414	#[test]
415	fn sort_digons(){
416		let mut graph:Graph<Append<u64>>=Graph::new();
417		let mut order=[0,1,2,3,4];
418
419		order.shuffle(&mut rand::rng());
420		for &n in order.iter(){
421			graph.connect(n,n+1).with_clear(true).with(Append(n+100));
422			graph.connect(n,n+1).with_clear(true).with(Append(n+200));
423		}
424		let unsorted:Vec<u64>=Unvec(&graph).forward(Vec::new());
425
426		graph.sort();
427		let sorted:Vec<u64>=Unvec(&graph).forward(Vec::new());
428		assert_eq!(sorted,[100,200,101,201,102,202,103,203,104,204]);
429		assert_ne!(sorted,unsorted);
430	}
431	#[test]
432	fn sort_line(){
433		let mut graph:Graph<Append<u64>>=Graph::new();
434		let mut order=[0,1,2,3,4,5,6,7,8,9];
435
436		order.shuffle(&mut rand::rng());
437		for &n in order.iter(){
438			graph.connect(n,n+1).with(Append(n));
439		}
440		let unsorted:Vec<u64>=Unvec(&graph).forward(Vec::new());
441
442		graph.sort();
443		let sorted:Vec<u64>=Unvec(&graph).forward(Vec::new());
444		assert_eq!(sorted,[0,1,2,3,4,5,6,7,8,9]);
445		assert_ne!(sorted,unsorted);
446	}
447	impl<E:Clone> AI<Vec<E>,Vec<E>> for Append<E>{
448		fn forward(&self,mut input:Vec<E>)->Vec<E>{
449			input.push(self.0.clone());
450			input
451		}
452	}
453	impl<E:Clone> Op for Append<E>{
454		type Output=Vec<E>;
455	}
456	#[derive(Clone,Debug)]
457	/// test ai module that appends a number to a vec
458	struct Append<E:Clone>(E);
459	use rand::seq::SliceRandom;
460	use super::*;
461}
462#[derive(Clone,Debug,Default,Eq,Hash,Ord,PartialEq,PartialOrd)]
463#[repr(transparent)]
464/// wraps collections so that merging concatenates them using the Extend trait
465pub struct Extendable<V>(pub V);
466/*#[derive(Clone,Debug)]
467/// allows configuring a connection to add to the graph
468pub struct ConnectionConfig{clear:bool,connection:Label,index:usize,input:Label,layer:Label,output:Label}*/
469#[derive(Debug)]// TODO split connection config and connection editor
470/// allows configuring a connection to add to the graph, or manipulating an existing connection
471pub struct ConnectionEditor<'a,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge>{clear:bool,connection:Label,graph:Option<&'a mut Graph<C>>,index:usize,input:Label,layer:Label,output:Label}
472#[derive(Clone,Debug)]
473/// information about a connection
474pub struct ConnectionInfo<'a,C:AI<V,V>+Op<Output=V>,V:Clone+Default+Merge>{clear:bool,connection:&'a Label,graph:&'a Graph<C>,input:&'a Label,layer:&'a Label,output:&'a Label}
475#[derive(Clone,Debug,Deserialize,Eq,PartialEq,Serialize)]
476/// graph like ai operation structure
477pub struct Graph<C>{connections:HashMap<Label,(u64,Label,Label,Label),H>,layers:HashMap<Label,C,H>,order:Vec<Label>}
478#[derive(Clone,Debug,Deserialize,Eq,Hash,PartialEq,Serialize)]
479/// label for graph connections or layers or nodes. format is id: name where id is a hex number or simply id if there is no name. name without a number will be parse as a name with a 0 id
480pub struct Label{id:u64,name:Option<Arc<str>>}
481#[derive(Clone,Copy,Debug,Default,Deserialize,Serialize)]
482#[repr(transparent)]
483/// wraps the graph so it can take singular io
484pub struct Unvec<A>(pub A);
485/// trait to allow merging multiple outputs into one graph node
486pub trait Merge{
487	/// merges the other into self, taking out of other if convenient
488	fn merge(&mut self,other:Self);
489}
490#[derive(Clone,Copy,Debug,Default)]
491#[repr(transparent)]
492struct H(u64);
493use crate::{AI,Decompose,Op};
494use serde::{Deserialize,Serialize};
495use std::{
496	collections::{HashMap,HashSet},fmt::{Display,Formatter,UpperHex,Result as FmtResult},hash::{BuildHasher,Hasher,Hash},iter::{FromIterator,Extend},mem,str::FromStr,sync::Arc
497};