133d722a9Sopenharmony_ciuse crate::syntax::map::{Entry, UnorderedMap as Map}; 233d722a9Sopenharmony_ciuse crate::syntax::report::Errors; 333d722a9Sopenharmony_ciuse crate::syntax::{Api, Struct, Type, Types}; 433d722a9Sopenharmony_ci 533d722a9Sopenharmony_cienum Mark { 633d722a9Sopenharmony_ci Visiting, 733d722a9Sopenharmony_ci Visited, 833d722a9Sopenharmony_ci} 933d722a9Sopenharmony_ci 1033d722a9Sopenharmony_cipub fn sort<'a>(cx: &mut Errors, apis: &'a [Api], types: &Types<'a>) -> Vec<&'a Struct> { 1133d722a9Sopenharmony_ci let mut sorted = Vec::new(); 1233d722a9Sopenharmony_ci let ref mut marks = Map::new(); 1333d722a9Sopenharmony_ci for api in apis { 1433d722a9Sopenharmony_ci if let Api::Struct(strct) = api { 1533d722a9Sopenharmony_ci let _ = visit(cx, strct, &mut sorted, marks, types); 1633d722a9Sopenharmony_ci } 1733d722a9Sopenharmony_ci } 1833d722a9Sopenharmony_ci sorted 1933d722a9Sopenharmony_ci} 2033d722a9Sopenharmony_ci 2133d722a9Sopenharmony_cifn visit<'a>( 2233d722a9Sopenharmony_ci cx: &mut Errors, 2333d722a9Sopenharmony_ci strct: &'a Struct, 2433d722a9Sopenharmony_ci sorted: &mut Vec<&'a Struct>, 2533d722a9Sopenharmony_ci marks: &mut Map<*const Struct, Mark>, 2633d722a9Sopenharmony_ci types: &Types<'a>, 2733d722a9Sopenharmony_ci) -> Result<(), ()> { 2833d722a9Sopenharmony_ci match marks.entry(strct) { 2933d722a9Sopenharmony_ci Entry::Occupied(entry) => match entry.get() { 3033d722a9Sopenharmony_ci Mark::Visiting => return Err(()), // not a DAG 3133d722a9Sopenharmony_ci Mark::Visited => return Ok(()), 3233d722a9Sopenharmony_ci }, 3333d722a9Sopenharmony_ci Entry::Vacant(entry) => { 3433d722a9Sopenharmony_ci entry.insert(Mark::Visiting); 3533d722a9Sopenharmony_ci } 3633d722a9Sopenharmony_ci } 3733d722a9Sopenharmony_ci let mut result = Ok(()); 3833d722a9Sopenharmony_ci for field in &strct.fields { 3933d722a9Sopenharmony_ci if let Type::Ident(ident) = &field.ty { 4033d722a9Sopenharmony_ci if let Some(inner) = types.structs.get(&ident.rust) { 4133d722a9Sopenharmony_ci if visit(cx, inner, sorted, marks, types).is_err() { 4233d722a9Sopenharmony_ci cx.error(field, "unsupported cyclic data structure"); 4333d722a9Sopenharmony_ci result = Err(()); 4433d722a9Sopenharmony_ci } 4533d722a9Sopenharmony_ci } 4633d722a9Sopenharmony_ci } 4733d722a9Sopenharmony_ci } 4833d722a9Sopenharmony_ci marks.insert(strct, Mark::Visited); 4933d722a9Sopenharmony_ci sorted.push(strct); 5033d722a9Sopenharmony_ci result 5133d722a9Sopenharmony_ci} 52