@@ -184,6 +184,54 @@ pub enum ParseFlakeError {
184184 #[ error( "Unrecognized node or token encountered" ) ]
185185 Unrecognized ,
186186}
187+
188+ fn parse_fragment ( fragment : & str ) -> Result < ( Option < String > , Option < String > ) , ParseFlakeError > {
189+ let mut node: Option < String > = None ;
190+ let mut profile: Option < String > = None ;
191+
192+ let ast = rnix:: parse ( fragment) ;
193+
194+ let first_child = match ast. root ( ) . node ( ) . first_child ( ) {
195+ Some ( x) => x,
196+ None => return Ok ( ( None , None ) )
197+ } ;
198+
199+ let mut node_over = false ;
200+
201+ for entry in first_child. children_with_tokens ( ) {
202+ let x: Option < String > = match ( entry. kind ( ) , node_over) {
203+ ( TOKEN_DOT , false ) => {
204+ node_over = true ;
205+ None
206+ }
207+ ( TOKEN_DOT , true ) => {
208+ return Err ( ParseFlakeError :: PathTooLong ) ;
209+ }
210+ ( NODE_IDENT , _) => Some ( entry. into_node ( ) . unwrap ( ) . text ( ) . to_string ( ) ) ,
211+ ( TOKEN_IDENT , _) => Some ( entry. into_token ( ) . unwrap ( ) . text ( ) . to_string ( ) ) ,
212+ ( NODE_STRING , _) => {
213+ let c = entry
214+ . into_node ( )
215+ . unwrap ( )
216+ . children_with_tokens ( )
217+ . nth ( 1 )
218+ . unwrap ( ) ;
219+
220+ Some ( c. into_token ( ) . unwrap ( ) . text ( ) . to_string ( ) )
221+ }
222+ _ => return Err ( ParseFlakeError :: Unrecognized ) ,
223+ } ;
224+
225+ if !node_over {
226+ node = x;
227+ } else {
228+ profile = x;
229+ }
230+ }
231+
232+ Ok ( ( node, profile) )
233+ }
234+
187235pub fn parse_flake ( flake : & str ) -> Result < DeployFlake , ParseFlakeError > {
188236 let flake_fragment_start = flake. find ( '#' ) ;
189237 let ( repo, maybe_fragment) = match flake_fragment_start {
@@ -195,51 +243,7 @@ pub fn parse_flake(flake: &str) -> Result<DeployFlake, ParseFlakeError> {
195243 let mut profile: Option < String > = None ;
196244
197245 if let Some ( fragment) = maybe_fragment {
198- let ast = rnix:: parse ( fragment) ;
199-
200- let first_child = match ast. root ( ) . node ( ) . first_child ( ) {
201- Some ( x) => x,
202- None => {
203- return Ok ( DeployFlake {
204- repo,
205- node : None ,
206- profile : None ,
207- } )
208- }
209- } ;
210-
211- let mut node_over = false ;
212-
213- for entry in first_child. children_with_tokens ( ) {
214- let x: Option < String > = match ( entry. kind ( ) , node_over) {
215- ( TOKEN_DOT , false ) => {
216- node_over = true ;
217- None
218- }
219- ( TOKEN_DOT , true ) => {
220- return Err ( ParseFlakeError :: PathTooLong ) ;
221- }
222- ( NODE_IDENT , _) => Some ( entry. into_node ( ) . unwrap ( ) . text ( ) . to_string ( ) ) ,
223- ( TOKEN_IDENT , _) => Some ( entry. into_token ( ) . unwrap ( ) . text ( ) . to_string ( ) ) ,
224- ( NODE_STRING , _) => {
225- let c = entry
226- . into_node ( )
227- . unwrap ( )
228- . children_with_tokens ( )
229- . nth ( 1 )
230- . unwrap ( ) ;
231-
232- Some ( c. into_token ( ) . unwrap ( ) . text ( ) . to_string ( ) )
233- }
234- _ => return Err ( ParseFlakeError :: Unrecognized ) ,
235- } ;
236-
237- if !node_over {
238- node = x;
239- } else {
240- profile = x;
241- }
242- }
246+ ( node, profile) = parse_fragment ( fragment) ?;
243247 }
244248
245249 Ok ( DeployFlake {
@@ -315,6 +319,16 @@ fn test_parse_flake() {
315319 ) ;
316320}
317321
322+ pub fn parse_file < ' a > ( file : & ' a str , attribute : & ' a str ) -> Result < DeployFlake < ' a > , ParseFlakeError > {
323+ let ( node, profile) = parse_fragment ( attribute) ?;
324+
325+ Ok ( DeployFlake {
326+ repo : & file,
327+ node,
328+ profile,
329+ } )
330+ }
331+
318332#[ derive( Debug , Clone ) ]
319333pub struct DeployData < ' a > {
320334 pub node_name : & ' a str ,
0 commit comments